From f3aa671fe65a9b0015fbccb3deabd245b6714283 Mon Sep 17 00:00:00 2001 From: Spencer Carrucciu Date: Thu, 20 Aug 2015 11:42:10 -0400 Subject: [PATCH] Squashed commit of the following: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 608a28e4e27ad8724841e892f7985355a01dad8a Merge: 047839c 2c25c21 Author: Spencer Carrucciu Date: Thu Aug 20 11:38:01 2015 -0400 Merge branch 'master' of https://github.com/scarrucciu/pandas commit 047839cfe5f0a2a0c9a3e6a474ece0702fecc5b7 Author: Spencer Carrucciu Date: Thu Aug 20 11:37:47 2015 -0400 10441 implement __reduce__/__setstate__ for Period pickle support commit 2c25c21f27c2902afaef5b14e8e4d9b564647c5a Merge: a4cc715 235570d Author: Spencer Carrucciu Date: Thu Aug 20 10:30:37 2015 -0400 Merge branch 'master' of https://github.com/scarrucciu/pandas commit a4cc7154ff9d2b063a47b300f324e6eff5a5697a Author: Spencer Carrucciu Date: Thu Aug 20 10:30:20 2015 -0400 10441 add period series to create_data in generate_legacy_data commit f64f7467cab6464a9ac30581ecb7ef0571602e52 Author: Spencer Carrucciu Date: Thu Aug 20 10:21:26 2015 -0400 10441 Use self.round_trip_pickle to test in test_period commit 235570d212c3c2b2bfea1a68b15109abeef5ad15 Author: Spencer Carrucciu Date: Thu Aug 20 10:21:26 2015 -0400 use self.round_trip_pickle to test in test_period commit 95f2db4e1e181c77b5caa864fe20c2a85840fc87 Author: Spencer Carrucciu Date: Thu Aug 20 09:48:52 2015 -0400 add _create_period to generate_legacy_storage_files commit c2d0e87f9da7007536840b6c2dc2935b12f515aa Merge: 278930e 2ef546d Author: Spencer Carrucciu Date: Thu Aug 20 09:43:49 2015 -0400 Merge branch 'master' of https://github.com/pydata/pandas commit 2ef546dcfa3c818afa6ae849865e4b7cf64436af Merge: 35284b5 9375460 Author: Jeff Reback Date: Thu Aug 20 08:54:55 2015 -0400 Merge pull request #10826 from sinhrks/merge_empty BUG: Merge with empty dataframe may raise IndexError commit 35284b564bc284e60ec19fa8fde0190a3ba80492 Merge: 3e35c84 96b7e27 Author: Jeff Reback Date: Thu Aug 20 08:48:09 2015 -0400 Merge pull request #10858 from behzadnouri/cat-attr removes categories & ordered from CategoricalIndex attributes commit 96b7e27553ef956602dd8c5e73425de356cc3617 Author: behzad nouri Date: Wed Aug 19 19:35:10 2015 -0400 removes categories & ordered from CategoricalIndex attributes commit 3e35c842f37265ac7339908869d4cc7bdef784d9 Author: Jeff Reback Date: Wed Aug 19 17:37:51 2015 -0400 DOC: fix doc-string in Categorical constructor, #10356 commit 9311a3924dd4097916928dee68a286284a98ca2f Merge: 2396370 17ec1d9 Author: Jeff Reback Date: Wed Aug 19 16:52:33 2015 -0400 Merge pull request #10738 from nickeubank/patch_sample_to_return_copy amend sample to return copy and align weight axis commit 17ec1d930d0ca05bc25bbf8c196afacb1b66cf30 Author: Nick Eubank Date: Wed Aug 19 10:57:04 2015 -0700 amend sample to return copy and align weight axis commit 2396370ddfa1110f9a2d4ae304bd09ad53c560f5 Merge: 94ec946 9c60d18 Author: Jeff Reback Date: Wed Aug 19 06:53:27 2015 -0400 Merge pull request #10853 from kawochen/TST-FIX-10837 TST: GH10837 remove test_ujson.py reliance on dict iteration order commit 94ec9461394827413b2ea7305b0f33640c8ff9b2 Author: Jeff Reback Date: Tue Aug 18 21:07:06 2015 -0400 PERF: add in numexpr to asv add to .gitignore commit c29a230417279f32bbcef78a81ef1d312ef023c6 Merge: 6d60d76 6c598fa Author: Joris Van den Bossche Date: Wed Aug 19 11:21:38 2015 +0200 Merge pull request #10854 from rgieseke/patch-1 DOC: fix Panel4D docstring commit 6d60d76c6985b0030b992e9763515a40e67efc3b Merge: d27068f ee7a094 Author: Joris Van den Bossche Date: Wed Aug 19 11:12:07 2015 +0200 Merge pull request #10852 from chris-b1/cookbook DOC: Excel formatting and searchsorted cookbook examples commit 6c598fab8af391b4240ef112759d065e54a6928a Author: Robert Gieseke Date: Wed Aug 19 10:54:24 2015 +0200 DOC: fix Panel4D docstring Just took this from https://github.com/pydata/pandas/blob/master/doc/source/dsintro.rst#panel4d-experimental commit 9c60d182399ddc4ccdf166f23b6e196e57d455c0 Author: Ka Wo Chen Date: Tue Aug 18 23:57:56 2015 -0400 TST: GH10837 remove test_ujson.py reliance on dict iteration order commit ee7a0947a27b254c1a37092d0b5aff3d3055746b Author: Chris Date: Tue Aug 18 21:51:09 2015 -0500 DOC: Excel formatting and searchsorted cookbook commit d27068f8b78661a64580340a5ab230d0dad17760 Merge: 310f9e4 201760e Author: Jeff Reback Date: Tue Aug 18 20:32:16 2015 -0400 Merge pull request #9715 from qwhelan/vbench_to_asv PERF: add initial asv config and vbench->asv conversion script commit 310f9e449a6e17d4b26ecc68b6af6115244fc9d2 Author: Jeff Reback Date: Tue Aug 18 20:20:37 2015 -0400 COMPAT: windows compat for #9838 commit ab769d87ad54ac84f6d4aa9fec44eb2d266e9b39 Merge: 5052900 22af130 Author: Jeff Reback Date: Tue Aug 18 19:37:09 2015 -0400 Merge pull request #10840 from chris-b1/valuecounts-float64 PERF: value_counts_float64 #10821 commit 5052900583b18fd86771928faffa665408beee38 Merge: 931e0e5 0468cad Author: Stephan Hoyer Date: Tue Aug 18 16:05:06 2015 -0700 Merge pull request #10411 from shoyer/max_distance ENH: tolerance argument for limiting pad, backfill and nearest neighbor reindexing commit 0468cadc7f3a225fc04f7ef6b93c1a7bb0cc5c00 Author: Stephan Hoyer Date: Tue Jun 23 00:03:23 2015 -0600 ENH: add tolerance to get_indexer, get_loc and reindex commit 22af130187a6363d447525ecb69a705c322655e0 Merge: f0706b1 8bb17cb Author: chris-b1 Date: Tue Aug 18 15:45:38 2015 -0500 Merge pull request #1 from insertinterestingnamehere/fused_cleanup Fused cleanup commit 8bb17cb02c31bb89e87a8fbddec0537fabd1d81d Author: Ian Henriksen Date: Tue Aug 18 11:39:15 2015 -0600 CLN: Combined build_count_table_int64 and build_count_table_float64 into a single function using fused types. commit cf002dcce4adcf45e1256b6f16aa2e2833a4cfc5 Author: Ian Henriksen Date: Tue Aug 18 11:25:25 2015 -0600 CLN: Combined value_count_in64 and value_count_float64 into a single routine using fused types. commit 931e0e5596e5714ecab5665d10735c155a2313f7 Author: Evan Wright Date: Sat Apr 4 15:13:33 2015 -0400 BUG: DataFrame.where does not respect axis parameter when shape is symmetric (GH #9736) commit 5314a5fb181f7eee0248d0ab6af3cd57c1733448 Merge: a0242ba 6c3da7f Author: Jeff Reback Date: Tue Aug 18 07:09:49 2015 -0400 Merge pull request #10686 from kawochen/BUG-FIX-10581 BUG: GH10581 where read_msgpack does not respect encoding commit a0242ba65ab704f91684df15f8f4e576acd6f97d Author: Jeff Reback Date: Tue Aug 18 07:07:42 2015 -0400 clean up some imports commit 8ccdf4821f2dcac2b2c0f210d07679b5178f0211 Author: Clearfield Christopher Date: Sat Aug 15 19:50:50 2015 -0700 BUG: Fix MLK and Memorial day date representations, #9760 commit 914b5dd3b551c52952b5f98f5004116dcdbea3d0 Merge: bc45bca 99b90de Author: Jeff Reback Date: Tue Aug 18 06:51:57 2015 -0400 Merge pull request #10716 from sinhrks/salign BUG: Series.align with MultiIndex may be inverted commit bc45bcac3964b91c57ee782ce1ce87b14fec1a0e Merge: a4875d6 7a9268d Author: Jeff Reback Date: Tue Aug 18 06:48:47 2015 -0400 Merge pull request #10810 from sinhrks/dup_doc DOC: Updated drop_duplicates doc commit a4875d66cc5813f3494123dfdc9b2daa8f9a2306 Merge: 20a85f8 451f308 Author: Jeff Reback Date: Tue Aug 18 06:47:43 2015 -0400 Merge pull request #10841 from MatthewGilbert/master DOC: Fix for #10823, updating min_periods docstring commit 20a85f8b7bdc89d40ae336a8bc5e161560bd40a3 Merge: 13cb1a7 f07e582 Author: Jeff Reback Date: Tue Aug 18 06:44:03 2015 -0400 Merge pull request #10838 from jreback/mi_panel BUG: Panel setitem with a multiindex #10360 (partial) commit 451f3080e65553ab74dacf5837a53340e35e9385 Author: Matthew Gilbert Date: Mon Aug 17 22:09:17 2015 -0400 DOC: Fix for #10823, updating min_periods docstring commit f0706b1843883f12807baeaad8a6046dd8f767e9 Author: Chris Date: Mon Aug 17 20:46:55 2015 -0500 PERF: value_counts_float64 #10821 commit 6c3da7f0dc67727590b9bdccd40a56e10fc58341 Author: Ka Wo Chen Date: Tue Jul 28 02:49:52 2015 -0400 BUG: GH10581 where read_msgpack does not respect encoding ENH: msgpack submodule version updated to 0.4.6 commit f07e582aef5a3ca6e3f406c56c38a8b26b6c69d9 Author: Jeff Reback Date: Mon Aug 17 18:24:11 2015 -0400 BUG: Panel setitem with a multiindex #10360 (partial) commit 13cb1a77471104cf89d0d74a6c5ee8c0c9c1247c Merge: 35cc80d e4368de Author: Jeff Reback Date: Mon Aug 17 16:50:10 2015 -0400 Merge pull request #10836 from cel4/fix_locale_failure skipped failing test on non-engish locales commit e4368de1ea2a6f62290ade05875f4c645c79c0f4 Author: cel4 Date: Mon Aug 17 19:22:26 2015 +0200 skipped failing test on non-engish locales commit 93754600e50afeb4e0636c09e17739aac6f03df4 Author: sinhrks Date: Sat Aug 15 22:55:42 2015 +0900 BUG: Merge with empty dataframe may raise IndexError commit 35cc80d83ee3e2065245b40f803f489ab641136d Merge: 05a8bad 780396b Author: Jeff Reback Date: Mon Aug 17 07:09:50 2015 -0400 Merge pull request #10825 from evanpw/csv_eof Fix handling of EOF in 'c' csv parser commit 05a8badce4a786eed17d6a4fc1287c84023024da Merge: 551f424 fe58ee3 Author: Jeff Reback Date: Sun Aug 16 05:54:59 2015 -0400 Merge pull request #10829 from dvmk/master Minor fix to error messages ('See the the caveats in the documentatio… commit 551f424e38fb3be9e685e995e375704caa1fca11 Merge: 2113672 a61d299 Author: Joris Van den Bossche Date: Sun Aug 16 10:28:53 2015 +0200 Merge pull request #10812 from jorisvandenbossche/depr-combine Deprecate combineAdd and combineMult (GH10735) commit fe58ee396b564284539b4c45ad928a3311a1b912 Author: David Kelly Date: Sun Aug 16 03:27:07 2015 -0500 Minor fix to error messages ('See the the caveats in the documentation...') commit 2113672040a884e8a3b18881e9608fed795e1129 Author: Luis Ortiz Date: Mon Jul 13 17:07:31 2015 +0000 BUG: GH8243 Change unary - to ~. Fixes numpy warning in ols. commit 780396b0098da830197cb0fcd230ca5c652193e7 Author: Evan Wright Date: Sat Aug 15 09:57:01 2015 -0400 BUG: Fix handling of EOF in 'c' csv parser (GH #10728, #10548) commit 433602022bfbb9ee2424b77694c60f276065dee8 Author: Safia Abdalla Date: Fri Jul 10 21:38:33 2015 -0700 ENH: Added functionality in resample to resolve #10530 Added tests for updated resample function Changed if-statement to be lower-bound inclusive Undid previous change to if statement Fixed typo in resample.py Fixed typo in _get_time_bins Updated _resample_timestamp function Updated condition in if-statement Updated exceptions raised in resample Moved test case into proper file Fixed typo in test case Updated tests for resampling fix ENH: Updated code for fixing #10530 Removed extraneous print statements from tests Moved code for fix to _get_time_delta_bins function Updated tests for resample TimeDeltaIndex with base Updated code for resample TimeDeltaIndex with base Removed print statements from test case Removed print statement in tests Added note to what's new Removed extra whitespace Removed addtional whitespace Removed whitespace Removed whitespace in resample.py Removed more whitespace in resample.py Removed more whitespace commit 09c4f73d7f331e70c26094374452e43821171fe4 Merge: 58db03e 661b7d7 Author: Jeff Reback Date: Sat Aug 15 18:22:36 2015 -0400 Merge pull request #10827 from evanpw/empty_nrows_chunksize Bug in read_csv when using nrows or chunksize on a file containing only a header commit 58db03eec9bd6d78976b844267c3c1a9f61a8eb3 Author: cel4 Date: Tue Dec 30 14:28:51 2014 +0100 ERR: improved error message when concatenating an empty sequence of dataframes, #9157 commit 661b7d766ef5acd609087fa960285f4e78986e6f Author: Evan Wright Date: Sat Aug 15 12:39:29 2015 -0400 BUG: read_csv fails when using nrows or chunksize on a file containing only a header (GH #9535) commit a61d299c16e676805215d651096d593d60b80ade Author: Joris Van den Bossche Date: Thu Aug 13 10:33:34 2015 +0200 Deprecate combineAdd and combineMult (GH10735) commit bcc7b0b6f8329c421d1991d1b4989afdc46ab90c Merge: 63c587d c0ff3e7 Author: Jeff Reback Date: Fri Aug 14 14:40:52 2015 -0400 Merge pull request #10808 from ajcr/iloc-negative-index BUG: fix bounds for negative ints when using iloc (GH 10779) commit c0ff3e7d03071f0a2847796b966d7279b18ac3bd Author: ajcr Date: Thu Aug 13 19:57:15 2015 +0100 BUG: fix bounds for iloc with negative integers (GH10779, GH10547) commit 63c587d9233ac18fb938a0cb9f1612a78ec7a7e2 Author: Jeff Reback Date: Fri Aug 14 12:31:33 2015 -0400 TST: skip shape comparison test in test_testing commit 8e15810e38ea32e7ee61ad148e20f88fd49f58e8 Author: Jeff Reback Date: Fri Aug 14 12:03:45 2015 -0400 DOC: doc/setup fixes for #9711 commit 7ed0b26d9594173cf5545348ab0a318880a3f5e2 Author: jreback Date: Fri Aug 14 11:47:22 2015 -0400 TST: need to use platform int on .take commit b2bc0a04a0726100acc3524874ef6b5cff607dae Merge: a2ac432 4694a42 Author: Jeff Reback Date: Fri Aug 14 11:40:16 2015 -0400 Merge pull request #9711 from kshedden/sas_xport SAS xport file reader commit 4694a428fd63e971159fffea4559e589088881e9 Author: Kerby Shedden Date: Fri Aug 14 04:03:38 2015 -0400 Minor changes following code review commit a2ac43240339a0a03bfb5028d579bf3b7d268664 Merge: f6d7c49 ac97541 Author: Jeff Reback Date: Thu Aug 13 09:07:42 2015 -0400 Merge pull request #10744 from chris-b1/dateoffset-add Allow DateOffset addition with Series commit ac975417636ae37eaa14dc3d5c23db80ceaf0a97 Author: Chris Date: Mon Aug 3 23:24:22 2015 -0500 ENH: Allow DateOffset operations with Series commit 7a9268d98ff92fc73bfa77c282422270baf16592 Author: sinhrks Date: Wed Aug 12 13:34:53 2015 +0900 DOC: Updated drop_duplicates doc commit f6d7c491f8896235f1ddc86e48963fdba0adfeb2 Merge: 12e6fe5 c06dd9b Author: Sinhrks Date: Wed Aug 12 22:51:50 2015 +0900 Merge pull request #10791 from sinhrks/take_freq BUG: Index.take may add unnecessary freq attribute commit 12e6fe5bee23cc41bd3bcb4acf653486bde64501 Merge: e945d7e 140995e Author: Jeff Reback Date: Wed Aug 12 09:44:32 2015 -0400 Merge pull request #10776 from kawochen/BUG-FIX-10747 BUG: GH10747 where cast_to_nanoseconds from NaT fails commit e945d7ed8f5507f0f0879609ee96670bfcaf4550 Merge: 490b940 5149e8c Author: Joris Van den Bossche Date: Wed Aug 12 13:37:32 2015 +0200 Merge pull request #10794 from jorisvandenbossche/doc-dev-versionadded DOC: add guideline to use versionadded directive to contributing docs (GH10215) commit 5149e8c7688eab1fb56009cded6d5f80411bb8a9 Author: Joris Van den Bossche Date: Tue Aug 11 11:12:26 2015 +0200 DOC: add guideline to use versionadded directive to contributing docs (GH10215) commit 490b9406341d797c2df33af44d25c6d4cf99e9ad Merge: 60c1a1d b6444e0 Author: Joris Van den Bossche Date: Wed Aug 12 11:55:47 2015 +0200 Merge pull request #10795 from sinhrks/dup_test TST: Suppress warnings of drop_duplicates tests commit 60c1a1db072fbfeb4eda1e028957b23261ab19fa Merge: 25be2f2 113b1ad Author: Joris Van den Bossche Date: Wed Aug 12 11:31:13 2015 +0200 Merge pull request #10803 from IamGianluca/fix_issue_10750 BUG: Allow read_sql_table to read from views commit 113b1adc4b4fa267ca668766a94e1a378d06d821 Author: Gianluca Rossi Date: Wed Aug 12 08:02:14 2015 +0100 BUG: Allow read_sql_table to read from views commit 140995eec716fabcd2e77388417133acc85144d9 Author: Ka Wo Chen Date: Sun Aug 9 02:39:22 2015 -0400 BUG: GH10747 in astyping of a NaT-like commit 25be2f22d59f7750788f8a130fb539f8d60de488 Author: Joris Van den Bossche Date: Wed Aug 12 00:42:00 2015 +0200 DOC: fix namespace commit c06dd9ba32370b0df280d58aab8cfb59e4dc0e20 Author: sinhrks Date: Tue Aug 11 07:20:01 2015 +0900 BUG: Index.take may add unnecessary freq attribute commit b6444e0bb8f4d2cb7388eea129feec499a89dbaa Author: sinhrks Date: Tue Aug 11 16:03:56 2015 +0900 TST: Suppress warnings of drop_duplicates tests commit 016dbe61853152d74904f4e168ae12597bda704e Author: ganego Date: Mon Aug 10 14:49:43 2015 +0200 Update install.rst - Added hint regarding pip install on low memory machines. - Added hint to python 3 version of pandas from distributon repos. commit 1e394fee3e4890fa7a905a962434d11e9033961b Merge: 529288e 4ed857e Author: Sinhrks Date: Tue Aug 11 01:27:46 2015 +0900 Merge pull request #10507 from sinhrks/test_assert TST: make assertion messages more understandable commit 478af3b28cbbb040a9dac97212924389965e36f6 Author: Kerby Shedden Date: Mon Mar 23 09:39:34 2015 -0400 Support for reading SAS xport files commit 4ed857e1616d407d5223180d0130b6d982b4ef85 Author: sinhrks Date: Fri Jun 26 04:54:37 2015 +0900 TST: make assertion messages more understandable commit 529288e0d187aeff7617ec10e287559bc5407c1c Merge: 0259ace 1b913ba Author: Sinhrks Date: Sun Aug 9 04:46:01 2015 +0900 Merge pull request #10236 from sinhrks/duplicated ENH: duplicated and drop_duplicates now accept keep kw commit 0259acef1085499c7a9c6a875162880a5020c7de Merge: a6df004 ec2064a Author: Sinhrks Date: Sun Aug 9 04:43:55 2015 +0900 Merge pull request #10718 from sinhrks/cat_dttz BUG: Categorical doesn't show tzinfo properly commit 1b913ba6671f0210e7f1ebaff203f57a31e2fe51 Author: sinhrks Date: Sun Mar 30 21:18:22 2014 +0900 ENH: duplicated and drop_duplicates now accept take=all kw commit a6df0042532a0ed116b2ffdeab7de0268d7572d8 Merge: e9b1a10 9642ec9 Author: Sinhrks Date: Sat Aug 8 23:38:46 2015 +0900 Merge pull request #10305 from sinhrks/pidx_order BUG: PeriodIndex.order doesnt preserve freq commit ec2064aecfe943215dd812898d8737f6391996f5 Author: sinhrks Date: Sat Aug 1 23:06:52 2015 +0900 BUG: Categorical doesn't show tzinfo properly commit 9642ec98735f805ffab9bb011bb02c75cc680b99 Author: sinhrks Date: Mon Jun 8 22:26:25 2015 +0900 BUG: PeriodIndex.order doesnt preserve freq commit e9b1a1009f3aed2b1aad834779ec277526f9fd6a Merge: 5a4d60f 32f5517 Author: Jeff Reback Date: Sat Aug 8 08:18:12 2015 -0400 Merge pull request #10433 from behzadnouri/stack-dupl-indx BUG: closes bug in stack when index is not unique commit 99b90de62e416d7f649f1153df0cbfc8702ec980 Author: sinhrks Date: Sat Aug 1 09:40:40 2015 +0900 Series.align with MultiIndex may be inverted commit 5a4d60f9e400ebc4bd68df6b77bb3c7dce8ce2f2 Merge: ff163a8 a209fe4 Author: Joris Van den Bossche Date: Fri Aug 7 12:54:07 2015 +0200 Merge pull request #10418 from carpevitam/master improve documentation for pandas.Series.interpolate commit a209fe487fbf4b798ad7a23b3fb3d038203346df Author: Andy Li Date: Tue Jun 23 13:25:54 2015 -0700 improve documentation for pandas.Series.interpolate commit 32f551795031bee130bb2dc2aa3812b5f78df947 Author: behzad nouri Date: Wed Jun 24 19:43:34 2015 -0400 closes bug in stack when index is not unique commit ff163a863da98f30c362956cd65e1e8fad7e3bd0 Merge: 83d4dfd d0bcb06 Author: Jeff Reback Date: Thu Aug 6 11:16:59 2015 -0400 Merge pull request #10757 from jbuyl/fix-read-stata-column-reordering BUG: Fix dtypes order when ordering is different from original file in pandas.io.stata.read_stata commit d0bcb06ba0213a369cd4d7682084b0f4cd440239 Author: Jonas Buyl Date: Thu Aug 6 14:37:29 2015 +0200 Fix column reordering commit 83d4dfd3e3ba20693605ab3e3129e2b7ed42b785 Author: seth-p Date: Wed Sep 3 10:11:49 2014 -0400 ENH: Added api_rst_coverage.py (#8166) commit 278930e4628524187c87150a2b10446b12310791 Merge: c8e8a10 4f7b514 Author: Spencer Carrucciu Date: Wed Aug 5 17:47:01 2015 -0400 Merge branch 'master' of https://github.com/scarrucciu/pandas commit c8e8a1069afb40e3f2f6a3fad0b9e6172bbf410f Author: Spencer Carrucciu Date: Wed Aug 5 17:46:25 2015 -0400 Squashed commit of the following: commit 4f7b514076358a66cbbc1bc629b7a5dc8ff17cbe Author: Spencer Carrucciu Date: Thu Jun 25 22:27:01 2015 -0400 changed to test_round_trip commit 22d9ad5b141fcc3663050a05d54634a0a092272b Author: Spencer Carrucciu Date: Thu Jun 25 19:50:32 2015 -0400 move def test_round_trip_pickle to tseries.test.test_period.py commit 81f76f226a81c9aae0d1cb52476650d6da861f2e Author: Spencer Carrucciu Date: Thu Jun 25 19:46:13 2015 -0400 move to tseries tests commit f55d3dc90d68e622d365a2a7ad6ae0468ffcabab Author: Spencer Carrucciu Date: Thu Jun 25 19:42:48 2015 -0400 create test for period class with pickle round trip method commit f9c517fc92be0314be8a184f456bb32a17fb8218 Author: Spencer Carrucciu Date: Thu Jun 25 13:47:09 2015 -0400 implement __reduce__/__setstate__ for Period pickle support commit c74820e4a5b3a2970fe90ce28104ee235684c506 Merge: 0e0a364 2a2a6d1 Author: Sinhrks Date: Wed Aug 5 19:29:55 2015 +0900 Merge pull request #10346 from sinhrks/to_html_bug BUG: df.to_html(index=False) renders index.name commit 0e0a364377e29da131b975d7bb6bdc4f69507cb0 Merge: 7f820f9 fb74f18 Author: Joris Van den Bossche Date: Wed Aug 5 10:12:32 2015 +0200 Merge pull request #10733 from jorisvandenbossche/doc-to_datetime DOC: to_datetime outdated example commit 7f820f9f664635474dcf05199648cc28b35b6d49 Merge: 0479a80 0fbc88a Author: Joris Van den Bossche Date: Wed Aug 5 08:44:58 2015 +0200 Merge pull request #10751 from fpinter/patch-1 Fix docstring spelling commit 0479a806584c0c1df7ffd2c7bd9b2ce4a495a7de Merge: f1719b7 39b8ce3 Author: Jeff Reback Date: Tue Aug 4 18:30:32 2015 -0400 Merge pull request #10393 from cpcloud/df-partial-sort Add nlargest/nsmallest for DataFrame commit 0fbc88a3e5376ff507755f23b50c099fc7f580d7 Author: Frank Pinter Date: Tue Aug 4 14:32:21 2015 -0700 Fix docstring spelling "analagous" -> "analogous" commit f1719b72c46f88807dd91cf6a092c2da12e676ca Merge: 4309dac 2289185 Author: Joris Van den Bossche Date: Tue Aug 4 23:15:43 2015 +0200 Merge pull request #10749 from jorisvandenbossche/doc-fixes DOC: fix some doc build errors/warnings commit 2289185ca41f50c0e25b0c86c515f4f90eb88ad6 Author: Joris Van den Bossche Date: Tue Aug 4 20:46:26 2015 +0200 DOC: fix some doc build errors/warnings commit 4309dac743c8c9cb5327770eee7e60f52050425a Merge: 94e394a 6bdcb16 Author: Tom Augspurger Date: Tue Aug 4 12:38:52 2015 -0500 Merge pull request #10729 from TomAugspurger/categorical-value_counts API: CategoricalIndex for value_counts commit 39b8ce3c26250528856aecb323ee96ca075b385b Author: Phillip Cloud Date: Mon Apr 13 11:30:21 2015 -0400 Implement nlargest and nsmallest for DataFrames commit 6bdcb164929cad21375db6b1de803f34edd52890 Author: Tom Augspurger Date: Thu Jul 30 18:07:19 2015 -0500 API: CategoricalIndex for value_counts Changes ``Categorical.value_counts`` to return a Series with a CategoricalIndex. Previously the Series and an Index. commit 94e394a237d0a3cba6f6a5e1c35e7cfbf06212af Merge: d3fed34 117ea52 Author: Jeff Reback Date: Tue Aug 4 08:27:27 2015 -0400 Merge branch 'kawochen-TST-TestMsgpack-gen' commit 117ea520ba6f394e425425a67c9a719b814222b1 Author: Ka Wo Chen Date: Mon Aug 3 23:25:36 2015 -0400 TST: test_packers.TestMsgpack checks for minimum structure and extra keys commit d3fed34cc6706576d8b60e943b66c6c42d5df6f6 Author: Jeff Reback Date: Tue Aug 4 08:19:30 2015 -0400 Revert "Merge pull request #10743 from kawochen/TST-TestMsgpack-gen" This reverts commit f00e51cd4eb96537357b33932c9d78711ca4bdc9, reversing changes made to 58ae9dbf8a8ce919dfbe3b02dbb2a0c96b4e8db7. commit f00e51cd4eb96537357b33932c9d78711ca4bdc9 Merge: 58ae9db c574d2c Author: Jeff Reback Date: Tue Aug 4 07:47:19 2015 -0400 Merge pull request #10743 from kawochen/TST-TestMsgpack-gen TST: test_packers.TestMsgpack checks for minimum structure and extra … commit c574d2ccfeb0cf7bfe3a7a2498face7664e3cca8 Author: Ka Wo Chen Date: Mon Aug 3 23:25:36 2015 -0400 TST: test_packers.TestMsgpack checks for minimum structure and extra keys commit 58ae9dbf8a8ce919dfbe3b02dbb2a0c96b4e8db7 Merge: 304a5f4 cf1f181 Author: Jeff Reback Date: Mon Aug 3 18:03:11 2015 -0400 Merge pull request #10724 from ajcr/GH9431 BUG: pd.unique should respect datetime64 and timedelta64 dtypes (GH9431) commit cf1f181b8dcd5f4a7f2989deac9f928c91e43520 Author: ajcr Date: Sun Aug 2 12:12:41 2015 +0100 BUG: pd.unique should respect datetime64 and timedelta64 dtypes (GH9431) commit fb74f18ea165154aec4d8af31b1c315a8474fea0 Author: Joris Van den Bossche Date: Mon Aug 3 14:56:47 2015 +0200 DOC: to_datetime outdated example commit 304a5f445c40a849ae99ff94e3df6e173e9cbfac Merge: babfc0d 30d9a7f Author: Jeff Reback Date: Mon Aug 3 08:40:41 2015 -0400 Merge branch 'mortada-dt_strftime' commit babfc0db14ee06a6c44276041c92d9f63c11f6f4 Merge: f88ce3b d751c63 Author: Jeff Reback Date: Mon Aug 3 08:09:19 2015 -0400 Merge pull request #10731 from jreback/data TST: better testing for io/data commit 30d9a7fcbaa276aed5c743d50311442108773c76 Merge: f88ce3b 4348781 Author: Jeff Reback Date: Mon Aug 3 07:09:04 2015 -0400 Merge branch 'dt_strftime' of https://github.com/mortada/pandas into mortada-dt_strftime commit d751c63bb01335847b1c52cdd95ff5317c892ea2 Author: Jeff Reback Date: Mon Aug 3 07:06:46 2015 -0400 TST: better testing for io/data commit f88ce3b8b265a21840b0eec831f46fc5b147174f Author: Joris Van den Bossche Date: Mon Aug 3 00:01:02 2015 +0200 DOC: fix whitespace in whatsnew commit 4b1cb266ce436f8712e8ea51cdd065f54a00fe98 Merge: 574a9df 22eb63c Author: Jeff Reback Date: Sun Aug 2 17:54:09 2015 -0400 Merge branch 'filter' commit 22eb63cbbc46c1610d57b7ce796d140d97059a67 Author: Jeff Reback Date: Sun Aug 2 17:46:23 2015 -0400 xref #10711, remove more iget warnings commit 574a9dfadeb75de44f8463914c1571bcf240eec0 Merge: 4024ec2 2226780 Author: Joris Van den Bossche Date: Sun Aug 2 23:46:24 2015 +0200 Merge pull request #10680 from jorisvandenbossche/doc-iter DOC: improve docs on iteration commit 4024ec250929401f6da3310bf5aacae6143edeec Merge: ae30697 66cec77 Author: Jeff Reback Date: Sun Aug 2 17:26:30 2015 -0400 Merge pull request #10513 from rosnfeld/issue_10451 BUG: display.precision options seems off-by-one (GH10451) commit ae3069750c6ded330345d04daee0cf7cb823a8af Author: Jeff Reback Date: Sun Aug 2 13:12:33 2015 -0400 DOC: move Categorical.name to deprecations section commit 0ed46a0786f226ada80cfc8bf8795ff715625025 Merge: 3bc19e5 b69bde6 Author: Jeff Reback Date: Sun Aug 2 13:07:09 2015 -0400 Merge pull request #10719 from jreback/irow DEPR: deprecate irow,icol,iget_value,iget in Series/DataFrame, #10711 commit 43487815b6003841fafc192b126d8c1e245ce5a2 Author: Mortada Mehyar Date: Wed May 13 10:53:02 2015 -0700 ENH: support .strftime for datetimelikes (closes #10086) commit 3bc19e5d68329709f9c97d11f19fe95af83c16fb Author: Jeff Reback Date: Sat Aug 1 10:17:14 2015 -0400 BLD: remove fake_pyrex commit fc08800ae71a18f2d5fa581c1d1713ebc3fbb908 Author: Andrea Bedini Date: Tue May 19 16:41:59 2015 +1000 BLD: Stop distributing ez_setup.py, #10168 The distributed version of ez_setup is few years out of date and the python packaging world is a fast moving target. Recent versions of Python 2 and 3 provide setuptools and pip out of the box. For other Python versions, we can point users to the official and up to date instructions at https://packaging.python.org/en/latest/installing.html commit 66cec775f3e283b3f6e6c02d07e4d0552772dac7 Author: Andrew Rosenfeld Date: Mon Jul 6 00:14:23 2015 +0100 BUG: display.precision options seems off-by-one (GH10451) commit b69bde6d9485fdd139ace82f4e84f2944fe30bbe Author: Jeff Reback Date: Sat Aug 1 10:57:34 2015 -0400 DEPR: deprecate irow,icol,iget_value,iget in Series/DataFrame, #10711 commit e13739a458aad695b94892dc211f427fe459230d Author: Jeff Reback Date: Sun Aug 2 09:16:44 2015 -0400 DOC: edits in io.rst commit 6b04681110e1c3fc6419562c54c4a626ca607c0e Author: Jeff Reback Date: Sat Aug 1 12:18:05 2015 -0400 DOC: release date revert commit fd4651af867d7efc077f431d79f3a8e0d8c41ebf Author: Jeff Reback Date: Sat Aug 1 11:53:38 2015 -0400 DOC: more whatsnew fixes commit 2a2a6d1c25b7279dd7a19668de2260cc0e6b04ee Author: sinhrks Date: Sat Jun 13 17:59:47 2015 +0900 BUG: df.to_html(index=False) renders index.name commit b1a1613e6c33777194b6aeb578a535705ef1ae0f Author: Jeff Reback Date: Sat Aug 1 10:34:00 2015 -0400 DOC: whatsnew updates commit e26b3b9bc5bfe3995cd7cd5d728710dc2b0b5947 Merge: 4157902 a42a90e Author: Joris Van den Bossche Date: Sat Aug 1 01:48:23 2015 +0200 Merge pull request #10714 from msund/patch-1 updating account info commit a42a90ea532fd3fb47e5b23481f1fa4fe3f24f5e Author: msund Date: Fri Jul 31 16:45:38 2015 -0700 updating account info commit 41579024d9da564a6b206690e2c92800ac426528 Merge: b281e65 2377b5c Author: Jeff Reback Date: Fri Jul 31 18:37:48 2015 -0400 Merge pull request #10097 from nickeubank/patch-1 Default values for dropna to "False" (issue 9382) commit b281e6570bc3bb3773520eff0b6965d5691e3ba2 Merge: 03be332 987b7e7 Author: Jeff Reback Date: Fri Jul 31 18:35:22 2015 -0400 Merge pull request #10674 from jreback/dt_default API: #10636, changing default of to_datetime to raise, deprecating coerce in favor of errors commit 2377b5c1aafa33fb5a3fb3966e0bb16b8bcd2c6a Author: Nick Eubank Date: Sat May 9 15:42:12 2015 -0700 Change pytable default for dropna to false (9382) commit 03be33210908713d71def9ec7ca7612867e67c63 Merge: fb2ebb6 0786158 Author: Jeff Reback Date: Fri Jul 31 07:14:36 2015 -0400 Merge pull request #10705 from jseabold/index-optional-pivot ENH: Index optional pivot commit 222678030bb721264fcee2fb992227a092b7e131 Author: Joris Van den Bossche Date: Mon Jul 27 01:12:25 2015 +0200 DOC: improve docs on iteration commit fb2ebb667e6a5532663899a34074ee539a7355e8 Merge: 829893d c0b43fa Author: Joris Van den Bossche Date: Fri Jul 31 09:23:04 2015 +0200 Merge pull request #10701 from jorisvandenbossche/fix-warning-test TST: fix usage of assert_produces_warning commit 078615847c6e402db67aab31c95ef1742341066e Author: Skipper Seabold Date: Thu Jul 30 11:05:14 2015 -0500 ENH: Make index optional in pivot. Closes #3962 TST: Test for index is None in pivot DOC: Add release note DOC: Formatting DOC: Document index=None commit 829893dbcb0d6a0fe04144acde392ac8fbf719d8 Merge: 8ae292c 5aa48ff Author: Joris Van den Bossche Date: Thu Jul 30 23:19:39 2015 +0200 Merge pull request #10706 from msund/patch-1 adding plotly to ecosystem commit 987b7e7e586b8df1d127406c69e0a9094a1a5322 Author: Jeff Reback Date: Sat Jul 25 10:24:04 2015 -0400 API: #10636, changing default of to_datetime to raise, deprecating coerce in favor of errors commit 8ae292c933e40a507e6256222039eb68e61c3fe7 Author: Jeff Reback Date: Thu Jul 30 14:33:19 2015 -0400 TST: winfix on dtype comparison, xref #10124 commit 5aa48ff47c1aaec44713495f28cc69d03e8fa0d8 Author: msund Date: Thu Jul 30 11:05:08 2015 -0700 Adding plotly to ecosystem commit 0e7906717a5e973ca5d9f571cd6fd098f7c864ea Author: Jeff Reback Date: Thu Jul 30 13:37:22 2015 -0400 fix up conda build recipe commit 70cb34c1bdbafaafe80c7587f45203805f58eaf7 Merge: ee5aa9e c84ab54 Author: Jeff Reback Date: Thu Jul 30 12:09:29 2015 -0400 Merge pull request #10124 from evanpw/issue_10114 BUG: Filter/transform fail in some cases when multi-grouping with a datetime-like key commit ee5aa9e919ab796d105f1d97d571f30b00948a10 Merge: 0b9db63 71b9cbb Author: Jeff Reback Date: Thu Jul 30 11:49:15 2015 -0400 Merge pull request #10619 from agijsberts/outer_indexer_right_empty Fix bug in outer_indexer where the special case of an empty right array resulted in bogus return data. commit 0b9db63ad46722e14c072cef5158c0b0c0d24f1e Author: Jeff Reback Date: Thu Jul 30 11:10:55 2015 -0400 TST: change Fred test to just look for some data commit cd8150d385fbf34f61767aefec7550aade949749 Merge: 92da9ed b8b4a69 Author: Jeff Reback Date: Thu Jul 30 10:36:19 2015 -0400 Merge pull request #10703 from jreback/index_sort BUG: Bug in Index construction with a mixed list of tuples #10697) commit b8b4a69187cb73be2c59daf9621c0bf964552a84 Author: Jeff Reback Date: Thu Jul 30 08:20:39 2015 -0400 BUG: Bug in Index construction with a mixed list of tuples #10697) commit c0b43fab91ac2fb08b1b824a2ee829c0fabba397 Author: Joris Van den Bossche Date: Thu Jul 30 11:13:26 2015 +0200 TST: fix usage of assert_produces_warning commit c84ab54b0268bc79b132209d9e5f5653d402af96 Author: Evan Wright Date: Tue May 12 16:49:02 2015 -0400 BUG: Filter/transform fail in some cases when multi-grouping with a datetime-like key (GH #10114) commit 92da9edd1f6e7d0beaf2e6c003838d3b4f96c90e Merge: d197833 976a045 Author: Sinhrks Date: Wed Jul 29 23:05:50 2015 +0900 Merge pull request #9814 from sinhrks/tsplot_df BUG: Repeated time-series plot causes memory leak commit 71b9cbbc71432b593430b23ece36cf67145a273d Author: agijsberts Date: Sun Jul 19 01:56:35 2015 +0200 Fixed bug in outer_indexer where the special case of an empty right array resulted in bogus return data. commit d197833c7d0f31daf71d7ab718549f9711bfa318 Merge: e2f1344 8be4d00 Author: Jeff Reback Date: Tue Jul 28 17:59:19 2015 -0400 Merge pull request #10248 from nipunreddevil/patch-1 Added link to aggregation and plotting time series commit e2f1344715d0d2998a05728ca08afe77dff49e30 Merge: c06f9ce 4ae02cf Author: Sinhrks Date: Wed Jul 29 06:45:17 2015 +0900 Merge pull request #10512 from sinhrks/test_nparray TST: Deprecate assert_numpy_array_equivalent commit 4ae02cfbd31ffa13ef7e9f95754c33c27dccfad7 Author: sinhrks Date: Sun Jul 5 08:03:47 2015 +0900 TST: Deprecate assert_numpy_array_equivalent commit c06f9ce1b98ed9fdd6d0515ca600d73d350aad5b Merge: a743743 29f1f42 Author: Sinhrks Date: Wed Jul 29 00:28:20 2015 +0900 Merge pull request #10508 from sinhrks/groupby_dtcat BUG: Groupby(sort=False) with datetime-like Categorical raises ValueError commit 29f1f42418d161b4690375acde5d5743bdd10772 Author: sinhrks Date: Sat Jul 4 10:27:11 2015 +0900 BUG: Groupby(sort=False) with datetime-like Categorical raises ValueError commit a7437430b5cb62e49a79b64d18eccfb2b4d6367f Author: Garrett-R Date: Sat Jun 27 21:25:41 2015 -0700 MAINT: minor refactoring and some documentation MAINT: minor readability edits to conf.py DOC: fix typos in documentation commit 7559522f4c599874cd05718acee452afe87e53c4 Author: Jan Rudolph Date: Mon Jul 20 14:57:17 2015 +0200 BUG: allow duplicate column names if they are not merged upon, #10639 commit 1d295cd95f8b06d28ddd026ec0ec3373effaf172 Author: Jeff Reback Date: Fri Jul 24 18:16:11 2015 -0400 provide proper index coercion with _shallow_copy for insert,delete,append operations commit 06a4d9130106c968dacbaeb6103e22cf8abb40d8 Author: maximilianr Date: Fri Jul 24 14:25:06 2015 -0400 Drop & insert on subtypes of index return their subtypes, #10620 commit bd73cd0149b7b7adaea6117664fecdc94a3f7dcf Author: Christoph Gohlke Date: Sun Jul 26 19:17:44 2015 -0700 Remove duplicate code commit 3db0e8271eb8d352c97f06beddf81fdc4f74a16f Author: Christoph Gohlke Date: Sun Jul 26 19:26:49 2015 -0700 Use Visual Studio 2013+ signbit function Use Visual Studio 2015+ stdint.h Don't define inline for Visual Studio 2015 commit a677217bb53ac518f612283a4681c7f3b86fe382 Merge: 18928c8 3793da0 Author: Joris Van den Bossche Date: Mon Jul 27 10:32:22 2015 +0200 Merge pull request #10666 from scls19fr/issue_10654 read_sql/to_sql can accept database URI as con parameter commit 18928c83a2d6729d0c4815cbd83a5d8c47e6c861 Author: Joris Van den Bossche Date: Mon Jul 27 09:55:59 2015 +0200 DOC: fix table in whatsnew commit 201760e4bb9ecbf5d479c210ae270c558235b089 Author: Chris Whelan Date: Sun Jul 26 19:21:46 2015 -0700 PERF: add initial asv config and vbench->asv conversion script commit 703f418b9b07a9c7dda622708851bb30de452773 Author: Chris Whelan Date: Sun Jul 26 19:20:49 2015 -0700 Fixes for vb_suite commit 9fed74d8147b18c6ecdf7ff248f2e151d2f90277 Author: Chris Whelan Date: Sun Jul 26 19:20:31 2015 -0700 Add period.pyx to package commit 3793da09c5a65c5b90ad742fc41a027f29a2c366 Author: scls19fr Date: Fri Jul 24 13:56:01 2015 +0200 read_sql/to_sql can accept database URI as con parameter (:issue:`10214`) read_sql/to_sql can accept database URI as con parameter (issue 10666) read_sql/to_sql can accept database URI as con parameter (issue 10666) read_sql/to_sql can accept database URI as con parameter (issue 10666) read_sql/to_sql can accept database URI as con parameter (issue 10666) commit 355b4623d842633746b29b6e7f1724af4cd87dae Merge: 30cbb02 e4639ee Author: jreback Date: Sat Jul 25 21:54:21 2015 -0400 Merge pull request #10632 from JanSchulz/rem_cat_name Remove Categorical.name commit e4639ee14f5562125886bca607e3a9615db0c439 Author: Jan Schulz Date: Sun Jul 19 23:28:13 2015 +0200 Remove Categorical.name to make it more numpy.ndarray like `name` was initialy introduced to save the name of a Series/column during a groupby, when categorical was mostly a helper for that. See here for the discussion: https://github.com/pydata/pandas/issues/10482 Closes: #10482 commit 30cbb0212321566772f3a82a56fddac1f3285541 Merge: 5cb70d9 c3effa6 Author: jreback Date: Sat Jul 25 10:52:12 2015 -0400 Merge pull request #10658 from ajcr/GH9428 BUG: GH9428 promote string dtype to object dtype for empty DataFrame commit c3effa622d1a09549d58fd513c1eeab07b364233 Author: ajcr Date: Wed Jul 22 22:56:59 2015 +0100 BUG: GH9428 promote string dtype to object dtype for empty DataFrame commit 5cb70d93a53f8a556c49bc4f3e78c135225944e2 Merge: 2f0c344 3d10b59 Author: jreback Date: Fri Jul 24 19:09:30 2015 -0400 Merge pull request #10662 from kshedden/stata118_doc Small doc update for Stata 118 support commit 2f0c344191be435b0302ad8e8af4ca3183f2fcf5 Author: Jeff Reback Date: Fri Jul 24 15:16:49 2015 -0400 TST: move test_parsing of s3 buckets to pandas-test public bucket commit df23f918cecbaf755cfdfc559a9ae98131fb390b Merge: 0d9bfa1 a92bd76 Author: jreback Date: Fri Jul 24 14:43:40 2015 -0400 Merge pull request #10649 from mdagost/url_gzip_fix ENH: allow gzip de-compression for files specified by a url commit 0d9bfa11281260f5cf2758e159d3724585367382 Author: Jeff Reback Date: Fri Jul 24 09:56:16 2015 -0400 add in .gz file to the repo for testing commit d739ec32ac8b14d3e1b520127784df89bc9f7189 Merge: 2242fd9 abb2df5 Author: jreback Date: Fri Jul 24 09:50:18 2015 -0400 Merge pull request #10644 from schettino72/gh10408-vectorized-setting-timestamp-column BUG: (GH10408, GH10412) in vectorised setting of timestamp columns commit 2242fd90b7242d6303455e312060e52fc87a197e Merge: ebea3a3 81d9e0b Author: jreback Date: Fri Jul 24 09:44:14 2015 -0400 Merge pull request #10637 from mortada/index_compare_tests BUG: made behavior of operator equal for CategoricalIndex consistent,… commit a92bd760797c2bb63041e46f7ab6ab74f9521869 Author: Michelangelo D'Agostino Date: Tue Jul 21 09:21:13 2015 -0500 ENH: Allow gzip de-compression for files specified by a url. commit 3d10b5924f212366ed7c4bf43f702d1bb809d8da Author: Kerby Shedden Date: Thu Jul 23 22:09:30 2015 -0400 Revise version support statement commit 9e34368063e58c9f8b53dd59685433c921f07d27 Author: Kerby Shedden Date: Thu Jul 23 10:09:59 2015 -0400 Small doc update for Stata 118 support commit abb2df5de15d98721ed7ee9ca2ba0f5b3d468eab Author: Eduardo Schettino Date: Tue Jul 21 15:22:50 2015 +0800 BUG: (GH10408, GH10412) in vectorised setting of timestamp columns Fix setting values with python datetime.date and numpy datetime64. commit ebea3a358a84d65c5a5fe44c8d6740f9f030106f Author: Jeff Reback Date: Thu Jul 23 07:40:33 2015 -0400 DOC: release note for #10516/#9882 commit 35fa0ccdc4d269c56a16c0b27d350d38bcfc7dc8 Merge: 31b7464 d194844 Author: jreback Date: Thu Jul 23 07:37:58 2015 -0400 Merge pull request #10516 from kshedden/stata118 Read Stata version 118 files closes #9882 commit 31b746403ceb5103c84d3365e71ce595771c2311 Merge: ed13da0 b298492 Author: jreback Date: Thu Jul 23 07:16:38 2015 -0400 Merge pull request #10659 from chris-b1/rolling-name BUG: #10565 Series.name lost in rolling_* funcions commit d194844d928185bc9b64dda2964f7a9c13eb9c08 Author: Kerby Shedden Date: Mon Jul 6 07:25:58 2015 -0400 Add support for dta version 118. commit b298492fe06e2b4c114f82dfc85d6bd26fa81feb Author: Chris Date: Wed Jul 22 19:12:38 2015 -0500 BUG: #10565 Series.name lost in rolling_* commit ed13da0e04ddf715ed527933167923792cdb2c65 Author: Jeff Reback Date: Wed Jul 22 14:19:17 2015 -0400 DOC: more enhancedperf fixes commit 8ec1c99c2056c836e75fa6f328faa33d4359b1c0 Author: Jeff Reback Date: Wed Jul 22 12:09:41 2015 -0400 DOC: use sub-headings in enhancedperformance.rst commit 81d9e0be80a5331db161f92800670cbdf2516af3 Author: Mortada Mehyar Date: Mon Jul 20 21:05:48 2015 +0800 BUG: made behavior of operator equal for CategoricalIndex consistent, improved unit tests commit 976a0452c353547936d17078162ff46938085179 Author: sinhrks Date: Sun Apr 5 12:45:29 2015 +0900 BUG: Repeated time-series plot causes memory leak commit 3bf13ac52d3b3831eefdf75162eef206c0e200b6 Merge: 818f0a7 640c5cb Author: jreback Date: Wed Jul 22 06:52:51 2015 -0400 Merge pull request #10614 from nickeubank/update_numba_docs Extended docs on numba commit 818f0a7e88762e9ac77609024ecb96ea185f4667 Merge: 6c48d12 dd538a3 Author: Sinhrks Date: Wed Jul 22 19:49:05 2015 +0900 Merge pull request #9894 from sinhrks/subplots_style ENH/BUG: color cannot be applied to line subplots commit 640c5cb5e82b9118b9a9c013f578d87ac27ac4e7 Author: Nick Eubank Date: Fri Jul 17 11:15:24 2015 -0700 Extended docs on numba commit 6c48d12d090f0a3f4d9a5c2d891e56f4485476e2 Merge: 751164d eefa29f Author: Tom Augspurger Date: Tue Jul 21 07:59:38 2015 -0500 Merge pull request #10604 from stephen-hoover/more-permissive-s3-reads ENH: More permissive S3 reading commit 751164daac71c749bac8131499c372eb5736075b Merge: c62cf68 022d7c5 Author: jreback Date: Tue Jul 21 08:39:43 2015 -0400 Merge pull request #10630 from jreback/winbuild TST: windows compat for testing / msgpack commit c62cf68fce9a156f7c7c2a74a6d2eda6448435cd Merge: a7a6e70 1eeeded Author: jreback Date: Tue Jul 21 07:40:02 2015 -0400 Merge pull request #10605 from Winterflower/9789-pandas-doc DOC: 9789 Added missing letter, fixed link and Examples formatting. commit a7a6e70459ca386c320f7a8dab5efec63e870f8c Merge: 384eb45 df249e8 Author: jreback Date: Tue Jul 21 07:37:50 2015 -0400 Merge pull request #10643 from kawochen/CLN-10566 CLN: Remove duplicate implementations of bind_method; typo in compat commit 022d7c5721f98a1ed30b61f73b3714022ec143ff Author: Jeff Reback Date: Sun Jul 19 16:40:17 2015 -0400 TST: skip buggy ujson tests on win-64/py2.7 commit b0c14c18aa52992c4c2b9cdc7b0da34e88a0ade2 Author: Jeff Reback Date: Sun Jul 19 16:06:01 2015 -0400 API: mspack compat on windows / right dtype.name rather than dtype.num commit 0efd52b04a7620cfa78a7d068dd7790344ffb717 Author: Jeff Reback Date: Fri Jul 17 18:47:32 2015 -0400 TST: skip buggy parsing test on win-64 commit dd538a3da306dbae4fcd929a0e1c0bb90845ccb2 Author: sinhrks Date: Sun Apr 12 11:09:58 2015 +0900 ENH/BUG: color cannot be applied to line subplots commit 384eb45587172b67c5de358b3e3c05cb0f61cdbd Author: Safia Abdalla Date: Mon Jul 20 23:06:17 2015 -0700 BUG: Fixed typo-related bug to resolve #9266 Fixed typo in _convert_to_ndarrays Added tests for typo fix commit d06537478486887042ef89141707f6b05695995e Author: Artemy Kolchinsky Date: Thu Jul 9 14:13:09 2015 -0400 BUG: get_dummies not returning SparseDataFrame Tests redo commit df249e8dbf1cc0098329914245789c3f7673c449 Author: Ka Wo Chen Date: Tue Jul 21 02:14:13 2015 -0400 CLN: Remove duplicate implementations of bind_method; typo in compat commit eefa29fa7ef332cada4a611ddd6bb22830a553a5 Author: Stephen Hoover Date: Thu Jul 16 14:30:42 2015 -0500 ENH: More permissive S3 reading When calling `get_bucket`, boto will by default try to establish that the S3 bucket exists by listing all of the keys that exist in it. This behavior is controlled by the "validate" keyword, which defaults to True. If your access key doesn't have permission to read everything in a bucket (even if you do have permission to read the file you're trying to access), this generates an uninformative exception. This PR sets "validate=False". This means that boto will trust you that the bucket exists, and not try to check immediately. If the bucket actually doesn't exist, the `get_contents_as_string` call a couple of lines later will generate the exception "S3ResponseError: S3ResponseError: 404 Not Found". One of the test cases expected a failure when reading the file "s3://cant_get_it/tips.csv"; with the changes in this PR, this file is now accessible. commit a3cca397fd07a7ddd607d892aee9e307413c9856 Merge: d25a9f3 1f01990 Author: jreback Date: Mon Jul 20 19:24:49 2015 -0400 Merge pull request #10615 from chris-b1/master PERF: Improve perf of to_datetime with ISO format commit 1f0199033e2e72e51fc412373fe48c8d6be38797 Author: Chris Date: Sat Jul 18 12:19:10 2015 -0500 PERF: Improve perf of to_datetime with ISO format commit d25a9f38119f3adde82abbc1c9f035429643a80d Merge: 5a9a9da a36988b Author: Sinhrks Date: Tue Jul 21 06:19:08 2015 +0900 Merge pull request #10558 from sinhrks/numexpr_0dim BUG: pd.eval with numexpr engine coerces 1 element numpy array to scalar commit a36988b30d0e43a0e0c6edec37a17dcdb6bf310a Author: sinhrks Date: Sun Jul 12 10:27:14 2015 +0900 BUG: pd.eval with numexpr engine coerces 1 element numpy array to scalar commit 1eeededdf45bb6403a0ed99f9dca4e750e7b7890 Author: Winterflower Date: Thu Jul 16 21:34:00 2015 +0100 DOC: 9789 Added missing letter, added link, fixed examples formatting DOC 9798: Fixed link and examples formatting Fixed for PEP8 compliance commit 5a9a9da80c1a8b3e146f579f581261257b604f66 Merge: 4bb45b1 59dd18b Author: jreback Date: Sat Jul 18 11:00:58 2015 -0400 Merge pull request #10613 from jreback/stata ENH: add StataReader context manager to ensure closing of the path commit 59dd18b3aeae80292f533d8ef1803cbad2eb4869 Author: Jeff Reback Date: Fri Jul 17 19:49:28 2015 -0400 ENH: add StataReader context manager to ensure closing of the path commit 4bb45b15bb4561e2fbb869a523e9258a91391542 Merge: 061c506 ed775bc Author: jreback Date: Sat Jul 18 09:30:43 2015 -0400 Merge pull request #10527 from kawochen/BUG-FIX-9618 BUG: GH9618 in read_msgpack where DataFrame has duplicate column names commit 061c5066ca8fcbe0ddb5242024c31053da76e3c6 Merge: 3089006 904aaea Author: jreback Date: Sat Jul 18 07:20:37 2015 -0400 Merge pull request #10577 from santegoeds/bugfix/csv_reader-empty-data-with-dtype-args Fixed bug where read_csv ignores dtype arg if input is empty. commit ed775bc5dd6771c492bf0b3c918a768f60835cf9 Author: Ka Wo Chen Date: Tue Jul 7 23:59:15 2015 -0400 BUG: GH9618 in read_msgpack where DataFrame has duplicate column names commit 30890064941ef86325dc99225c9aa750eeb4a75b Merge: d7c31ca 6955de6 Author: jreback Date: Fri Jul 17 20:03:27 2015 -0400 Merge pull request #10497 from bwillers/categorical_shift BUG: CategoricalBlock shift GH9416 commit 904aaea9232e0ea4a34a07f5c911cf11fb273074 Author: Tjerk Santegoeds Date: Sun Jul 5 18:21:12 2015 +0200 BUG: pd.read_csv uses dtype arg with empty input commit d7c31ca0a4831e11e86a1700da1915afd0d81741 Merge: c87fa18 68b43d8 Author: Sinhrks Date: Sat Jul 18 06:03:49 2015 +0900 Merge pull request #10609 from sinhrks/fama TST: test_read_famafrench fails with HTTP 404 commit c87fa18cc22c15d37c023581fad9a46fff31534d Author: Ka Wo Chen Date: Wed Jun 17 02:10:24 2015 -0400 ERR: GH9513 NaT methods now raise ValueError, return np.nan or return NaT commit b06105595868cf35bd60cc1b131de94ea3577176 Author: Jeff Reback Date: Fri Jul 17 10:39:04 2015 -0400 DOC: corrections for None/np.nan comparisons commit 2da060ce4a3635ece00ed947d26510be1a13cb08 Author: Jeff Reback Date: Fri Jul 17 10:22:53 2015 -0400 DOC: enhanced docs for #10569 commit 0de48d0dff01ca1b8f9b9aaf20958bcd4d6abf79 Merge: 5b97367 effb676 Author: jreback Date: Fri Jul 17 09:58:58 2015 -0400 Merge pull request #10569 from jreback/comp ERR: Boolean comparisons of a Series vs None will now be equivalent to null comparisons commit effb6761e1e7608c44e9bd1e02dfef2137c928fc Author: Jeff Reback Date: Fri Jul 17 09:30:49 2015 -0400 misc import cleanups commit 0bd25ab0c44e5e0a82c1abcca57d517a5fcc7659 Author: Jeff Reback Date: Fri Jul 17 09:26:20 2015 -0400 DOC: whatsnew changes commit 4def8e48d9aaa645b2a20a93ba0ad43417024ca1 Author: Jeff Reback Date: Fri Jul 17 08:58:44 2015 -0400 TST: fixes stata datetimelike comparisons for #10606 commit 26ee43e82390e52121b563d15ca1c68425d5b5fc Author: Kerby Shedden Date: Fri Jul 17 02:44:10 2015 -0400 Align options in chunk and full file read commit b381327acd2855b5b1e23ad87f25bee84cb322ce Author: Jeff Reback Date: Thu Jul 16 20:59:06 2015 -0400 DEPR: remove unordered types depreceation usage in core/index.py commit 8016a7f4443c7c1a8985a2acdd828fcfae6abedd Author: Jeff Reback Date: Thu Jul 16 14:23:49 2015 -0400 DEPR: remove visible deprecation warning for slicing in test_internals commit dccf5ebf7224af8fa26e0fc529c9b873f0393431 Author: Jeff Reback Date: Thu Jul 16 10:04:09 2015 -0400 DEPR: remove numpy deprecation warnings for i8 vs integer comparisions commit 4fe7c68728da2174f7ccd290a43e358f16a1a6f9 Author: Jeff Reback Date: Sat Jul 11 09:36:37 2015 -0500 ERR: Boolean comparisons of a Series vs None will now be equivalent of to null comparisions, rather than raise TypeError, xref, #1079 commit 5b973674bb4ac2ec17e0519912a2ec7cda7986b0 Merge: 0c19941 f1598d3 Author: Joris Van den Bossche Date: Fri Jul 17 15:46:29 2015 +0200 Merge pull request #10600 from jorisvandenbossche/doc-whatsnew-fixes DOC: some formatting fixes in whatsnew commit 0c19941fe6c983442a5e4cf18c47626dcda8cb26 Merge: c740bb0 6213fb3 Author: jreback Date: Fri Jul 17 09:05:06 2015 -0400 Merge pull request #10597 from cpcloud/cat-perf Improve categorical concat speed by ~20x commit 68b43d802f30ce596a9f7e7aac31e995f5c016fa Author: sinhrks Date: Fri Jul 17 19:01:13 2015 +0900 TST: test_read_famafrench fails with HTTP 404 commit 6213fb37e38228c681ef99e7a86f3dec4a58a408 Author: Phillip Cloud Date: Wed Jul 15 18:08:33 2015 -0400 Improve categorical concat perf by ~20x commit f1598d3e6f10b92c72090a431a972e7628e76bb5 Author: Joris Van den Bossche Date: Thu Jul 16 11:15:59 2015 +0200 DOC: ignore deprecation warnings for convert_objects (GH10265) commit 95a90e0108248ed9aa81d227c54d7bbc15309913 Author: Joris Van den Bossche Date: Thu Jul 16 11:01:43 2015 +0200 DOC: some formatting fixes in whatsnew commit c740bb0de6913c46c47c71ed06600821b2082876 Merge: 5c906ff d5ff457 Author: Joris Van den Bossche Date: Thu Jul 16 10:32:48 2015 +0200 Merge pull request #9947 from mortada/index_compare operator equal on Index should behavior similarly to Series commit d5ff45775bf5a542b627a1ac2a170b8fb39501c3 Author: Mortada Mehyar Date: Mon Apr 20 00:38:43 2015 -0700 BUG: operator equal on Index should behavior similarly to Series commit 5c906ff9262a2e1c250486eef5420da38cddf63d Merge: e023f2f c4a0147 Author: jreback Date: Wed Jul 15 20:08:25 2015 -0400 Merge pull request #10370 from jreback/build CI: use versioneer to have PEP440 versions commit e023f2f7d7739ab0c509d53f97066b6e60b04917 Author: Jeff Reback Date: Wed Jul 15 20:05:08 2015 -0400 TST: skip famafrench test for now commit 1381e51d3d6479264b9eaa116f903bfc35f2f9b3 Merge: b3c338d 84781f1 Author: Joris Van den Bossche Date: Thu Jul 16 01:37:23 2015 +0200 Merge pull request #10589 from bashtage/convert-objects-doc-fix DOC: Small improvement to convert_objects doc commit b3c338d20df125349115a1b5af680f466a5b6264 Merge: c538b3f c734896 Author: Joris Van den Bossche Date: Thu Jul 16 01:36:26 2015 +0200 Merge pull request #10593 from Winterflower/pandas-doc-10371 DOC-10371 Add note regarding supported interpolation methods for Series/DF commit c7348965855bb914825607d0c62caca4c2e8ad43 Author: Winterflower Date: Wed Jul 15 22:36:34 2015 +0100 Bug-10371: Add note regarding supported interpolation methods for MultiIndex series/dfs 10371: Added separating line and pretty formatting commit c538b3f9fcbbc2c3149ee462b64317168ec4a856 Author: jreback Date: Wed Jul 15 19:05:29 2015 -0400 TST: dtype comparisons on windows, xref #10472 commit 84781f1af1993ba35754c72600d807b2b0db4f6b Author: Kevin Sheppard Date: Wed Jul 15 17:03:12 2015 -0400 DOC: Small improvement to convert_objects doc Fix small issues in convert_objects doc [skip ci] commit 6246cc1bb5149863de09b470530b69f7e22cad87 Merge: 5b1e500 a80577e Author: Sinhrks Date: Wed Jul 15 23:31:09 2015 +0900 Merge pull request #9813 from sinhrks/plot_test TST: Split graphics_test to main and others commit a80577e2e5bafac3e4b15fca521a61527f55868e Author: sinhrks Date: Sun Apr 5 17:35:33 2015 +0900 TST: Split graphics_test to main and others commit 5b1e500ebf0637a98763bcf0892f26ae5d101b33 Merge: 50c1ee8 c2ea0d4 Author: jreback Date: Tue Jul 14 11:52:23 2015 -0400 Merge pull request #7599 from sinhrks/parsenat API/BUG: Make consistent datetime string parse function commit 50c1ee89d0d3d063920e4f6b5c8e031f3f5407c1 Merge: 35c0863 e9d6678 Author: jreback Date: Tue Jul 14 08:47:25 2015 -0400 Merge pull request #10265 from bashtage/enforce-coercion-conversion BUG: Ensure 'coerce' actually coerces datatypes commit e9d6678ac98c56ac057baa1a7be2e32a8aed5896 Author: Kevin Sheppard Date: Thu Jul 9 13:59:31 2015 -0400 CLN: PEP 8 improvements commit 0727803b27e6b0299a903a47aecde0b747c91b7e Author: Kevin Sheppard Date: Sun Jul 12 23:15:13 2015 -0400 BUG: Ensure 'coerce' actually coerces datatypes Changes behavior of convert objects so that passing 'coerce' will ensure that data of the correct type is returned, even if all values are null-types (NaN or NaT). closes #9589 commit 35c086396084fb929b6de40f7d7f3fa48d6f3b25 Merge: d00258e c6bab91 Author: jreback Date: Mon Jul 13 09:14:25 2015 -0400 Merge pull request #10502 from jorisvandenbossche/remove-na_fvalues CLN: remove na_fvalues from TextFileReader (read_csv et al) signature (GH10481) commit d00258e57302fc2d72ec1a6c3f75d58de705f7f4 Merge: 98961c5 3bd9b26 Author: Joris Van den Bossche Date: Mon Jul 13 15:12:02 2015 +0200 Merge pull request #10561 from jorisvandenbossche/doc-imports DOC: consistent imports (GH9886) part IV commit 98961c57ee4ee8de97562fe2d82dbb1f587d0d8c Merge: 83b2320 271ae44 Author: jreback Date: Mon Jul 13 08:42:41 2015 -0400 Merge pull request #10473 from bashtage/hdf-complex BUG: Enable complex values to be written to HDF commit 271ae441c1d0256b9c8b61449b21644e39c70cbf Author: Kevin Sheppard Date: Mon Jun 29 15:17:55 2015 -0400 BUG: Enable complex values to be written to HDF Enable table format to be used to store complex values in DataFrames, Panels and Panel4Ds. Add tests for both fixed and panel. Add exception when attempting to write Series with complex values. closes #10447 commit 83b232089b9292b11d4b9b00c0e50cc4a829f016 Merge: df1f5cf eccbfa7 Author: jreback Date: Mon Jul 13 06:56:10 2015 -0400 Merge pull request #10443 from bashtage/read-hdf-singleton ENH: Simplify using read_hdf for HDF files with one dataset commit eccbfa7f0caf89b93957633006a8b21b1c2bde99 Author: Kevin Sheppard Date: Thu Jun 25 15:51:03 2015 -0400 ENH: Simplify using read_hdf for HDF files with one dataset Allow read_hdf to be used without a key when a single pandas object is stored in a HDF file. Raises if multiple pandas objects found. commit df1f5cfe6b37bdba08e925a9f83d232b47a48afa Merge: e660c05 ece8223 Author: jreback Date: Sun Jul 12 22:40:09 2015 -0400 Merge pull request #10557 from kjordahl/bug/pickle-subclass-metadata Pickle subclass metadata commit ece82234d3e3cd55b12e2443fb7fb6b778f2fb25 Author: Kelsey Jordahl Date: Sun Jul 12 15:03:06 2015 -0500 ENH: Add attributes to serialize ENH: Add _metadata to _internal_names TST: Test for serialized metadata in subclass TST: Move test subclassed dataframe to testing utils to make it pickleable CLN: Remove __getstate__() from Series DOC: Add to whatsnew commit 3bd9b2695be12ec6f2e12865ee58d50226af6474 Author: Joris Van den Bossche Date: Sun Jul 5 21:12:45 2015 +0200 DOC: consistent imports (GH9886) part IV commit c2ea0d4d1f7333dfb5f35d0795267d8894a37d83 Author: sinhrks Date: Sat Jun 28 20:13:35 2014 +0900 BUG: each date parsing funcs results differently commit e660c058a662426afc4d8855aabf4677f01b4a4c Merge: b9e5f1e d82721c Author: jreback Date: Sat Jul 11 11:47:31 2015 -0500 Merge pull request #10542 from schettino72/10151-cleanup-up-platform-python-version-checks CLN: cleanup up platform / python version checks. fix GB10151 commit b9e5f1e8c29dde55e517cb53ce14834170c4bfb5 Merge: b855bb5 d555682 Author: Stephan Hoyer Date: Sat Jul 11 01:45:10 2015 -0500 Merge pull request #10493 from clarkfitzg/histogram_label ENH: GH10485 'Frequency' label for Series.plot commit b855bb53fa9ac9bf3d1c181c6a11ebbd498df743 Merge: 2b8b180 98fdcb6 Author: Joris Van den Bossche Date: Sat Jul 11 01:17:52 2015 +0200 Merge pull request #10262 from artemyk/mysql_numeric_identifier TST: test_sql: properly drop tables with names that need to be quoted commit d82721cf173acbbc27129152bb51d2b1d7a7c528 Author: Eduardo Schettino Date: Sat Jul 11 03:52:59 2015 +0800 CLN: cleanup up platform / python version checks. fix GB10151 commit 98fdcb6c68a6d5abdcba748605da06467f9d3fe0 Author: Artemy Kolchinsky Date: Wed Jun 3 15:31:53 2015 -0400 BUG: Should allow numeric mysql table names Allowing all numeric Cleanup Rebased Postgres fix Fix Fix Fix commit 2b8b180e2b32ad53cec4ef94b74a0c229b8b8484 Merge: bbec57d b114bad Author: jreback Date: Fri Jul 10 07:57:06 2015 -0500 Merge pull request #10541 from zafia/column-name-in-parser-exception ENH: Update exception message to resolve #10515 commit b114bad68b8f83e7f157016618408ae6a4623b6a Author: Safia Abdalla Date: Thu Jul 9 19:52:45 2015 -0700 ENH: Update exception message to resolve #10515 commit 6955de608710244498110edd1419518863ae153a Author: Bernard Willers Date: Fri Jul 3 09:36:15 2015 -0400 BUG: CategoricalBlock shift GH9416 CategoricalBlocks always seem to have ndim=1, even if multiple categoricals are in a frame with the same categories. This simplifies the axis shift logic somewhat. commit d555682cfc70836b166a9d315504e915c8dcb5b7 Author: Clark Fitzgerald Date: Thu Jul 2 10:31:31 2015 -0700 ENH: GH10485 'Frequency' label for Series.plot commit bbec57d6f881cb7d26ad65319595c8594381fe8c Merge: a14f513 a35d9b7 Author: jreback Date: Wed Jul 8 09:19:41 2015 -0500 Merge pull request #10472 from jvkersch/fix/var-welford-algorithm ENH: Make group_var_ use Welford's algorithm. commit a35d9b73c19a9fa79dc570f343b94362410ae287 Author: Joris Vankerschaver Date: Mon Jun 29 18:20:04 2015 +0100 ENH: Make group_var_ use Welford's algorithm. commit a14f513d5b7104bf5a16bfecf85da495ac39053c Author: Stephan Hoyer Date: Tue Jul 7 23:43:31 2015 -0500 Fix broken tests RE: immutability error message commit e317a706eb3ffa1b44986d824ab46426195b9cc5 Merge: 758ca05 e8d3c89 Author: Stephan Hoyer Date: Tue Jul 7 12:18:50 2015 -0700 Merge pull request #10525 from certik/typos Fix a typo 'does' -> 'do' commit e8d3c892becacabf1c919860aea352871da420e0 Author: Ondřej Čertík Date: Tue Jul 7 13:37:38 2015 -0500 Fix a typo 'does' -> 'do' commit 758ca05e2eb04532b5d78331ba87c291038e2c61 Author: Garrett-R Date: Sat Jun 27 15:11:12 2015 -0700 DOC: Add warning for newbs not to edit auto-generated file, #10456 commit b0946f00d364def9a58fb58c695723050eaa2f79 Merge: 3382e12 2f5952f Author: jreback Date: Tue Jul 7 10:53:55 2015 -0500 Merge pull request #10518 from ringw/hdf5-doc-fix DOC: Clarified PyTables "natural" names commit 3382e12b0d5aa990540a4b4fa8a84f70186d0631 Author: Richard Lewis Date: Wed Jul 1 20:34:10 2015 +0100 BUG: Series.from_csv not loading header names, #10483 commit 5a76b44f89922a3c3c8656fa039c1434e633da57 Author: Vincent Davis Date: Mon Jul 6 10:21:36 2015 -0600 BUG: inconsistent behavior with invalid dates in to_datetime, #10154 commit fbe8c0b746ed8d24c34d18ea5713d7d47bd94ff3 Merge: 9fef291 8523105 Author: jreback Date: Tue Jul 7 05:30:45 2015 -0400 Merge pull request #10469 from santegoeds/bugfix/fix-csv_reader-multiindex-empty-data BUG: Fix csv_read bugs when using empty input. GH10467 & GH10413 commit 85231050c7438425467a93686d1382000973efd8 Author: Tjerk Santegoeds Date: Mon Jul 6 22:43:49 2015 +0200 Add addition test for pandas.csv_read to test variations of index_col kwarg. commit 2f5952f44cd86682195583a0ffc11ec811632f10 Author: Dan Ringwalt Date: Mon Jul 6 14:23:47 2015 -0400 DOC: Clarified PyTables "natural" names commit 4b2ceeb955c3f5be725f7a8efb3d20477fc6bb2c Author: Tjerk Santegoeds Date: Thu Jul 2 22:55:10 2015 +0200 BUG: Fix csv_read bug with reversed index_col list. commit c4a0147c9e46c6b43501e126609c6d16c3eff2ba Author: Jeff Reback Date: Mon Jun 15 12:26:11 2015 -0400 CI: use versioneer, for PEP440 version strings #9518 use binstar build OSX stack testing, #7127 commit 9fef291756ad77a4c61c750f5cc53c3765d1535c Merge: 4a03e93 b8528da Author: Sinhrks Date: Mon Jul 6 21:54:05 2015 +0900 Merge pull request #10501 from sinhrks/test_dtcategorical TST: Fix test for datetime categorical commit 4a03e936426936068afb063e44393312d82d12ae Merge: bfe5a7f 9093447 Author: jreback Date: Mon Jul 6 08:41:42 2015 -0400 Merge pull request #10509 from sinhrks/gen_pickle TST: Simplify genelate_legacy_pickles.py usage commit bfe5a7f0c1d7250be68f1d2bceca2138d561014d Author: cyrusmaher Date: Wed Jun 17 23:59:06 2015 -0700 API: allow a filter regex to work on numeric labels, #10506 commit 0eb158745b484e7560d46135f9a42af2eed1d198 Author: Terry Santegoeds Date: Mon Jun 29 14:42:54 2015 +0100 BUG: Fix csv_read bugs when using empty input. GH10467 & GH10413 commit 909344714279755eabf7776481d8ec37ab967fed Author: sinhrks Date: Sat Jul 4 20:35:01 2015 +0900 TST: Simplify genelate_legacy_pickles.py usage commit 9da54ad0f92c54823e992dfbb4f572a01e173f0b Merge: 0859e07 fb677c8 Author: Sinhrks Date: Sat Jul 4 20:29:41 2015 +0900 Merge pull request #10500 from sinhrks/test_quantile TST: DataFrame.quantile should have Float64Index commit 0859e07b91393f3f464853a3a92eb23e05237583 Merge: 80597dc 3d54fe7 Author: jreback Date: Fri Jul 3 15:35:54 2015 -0400 Merge pull request #10499 from joshlk/master Updated to_hdf doc string commit 80597dc2a8a943b710317d1f56990af20e7c8657 Merge: bac025f 7327f6b Author: Joris Van den Bossche Date: Fri Jul 3 19:44:56 2015 +0200 Merge pull request #10105 from graingert/sqlalchemy-connectable support both sqlalchemy engines and connections commit b8528da859e10e9215bd2eb10efdc9ed7ffadb34 Author: Sinhrks Date: Fri Jul 3 12:39:58 2015 +0900 TST: Fix test for datetime categorical commit fb677c87e22e984c14380bfc515e30c1443366bd Author: Sinhrks Date: Fri Jul 3 12:35:39 2015 +0900 TST: DataFrame.quantile should have Float64Index commit 3d54fe7f2295b40b4d6e6b35f2dcff6bb8bfd523 Author: Josh Levy-Kramer Date: Fri Jul 3 14:49:35 2015 +0100 Updated to_hdf doc string Updated the docstring to make clear that a HDFStore is required for a buffer, if a path is not directly passed commit c6bab913e753518676cc4717f05bbea2aba8ad01 Author: Joris Van den Bossche Date: Fri Jul 3 15:45:09 2015 +0200 CLN: remove na_fvalues from TextFileReader (read_csv et al) signature (GH10481) commit 7327f6bb16cfcf0b7ddf12f5403c81aa3757211e Author: Thomas Grainger Date: Wed May 27 12:45:06 2015 +0100 support both sqlalchemy engines and connections Fixes #7877 update pymysql to 0.6.3 to avoid cursor bugs Add documentation and tests for SQLAlchemy connectables explicit reference to connection/engine in docs Temporary table test pass compile the connectable commit bac025fff88a8e4ef59955cd86cc733a58464c0c Merge: 5455aca f174c98 Author: Joris Van den Bossche Date: Fri Jul 3 15:33:49 2015 +0200 Merge pull request #10386 from jorisvandenbossche/get-schema-keys BUG: fix multiple columns as primary key in io.sql.get_schema (GH10385) commit f174c989f8dd15cd12ab37072cd421df9da21a0c Author: Joris Van den Bossche Date: Thu Jun 18 13:56:13 2015 +0200 BUG: fix multiple columns as primary key in io.sql.get_schema (GH10385) commit 5455acabae563f1b39c6dd9fc860096b3a2fcccc Merge: 5c5c811 2344ff2 Author: jreback Date: Fri Jul 3 07:58:52 2015 -0400 Merge pull request #10490 from kawochen/BUG-FIX-10369 TST/ERR: GH10369 read_msgpack checks argument type commit 5c5c811c6408911f23b7348aed0c23ac9f6cb8cc Author: Jeff Reback Date: Thu Jul 2 19:31:53 2015 -0400 more badges in README.md commit 127415cd6edf849413eea1740ce7c93d06ba46a2 Author: Jeff Reback Date: Thu Jul 2 18:44:37 2015 -0400 nicer README.md page commit 07d61605800378b78050ea920809365bef1b4085 Author: Jeff Reback Date: Thu Jul 2 18:17:25 2015 -0400 DOC: readme.md again commit 70d5929b4f8242e2044e1631ee23d2d984cae876 Author: Jeff Reback Date: Thu Jul 2 18:16:08 2015 -0400 DOC: update readme.md again commit 16442ebeb0943bfea65078a599218f353a869b21 Author: Jeff Reback Date: Thu Jul 2 18:13:27 2015 -0400 DOC: add downloads to the readme.md page commit 2344ff21a7902ba39f35a13f89a410922bbab334 Author: Ka Wo Chen Date: Thu Jul 2 08:41:01 2015 -0400 TST/ERR: GH10369 read_msgpack checks argument type commit 9ed13a1ed4337b1536369fdff37fb252a6fd282e Merge: 91030a6 edb572c Author: jreback Date: Thu Jul 2 15:09:35 2015 -0400 Merge pull request #9395 from larsmans/cleanup MAINT: get rid of some compiler warnings commit 91030a603ad4cd25442e419bf4e4ca011fd66089 Merge: 0189bae 9e6c29a Author: Joris Van den Bossche Date: Thu Jul 2 09:42:54 2015 +0200 Merge pull request #10488 from jaidevd/jd-doc-na-values DOC: Better explain the behaviour of na_values commit 0189bae3c24228d134c03c8727e4f420da5c43d9 Merge: c962c0b c80e132 Author: Stephan Hoyer Date: Thu Jul 2 00:11:13 2015 -0700 Merge pull request #10487 from ETF/patch-1 Small style consistency fix commit 9e6c29a35ab34a1c88dbac23af2e4b0a1f6ee6bd Author: Jaidev Deshpande Date: Thu Jul 2 09:45:36 2015 +0530 DOC: Better explain the behaviour of na_values commit c80e132100af88cb85daa89c87b64fa9743bb00e Author: ETF Date: Wed Jul 1 20:25:24 2015 -0700 Small style consistency fix Removed unneeded spaces in kwargs related to read_gbq() commit c962c0bf0c09dcbcc25b09439b4247fab7299e4b Merge: c4c5d44 762d680 Author: Sinhrks Date: Wed Jul 1 22:46:10 2015 +0900 Merge pull request #10464 from sinhrks/categorical_map BUG: Series.map using categorical Series raises AttributeError commit c4c5d4472bc17e885df706430dd79dda2b0690cb Merge: cbb2673 0451bc3 Author: Joris Van den Bossche Date: Wed Jul 1 15:21:04 2015 +0200 Merge pull request #10387 from sinhrks/plot_color_str BUG: DataFrame.plot raises ValueError when color name is specified by multiple characters commit 762d6807e04c1290d76d77602f9b83a8f98a9b57 Author: sinhrks Date: Sun Jun 28 15:39:13 2015 +0900 BUG: Series.map using categorical Series raises AttributeError commit cbb267386906635e6b0709e8dc96325d0087dd86 Merge: 6cb762f 204ce41 Author: Joris Van den Bossche Date: Wed Jul 1 12:58:05 2015 +0200 Merge pull request #10450 from harshnisar/GH10414-DOC-missing-example DOC: GH10414 Missing example in NA values in GroupBy commit 6cb762f1425f591f43ba4b2ba472135727e4b2b1 Merge: 054821d fe3cc07 Author: jreback Date: Wed Jul 1 06:53:21 2015 -0400 Merge pull request #10479 from jaidevd/jd-fix-csv-docstring Fix docstring for na_values in parsers commit 204ce413d4c00e448ef88441fdc88936f4c07688 Author: Harsh Nisar Date: Sat Jun 27 00:53:33 2015 +0530 DOC: GH10414 Missing example in NA values in GroupBy commit fe3cc076b3a4f71f82f42f146bc56ad7f79ba055 Author: Jaidev Deshpande Date: Wed Jul 1 10:20:06 2015 +0530 Add str as an option for na_values in docstring commit 054821dc90ded4263edf7c8d5b333c1d65ff53a4 Author: Jeff Reback Date: Tue Jun 30 17:20:15 2015 -0400 TST: 32-test fixes commit 16a44ad5a24b58310874fe4e9a51d5868d5aa950 Merge: d62f02b 0bc2904 Author: jreback Date: Tue Jun 30 06:55:03 2015 -0400 Merge pull request #10199 from jreback/gil PERF: releasing the GIL, #8882 commit d62f02b22441e23b4e06c91163f1eb63d3a7092f Author: Ka Wo Chen Date: Wed Jun 24 01:22:56 2015 -0400 BUG: GH9907 generate_range when start and end have higher resolution than offset commit 71ac2eb22c5c8c78aaf5a5207cfe1a1dfe9fcb2f Merge: 01995b2 572510c Author: jreback Date: Tue Jun 30 06:46:13 2015 -0400 Merge pull request #10458 from sinhrks/assert_isinstance TST/CLN: remove assert_isinstance commit edb572cf6720b58dc7c3bf9821c06abea95ae768 Author: Lars Buitinck Date: Mon Feb 2 17:39:50 2015 +0100 MAINT: get rid of some compiler warnings * uninitialized pointer * unused variables * unused function * ISO C prototypes * cimport * * useless cast before snprintf commit 01995b2c2c759c66b208dc0bd8a35f5f23c39b9f Author: Jeff Reback Date: Sun Jun 28 19:32:26 2015 -0400 DOC: fix formatting in DataFrame.to_csv doc-string commit 572510c77288077520f3a4166287c2c1b5c7728f Author: sinhrks Date: Sun Jun 28 07:51:13 2015 +0900 TST/CLN: remove assert_isinstance commit c97238c2e3b9475b0e30ab7b68ebcf1239ddcc10 Merge: c8d20a6 023fc37 Author: jreback Date: Sat Jun 27 18:04:22 2015 -0400 Merge pull request #10179 from sebp/bug_concat_categorical BUG: concat on axis=0 with categorical (GH10177) commit c8d20a6803e6444bce900a2f95c61ec357e5e711 Merge: 4c96ad9 fd26644 Author: Phillip Cloud Date: Sat Jun 27 15:04:41 2015 -0400 Merge pull request #10455 from cpcloud/odo-eco Add odo to ecosystem docs commit fd2664428b3466a44aa5181ce747f1534fb46f3e Author: Phillip Cloud Date: Sat Jun 27 11:52:52 2015 -0400 Add odo to ecosystem docs commit 023fc371cc900e28cffaf7b8c436b23f80e22f40 Author: Sebastian Pölsterl Date: Wed May 20 17:31:41 2015 +0200 BUG: concat on axis=0 with categorical (GH10177) commit 4c96ad9b4fbc02823e40839389aa39a46b1cfdc9 Merge: 654e739 125c5b0 Author: jreback Date: Sat Jun 27 10:39:07 2015 -0400 Merge pull request #10453 from mortada/str_doc_fix DOC: fixed docstrings for StringMethods ljust and rjust commit 125c5b07b5e36266ee35c106ded948113c2be52f Author: Mortada Mehyar Date: Sat Jun 27 21:56:03 2015 +0800 DOC: fixed docstrings for StringMethods ljust and rjust commit 654e7397280be9a681fafcf8f70cfe3e20a9ef47 Merge: 3908ad5 b6a9309 Author: Sinhrks Date: Sat Jun 27 12:51:56 2015 +0900 Merge pull request #10419 from sinhrks/base_name_handling BUG: Fix value_counts name handling commit 0451bc35472b6a3c9cdc5fd401e731e4ab91a45e Author: sinhrks Date: Wed Jun 17 22:45:33 2015 +0900 BUG: DataFrame.plot raises ValueError when color name is specified by multiple characters commit b6a9309b87c5c6b326ee001d43402b6a211ef3a0 Author: sinhrks Date: Tue May 12 22:43:01 2015 +0900 BUG: Fix value_counts name handling commit 3908ad53e33c74096eb5a682256dc13fb6e91e3a Author: Jeff Reback Date: Fri Jun 26 19:29:14 2015 -0400 DOC: release note for #9607, as_blocks copy arg commit 8eabc4edc6beb4d4addff5dcb72eea476b3f8d40 Author: tzinckgraf Date: Wed Jun 3 23:30:14 2015 -0400 ENH: allow as_blocks to take a copy argument (#9607) commit 0bc2904abc73cd11f50f1837c97446c09e2971bf Author: Jeff Reback Date: Fri May 22 14:41:15 2015 -0400 PERF: releasing the GIL, #8882 commit b08ab8eda52e6b1b10caebbf09d11566dae3e974 Author: Jeff Reback Date: Fri May 22 14:41:15 2015 -0400 PERF: vbenches for #8882, releasing the GIL commit 25fc49d975d74c5cb969089dcb3efeda15c3262f Author: Garrett-R Date: Sun Jun 14 02:03:31 2015 -0700 BUG: #10228 resampling empty Series caused segfaults commit 7e9026db746d2762c615b32e4e0ddf4cf1cc61e5 Author: juricast Date: Thu Jun 25 10:47:04 2015 +0200 BUG #GH10425 test_categorical big-endian fix whatsnew modified commit af3a76205ce316ba53535c7aaebe6b03d8fde976 Author: jreback Date: Fri Jun 26 15:13:00 2015 -0400 BUG: xref #10428, need platform_int as indexer commit d9fba8ea0b4357edc662f0a7d9978c4a2e7105fd Merge: 383865f 55d07c0 Author: jreback Date: Fri Jun 26 14:08:21 2015 -0400 Merge pull request #10383 from cancan101/interp_kwargs Allow passing other arguments to interpolation functions commit 4f7b514076358a66cbbc1bc629b7a5dc8ff17cbe Author: Spencer Carrucciu Date: Thu Jun 25 22:27:01 2015 -0400 changed to test_round_trip commit 22d9ad5b141fcc3663050a05d54634a0a092272b Author: Spencer Carrucciu Date: Thu Jun 25 19:50:32 2015 -0400 move def test_round_trip_pickle to tseries.test.test_period.py commit 81f76f226a81c9aae0d1cb52476650d6da861f2e Author: Spencer Carrucciu Date: Thu Jun 25 19:46:13 2015 -0400 move to tseries tests commit f55d3dc90d68e622d365a2a7ad6ae0468ffcabab Author: Spencer Carrucciu Date: Thu Jun 25 19:42:48 2015 -0400 create test for period class with pickle round trip method commit f9c517fc92be0314be8a184f456bb32a17fb8218 Author: Spencer Carrucciu Date: Thu Jun 25 13:47:09 2015 -0400 implement __reduce__/__setstate__ for Period pickle support commit 383865f2d6481ae19e1ef3b19806fa99ac26b286 Merge: 4a4fe0b 3f39d2a Author: jreback Date: Wed Jun 24 21:10:34 2015 -0400 Merge pull request #10431 from jreback/numpy_dev BUG: provide categorical concat always on axis 0, #10430 commit 3f39d2adc3108fdcd8230c7225af4f98045e0be6 Author: Jeff Reback Date: Wed Jun 24 20:08:45 2015 -0400 BUG: provide categorical concat always on axis 0, #10430 numpy 1.10 makes this an error for 1-d on axis != 0 commit 4a4fe0b0b4ed188c3d155f0d5b35fedf09aa3f2a Merge: ad37b5d 2874420 Author: jreback Date: Wed Jun 24 16:59:59 2015 -0400 Merge pull request #10290 from jreback/mi_perf PERF: improved performance of multiindex slicing commit ad37b5dbf9fa8d4ad47de3b2235ed6f4cc04410e Merge: 499eb21 09b73d5 Author: jreback Date: Wed Jun 24 16:46:26 2015 -0400 Merge pull request #10429 from jreback/td2 BUG: Timedeltas with no specified units (and frac) should raise, #10426 commit 499eb21343e7af4cdc9ff42e9d3ee1f8fe5a31b5 Merge: 512d9d5 9e517ac Author: jreback Date: Wed Jun 24 16:45:55 2015 -0400 Merge pull request #10428 from jreback/indexing BUG: using .loc[:,column] fails type coercion when the object is a multi-index commit 512d9d5db5573e04d84d888c3da792682b9cff7d Author: Jeff Reback Date: Wed Jun 24 16:28:27 2015 -0400 DOC: update missing.rst with ref to groupby.rst commit 55d07c0c0849a0f2ff75400c25b2b40ce75a2575 Author: Alex Rothberg Date: Thu Jun 18 01:02:55 2015 -0400 ENH: GH10378 Pass kwargs to interpolation methods. commit 09b73d55dfd35b418d64170334603eea45e77e23 Author: Jeff Reback Date: Wed Jun 24 09:12:56 2015 -0400 BUG: Timedeltas with no specified units (and frac) should raise, #10426 commit 9e517acb8720fd5f34541f12cd11d5ddb4e6afc5 Author: Jeff Reback Date: Wed Jun 24 08:51:07 2015 -0400 BUG: using .loc[:,column] fails when the object is a multi-index, #10408 commit 8e02d4539cf866160afb0dc0bd427725404eab7e Merge: 5bf4ff2 8545489 Author: Joris Van den Bossche Date: Wed Jun 24 12:53:33 2015 +0200 Merge pull request #10423 from ihoegen/master Removed scikit-timeseries migration docs from FAQ commit 85454897898d2304e2a4d6bfca3e97f5e649a5e3 Author: Ian Hoegen Date: Tue Jun 23 23:29:17 2015 -0700 Removed scikit-timeseries migration docs from FAQ Issue #10281 commit 5bf4ff29f41c2cb6601c7ce050cee3cd515c9fa0 Merge: 30197b5 0518e63 Author: Sinhrks Date: Tue Jun 23 23:12:07 2015 +0900 Merge pull request #10405 from sinhrks/test_unicode TST: Use unicode literals in string test commit 30197b54a1e2f5d0aac6faffe6528cef265729d2 Merge: 4220d47 60a6e9f Author: Sinhrks Date: Tue Jun 23 23:11:22 2015 +0900 Merge pull request #10367 from sinhrks/drop_duplicates_names BUG: drop_duplicates drops name(s). commit 4220d476803beeaebe2762b004ca60eb3e2d4528 Merge: b8367a0 3747e63 Author: jreback Date: Tue Jun 23 10:00:39 2015 -0400 Merge pull request #10400 from kawochen/BUG-FIX-10395 BUG: GH10395 bug in DataFrame.interpolate with axis=1 and inplace=True commit b8367a0b98b708ea082bb666bcca7e96d6110f4d Merge: 8f94f9b b308a8a Author: Joris Van den Bossche Date: Tue Jun 23 14:42:59 2015 +0200 Merge pull request #10359 from jorisvandenbossche/doc-imports2 DOC: consistent imports (GH9886) part III commit 3747e63380a5aaf792b5cc30ec9a6eed8dd23d7c Author: Ka Wo Chen Date: Sun Jun 21 02:20:12 2015 -0400 BUG: GH10395 bug in DataFrame.interpolate with axis=1 and inplace=True commit 8f94f9b17f1be75516b3238ed3191a220ca0de90 Merge: 7d6fb51 81eba22 Author: jreback Date: Tue Jun 23 07:00:14 2015 -0400 Merge pull request #10401 from kawochen/BUG-FIX-10392 BUG: GH10392 bug where Table.select_column does not preserve column name commit 81eba22080703bfb38e1db76b45879ffacdae338 Author: Ka Wo Chen Date: Sun Jun 21 11:40:58 2015 -0400 BUG: GH10392 bug where Table.select_column does not preserve column name commit 0518e634ffc3f2d2d6430fdd95fa394e88496ff3 Author: sinhrks Date: Mon Jun 22 21:40:16 2015 +0900 TST: Use unicode literals in string test commit 2874420f8633c23e095c6e3d20c5635785e41503 Author: Jeff Reback Date: Fri Jun 5 11:33:23 2015 -0400 PERF: fix _get_level_indexer to accept an intermediate indexer result commit b06925362dda6a69f1ee74b42879ea4232c9af5f Author: Jeff Reback Date: Fri Jun 5 09:21:11 2015 -0400 PERF: bench for #10287 commit 7d6fb510c1dfdbe7342f32f05ca5fd69b7854081 Merge: af8eb59 528d8ad Author: jreback Date: Mon Jun 22 09:46:37 2015 +0100 Merge pull request #10397 from jreback/py3.2 BLD: remove support for 3.2, #9118 commit af8eb5910ca0770b4edd24a32aa215ca8e7ae696 Merge: 2fea54a bb5ec57 Author: jreback Date: Mon Jun 22 09:34:19 2015 +0100 Merge pull request #10396 from jreback/td PERF: parse and timedelta ops improvements, #6755 commit 60a6e9f34018c8093553485d3611efb6af28a248 Author: sinhrks Date: Tue Jun 16 23:11:02 2015 +0900 BUG: drop_duplicates drops name(s). commit 2fea54af7699bfeda267d598010a4004b079cd49 Merge: 0b74c72 9220309 Author: jreback Date: Sat Jun 20 17:20:11 2015 +0100 Merge pull request #10376 from bashtage/improve-excel ENH: Enable ExcelWriter to construct in-memory sheets commit 92203096ceba0cfea72bb28d434f34f58e68bb0a Author: Kevin Sheppard Date: Tue Jun 16 18:05:53 2015 -0400 ENH: Enable ExcelWriter to construct in-memory sheets Add support for StringIO/BytesIO to ExcelWriter Add vbench support for writing excel files Add support for serializing lists/dicts to strings Fix bug when reading blank excel sheets Added xlwt to Python 3.4 builds closes #8188 closes #7074 closes #6403 closes #7171 closes #6947 commit 528d8ad442720cf99250b800759a27a8803a15d3 Author: Jeff Reback Date: Sat Jun 20 14:01:34 2015 +0100 BLD: remove support for 3.2, #9118 commit bb5ec5709a8d77ee68bfbd3e663458382c382eb3 Author: Jeff Reback Date: Sat Jun 20 10:20:20 2015 +0100 PERF: timedelta and datetime64 ops improvements commit 611bbc594ce3de0f3b1232da9176c6d266f84b76 Author: Jeff Reback Date: Thu Jun 18 13:44:38 2015 -0400 PERF: parse timedelta strings in cython #6755 commit 0b74c72e1c7fe320440fa97a3d256107ea329307 Merge: d8a2f30 c6d7a9a Author: jreback Date: Sat Jun 20 12:09:44 2015 +0100 Merge pull request #10389 from behzadnouri/nat-reset-index BUG: closes bug in reset_index when index contains NaT commit c6d7a9a7a48c05a3e49a2048365a7d23dd2e1854 Author: behzad nouri Date: Thu Jun 18 19:19:54 2015 -0400 closes bug in reset_index when index contains NaT commit d8a2f30e978cb606e146254083df9f3e987cffca Merge: 7636c2c 7da7c97 Author: jreback Date: Thu Jun 18 11:36:21 2015 -0400 Merge pull request #10379 from rekcahpassyla/empty_series_with_freq_setitem2 Check for size=0 before setting item commit 7da7c97602412f28bf51e46f775bc39bad255a26 Author: rekcahpassyla <0xdeadcafebeef@gmail.com> Date: Wed Jun 17 18:34:18 2015 +0100 Check for size=0 before setting item Fixes #10193 commit 7636c2c035f66ec94d5ed0ab63976d58a7e4df23 Merge: c98dcdf 76b06f0 Author: Sinhrks Date: Mon Jun 15 21:57:03 2015 +0900 Merge pull request #10350 from sinhrks/freq_tests BUG: frequencies.get_freq_code raises an error against offset with n != 1 commit c98dcdf8479b879d2d77d7366109334ba125404b Merge: 37fa925 47c0695 Author: jreback Date: Mon Jun 15 06:44:29 2015 -0400 Merge pull request #10354 from behzadnouri/cat-reduce BUG: closes bug in apply when function returns categorical commit 47c0695ba3025d1538f964ba6e85868560964aa7 Author: behzad nouri Date: Sun Jun 14 18:43:23 2015 -0400 closes bug in apply when function returns categorical commit 76b06f0cbad54b2e27766165bb142163505e0df2 Author: sinhrks Date: Sun Jun 7 11:11:13 2015 +0900 BUG: frequencies.get_freq_code raises an error against offset with n != 1 commit 37fa925dda808c403b45f3d2a64d9eca630dbcea Merge: af3c3a3 027310a Author: jreback Date: Sun Jun 14 10:36:19 2015 -0400 Merge pull request #10352 from jreback/doc-tests CI: run doc-tests always commit 027310aa04b9b11c47f5dde1c9398fb37ab7af92 Author: Jeff Reback Date: Sun Jun 14 08:59:49 2015 -0400 CI: run doc-tests always commit b308a8ae1c3c9e67e2516fa3146018ff984a7010 Author: Joris Van den Bossche Date: Sun Jun 14 12:27:53 2015 +0200 DOC: consistent imports (GH9886) part III commit 8be4d00d4835b973439d27b93002f1e78eff0055 Author: Nipun Batra Date: Tue Jun 2 15:22:08 2015 +0530 Added link to aggregation and plotting time series --- .binstar.yml | 32 +- .gitattributes | 1 + .gitignore | 9 +- .travis.yml | 14 - MANIFEST.in | 2 + README.md | 43 +- asv_bench/asv.conf.json | 66 + asv_bench/benchmarks/__init__.py | 0 asv_bench/benchmarks/attrs_caching.py | 23 + asv_bench/benchmarks/binary_ops.py | 236 + asv_bench/benchmarks/categoricals.py | 11 + asv_bench/benchmarks/ctors.py | 52 + asv_bench/benchmarks/eval.py | 239 + asv_bench/benchmarks/frame_ctor.py | 1706 +++ asv_bench/benchmarks/frame_methods.py | 936 ++ asv_bench/benchmarks/gil.py | 267 + asv_bench/benchmarks/groupby.py | 1683 +++ asv_bench/benchmarks/hdfstore_bench.py | 351 + asv_bench/benchmarks/index_object.py | 292 + asv_bench/benchmarks/indexing.py | 458 + asv_bench/benchmarks/inference.py | 138 + asv_bench/benchmarks/io_bench.py | 135 + asv_bench/benchmarks/io_sql.py | 215 + asv_bench/benchmarks/join_merge.py | 359 + asv_bench/benchmarks/miscellaneous.py | 30 + asv_bench/benchmarks/packers.py | 857 ++ asv_bench/benchmarks/pandas_vb_common.py | 1 + asv_bench/benchmarks/panel_ctor.py | 64 + asv_bench/benchmarks/panel_methods.py | 56 + asv_bench/benchmarks/parser_vb.py | 109 + asv_bench/benchmarks/plotting.py | 19 + asv_bench/benchmarks/reindex.py | 384 + asv_bench/benchmarks/replace.py | 48 + asv_bench/benchmarks/reshape.py | 76 + asv_bench/benchmarks/series_methods.py | 74 + asv_bench/benchmarks/sparse.py | 55 + asv_bench/benchmarks/stat_ops.py | 236 + asv_bench/benchmarks/strings.py | 393 + asv_bench/benchmarks/timedelta.py | 34 + asv_bench/benchmarks/timeseries.py | 1046 ++ asv_bench/vbench_to_asv.py | 151 + bench/bench_sparse.py | 3 +- ci/requirements-2.7.txt | 2 +- ci/requirements-3.2.txt | 4 - ci/requirements-3.4.txt | 1 + ci/requirements-3.4_SLOW.txt | 1 + ci/script.sh | 4 +- conda.recipe/bld.bat | 2 +- conda.recipe/build.sh | 4 +- conda.recipe/meta.yaml | 7 +- doc/source/api.rst | 16 +- doc/source/basics.rst | 288 +- doc/source/conf.py | 21 +- doc/source/contributing.rst | 28 +- doc/source/cookbook.rst | 12 + doc/source/dsintro.rst | 171 +- doc/source/ecosystem.rst | 28 +- doc/source/enhancingperf.rst | 107 +- doc/source/faq.rst | 167 +- doc/source/gotchas.rst | 53 +- doc/source/groupby.rst | 153 +- doc/source/indexing.rst | 241 +- doc/source/install.rst | 15 +- doc/source/internals.rst | 19 +- doc/source/io.rst | 257 +- doc/source/missing_data.rst | 58 +- doc/source/options.rst | 31 +- doc/source/r_interface.rst | 10 +- doc/source/timedeltas.rst | 2 + doc/source/timeseries.rst | 123 +- doc/source/visualization.rst | 7 + doc/source/whatsnew/v0.11.0.txt | 3 +- doc/source/whatsnew/v0.17.0.txt | 646 +- ez_setup.py | 264 - fake_pyrex/Pyrex/Distutils/__init__.py | 1 - fake_pyrex/Pyrex/Distutils/build_ext.py | 1 - fake_pyrex/Pyrex/__init__.py | 1 - pandas/__init__.py | 6 +- pandas/_version.py | 460 + pandas/algos.pyx | 4 + pandas/compat/__init__.py | 3 +- pandas/computation/align.py | 17 +- pandas/computation/tests/test_eval.py | 78 +- pandas/core/algorithms.py | 22 +- pandas/core/base.py | 31 +- pandas/core/categorical.py | 222 +- pandas/core/common.py | 206 +- pandas/core/config_init.py | 2 +- pandas/core/format.py | 58 +- pandas/core/frame.py | 283 +- pandas/core/generic.py | 212 +- pandas/core/groupby.py | 137 +- pandas/core/index.py | 379 +- pandas/core/indexing.py | 40 +- pandas/core/internals.py | 176 +- pandas/core/ops.py | 192 +- pandas/core/panel4d.py | 4 +- pandas/core/reshape.py | 45 +- pandas/core/series.py | 60 +- pandas/core/strings.py | 6 +- pandas/hashtable.pyx | 758 +- pandas/index.pyx | 11 +- pandas/io/api.py | 1 + pandas/io/common.py | 31 +- pandas/io/data.py | 2 +- pandas/io/excel.py | 38 +- pandas/io/gbq.py | 2 +- pandas/io/json.py | 2 +- pandas/io/packers.py | 101 +- pandas/io/parsers.py | 80 +- pandas/io/pytables.py | 47 +- pandas/io/sas.py | 459 + pandas/io/sql.py | 139 +- pandas/io/stata.py | 549 +- pandas/io/tests/data/DEMO_G.XPT | Bin 0 -> 3753760 bytes pandas/io/tests/data/DEMO_G.csv | 9757 +++++++++++++++++ pandas/io/tests/data/DRXFCD_G.XPT | Bin 0 -> 2195200 bytes pandas/io/tests/data/DRXFCD_G.csv | 7619 +++++++++++++ pandas/io/tests/data/SSHSV1_A.XPT | Bin 0 -> 23920 bytes pandas/io/tests/data/SSHSV1_A.csv | 1427 +++ pandas/io/tests/data/blank.xls | Bin 0 -> 23040 bytes pandas/io/tests/data/blank.xlsx | Bin 0 -> 8379 bytes pandas/io/tests/data/blank_with_header.xls | Bin 0 -> 23040 bytes pandas/io/tests/data/blank_with_header.xlsx | Bin 0 -> 8773 bytes .../0.16.2_AMD64_windows_2.7.10.msgpack | Bin 0 -> 4684 bytes .../0.16.2/0.16.2_AMD64_windows_3.4.3.msgpack | Bin 0 -> 4684 bytes .../0.16.2_x86_64_darwin_2.7.10.msgpack | Bin 0 -> 4684 bytes .../0.16.2/0.16.2_x86_64_linux_2.7.10.msgpack | Bin 0 -> 4684 bytes .../0.16.2/0.16.2_x86_64_linux_3.4.3.msgpack | Bin 0 -> 4684 bytes .../0.16.2/0.16.2_AMD64_windows_2.7.10.pickle | Bin 0 -> 15064 bytes .../0.16.2/0.16.2_AMD64_windows_3.4.3.pickle | Bin 0 -> 13744 bytes .../0.16.2/0.16.2_x86_64_darwin_2.7.10.pickle | Bin 0 -> 14893 bytes .../0.16.2/0.16.2_x86_64_linux_2.7.10.pickle | Bin 0 -> 14893 bytes .../0.16.2/0.16.2_x86_64_linux_3.4.3.pickle | Bin 0 -> 14116 bytes pandas/io/tests/data/salary.table.gz | Bin 0 -> 302 bytes pandas/io/tests/data/stata14_118.dta | Bin 0 -> 5556 bytes pandas/io/tests/generate_legacy_pickles.py | 169 - .../io/tests/generate_legacy_storage_files.py | 206 + pandas/io/tests/test_common.py | 4 +- pandas/io/tests/test_cparser.py | 39 + pandas/io/tests/test_data.py | 22 +- pandas/io/tests/test_excel.py | 84 +- pandas/io/tests/test_html.py | 48 +- pandas/io/tests/test_json/test_pandas.py | 28 +- pandas/io/tests/test_json/test_ujson.py | 110 +- pandas/io/tests/test_packers.py | 132 +- pandas/io/tests/test_parsers.py | 327 +- pandas/io/tests/test_pickle.py | 8 +- pandas/io/tests/test_pytables.py | 206 +- pandas/io/tests/test_sas.py | 112 + pandas/io/tests/test_sql.py | 508 +- pandas/io/tests/test_stata.py | 134 +- pandas/io/wb.py | 2 +- pandas/lib.pyx | 132 +- pandas/msgpack.pyx | 669 -- pandas/msgpack/__init__.py | 49 + pandas/msgpack/_packer.pyx | 294 + pandas/msgpack/_unpacker.pyx | 466 + pandas/msgpack/_version.py | 1 + pandas/msgpack/exceptions.py | 29 + pandas/parser.pyx | 3 +- pandas/sparse/tests/test_array.py | 8 +- pandas/sparse/tests/test_libsparse.py | 6 +- pandas/sparse/tests/test_sparse.py | 70 +- pandas/src/datetime/np_datetime_strings.c | 4 +- pandas/src/generate_code.py | 1353 +-- pandas/src/generated.pyx | 3446 +++--- pandas/src/headers/math.h | 2 +- pandas/src/headers/stdint.h | 2 +- pandas/src/khash.pxd | 81 +- pandas/src/msgpack/pack.h | 17 +- pandas/src/msgpack/pack_template.h | 870 +- pandas/src/msgpack/sysdep.h | 1 - pandas/src/msgpack/unpack.h | 153 +- pandas/src/msgpack/unpack_define.h | 90 +- pandas/src/msgpack/unpack_template.h | 729 +- pandas/src/parse_helper.h | 2 +- pandas/src/parser/tokenizer.c | 58 +- pandas/src/parser/tokenizer.h | 6 +- pandas/src/period.pyx | 8 + pandas/src/period_helper.h | 2 +- pandas/src/reduce.pyx | 54 +- pandas/src/testing.pyx | 83 +- pandas/stats/moments.py | 2 +- pandas/stats/ols.py | 5 +- pandas/stats/tests/test_moments.py | 26 +- pandas/stats/tests/test_ols.py | 6 +- pandas/tests/test_algos.py | 270 +- pandas/tests/test_base.py | 233 +- pandas/tests/test_categorical.py | 729 +- pandas/tests/test_common.py | 21 +- pandas/tests/test_compat.py | 2 +- pandas/tests/test_expressions.py | 17 +- pandas/tests/test_format.py | 213 +- pandas/tests/test_frame.py | 831 +- pandas/tests/test_generic.py | 62 +- pandas/tests/test_graphics.py | 1053 +- pandas/tests/test_graphics_others.py | 913 ++ pandas/tests/test_groupby.py | 186 +- pandas/tests/test_index.py | 740 +- pandas/tests/test_indexing.py | 141 +- pandas/tests/test_internals.py | 45 +- pandas/tests/test_lib.py | 237 +- pandas/tests/test_msgpack/test_buffer.py | 10 +- pandas/tests/test_msgpack/test_case.py | 1 + pandas/tests/test_msgpack/test_extension.py | 57 + pandas/tests/test_msgpack/test_format.py | 2 +- pandas/tests/test_msgpack/test_limits.py | 94 + pandas/tests/test_msgpack/test_newspec.py | 88 + pandas/tests/test_msgpack/test_obj.py | 4 +- pandas/tests/test_msgpack/test_read_size.py | 1 + pandas/tests/test_msgpack/test_seq.py | 17 +- pandas/tests/test_msgpack/test_sequnpack.py | 12 + pandas/tests/test_msgpack/test_unpack.py | 65 + pandas/tests/test_msgpack/test_unpack_raw.py | 13 +- pandas/tests/test_multilevel.py | 81 +- pandas/tests/test_panel.py | 4 +- pandas/tests/test_panel4d.py | 2 +- pandas/tests/test_reshape.py | 31 +- pandas/tests/test_rplot.py | 4 +- pandas/tests/test_series.py | 484 +- pandas/tests/test_strings.py | 142 +- pandas/tests/test_testing.py | 413 +- pandas/tests/test_tseries.py | 50 +- pandas/tests/test_util.py | 27 - pandas/tools/merge.py | 39 +- pandas/tools/plotting.py | 605 +- pandas/tools/rplot.py | 2 +- pandas/tools/tests/test_merge.py | 124 +- pandas/tools/tests/test_pivot.py | 2 +- pandas/tools/tests/test_tile.py | 36 +- pandas/tools/tests/test_util.py | 3 +- pandas/tools/tile.py | 4 +- pandas/tseries/base.py | 55 +- pandas/tseries/common.py | 5 +- pandas/tseries/frequencies.py | 156 +- pandas/tseries/holiday.py | 6 +- pandas/tseries/index.py | 106 +- pandas/tseries/offsets.py | 185 +- pandas/tseries/period.py | 76 +- pandas/tseries/plotting.py | 151 +- pandas/tseries/resample.py | 4 + pandas/tseries/tdi.py | 19 +- pandas/tseries/tests/test_base.py | 453 +- pandas/tseries/tests/test_daterange.py | 70 +- pandas/tseries/tests/test_frequencies.py | 112 +- pandas/tseries/tests/test_offsets.py | 33 +- pandas/tseries/tests/test_period.py | 44 +- pandas/tseries/tests/test_plotting.py | 64 +- pandas/tseries/tests/test_resample.py | 71 +- pandas/tseries/tests/test_timedeltas.py | 52 +- pandas/tseries/tests/test_timeseries.py | 313 +- .../tseries/tests/test_timeseries_legacy.py | 20 +- pandas/tseries/tests/test_timezones.py | 12 +- pandas/tseries/tests/test_tslib.py | 195 +- pandas/tseries/timedeltas.py | 183 +- pandas/tseries/tools.py | 307 +- pandas/tslib.pyx | 861 +- pandas/util/decorators.py | 4 +- pandas/util/testing.py | 570 +- scripts/api_rst_coverage.py | 43 + setup.cfg | 12 + setup.py | 126 +- vb_suite/binary_ops.py | 6 +- vb_suite/categoricals.py | 16 + vb_suite/frame_ctor.py | 33 +- vb_suite/frame_methods.py | 8 +- vb_suite/gil.py | 98 + vb_suite/groupby.py | 21 +- vb_suite/indexing.py | 43 + vb_suite/io_bench.py | 1 + vb_suite/join_merge.py | 32 +- vb_suite/packers.py | 46 +- vb_suite/pandas_vb_common.py | 2 + vb_suite/reindex.py | 28 +- vb_suite/series_methods.py | 10 + vb_suite/sparse.py | 4 +- vb_suite/suite.py | 1 + vb_suite/test_perf.py | 2 +- vb_suite/timeseries.py | 99 +- versioneer.py | 1699 +++ 281 files changed, 52524 insertions(+), 10227 deletions(-) create mode 100644 asv_bench/asv.conf.json create mode 100644 asv_bench/benchmarks/__init__.py create mode 100644 asv_bench/benchmarks/attrs_caching.py create mode 100644 asv_bench/benchmarks/binary_ops.py create mode 100644 asv_bench/benchmarks/categoricals.py create mode 100644 asv_bench/benchmarks/ctors.py create mode 100644 asv_bench/benchmarks/eval.py create mode 100644 asv_bench/benchmarks/frame_ctor.py create mode 100644 asv_bench/benchmarks/frame_methods.py create mode 100644 asv_bench/benchmarks/gil.py create mode 100644 asv_bench/benchmarks/groupby.py create mode 100644 asv_bench/benchmarks/hdfstore_bench.py create mode 100644 asv_bench/benchmarks/index_object.py create mode 100644 asv_bench/benchmarks/indexing.py create mode 100644 asv_bench/benchmarks/inference.py create mode 100644 asv_bench/benchmarks/io_bench.py create mode 100644 asv_bench/benchmarks/io_sql.py create mode 100644 asv_bench/benchmarks/join_merge.py create mode 100644 asv_bench/benchmarks/miscellaneous.py create mode 100644 asv_bench/benchmarks/packers.py create mode 120000 asv_bench/benchmarks/pandas_vb_common.py create mode 100644 asv_bench/benchmarks/panel_ctor.py create mode 100644 asv_bench/benchmarks/panel_methods.py create mode 100644 asv_bench/benchmarks/parser_vb.py create mode 100644 asv_bench/benchmarks/plotting.py create mode 100644 asv_bench/benchmarks/reindex.py create mode 100644 asv_bench/benchmarks/replace.py create mode 100644 asv_bench/benchmarks/reshape.py create mode 100644 asv_bench/benchmarks/series_methods.py create mode 100644 asv_bench/benchmarks/sparse.py create mode 100644 asv_bench/benchmarks/stat_ops.py create mode 100644 asv_bench/benchmarks/strings.py create mode 100644 asv_bench/benchmarks/timedelta.py create mode 100644 asv_bench/benchmarks/timeseries.py create mode 100644 asv_bench/vbench_to_asv.py delete mode 100644 ci/requirements-3.2.txt delete mode 100644 ez_setup.py delete mode 100644 fake_pyrex/Pyrex/Distutils/__init__.py delete mode 100644 fake_pyrex/Pyrex/Distutils/build_ext.py delete mode 100644 fake_pyrex/Pyrex/__init__.py create mode 100644 pandas/_version.py create mode 100644 pandas/io/sas.py create mode 100644 pandas/io/tests/data/DEMO_G.XPT create mode 100644 pandas/io/tests/data/DEMO_G.csv create mode 100644 pandas/io/tests/data/DRXFCD_G.XPT create mode 100644 pandas/io/tests/data/DRXFCD_G.csv create mode 100644 pandas/io/tests/data/SSHSV1_A.XPT create mode 100644 pandas/io/tests/data/SSHSV1_A.csv create mode 100755 pandas/io/tests/data/blank.xls create mode 100755 pandas/io/tests/data/blank.xlsx create mode 100755 pandas/io/tests/data/blank_with_header.xls create mode 100755 pandas/io/tests/data/blank_with_header.xlsx create mode 100644 pandas/io/tests/data/legacy_msgpack/0.16.2/0.16.2_AMD64_windows_2.7.10.msgpack create mode 100644 pandas/io/tests/data/legacy_msgpack/0.16.2/0.16.2_AMD64_windows_3.4.3.msgpack create mode 100644 pandas/io/tests/data/legacy_msgpack/0.16.2/0.16.2_x86_64_darwin_2.7.10.msgpack create mode 100644 pandas/io/tests/data/legacy_msgpack/0.16.2/0.16.2_x86_64_linux_2.7.10.msgpack create mode 100644 pandas/io/tests/data/legacy_msgpack/0.16.2/0.16.2_x86_64_linux_3.4.3.msgpack create mode 100644 pandas/io/tests/data/legacy_pickle/0.16.2/0.16.2_AMD64_windows_2.7.10.pickle create mode 100644 pandas/io/tests/data/legacy_pickle/0.16.2/0.16.2_AMD64_windows_3.4.3.pickle create mode 100644 pandas/io/tests/data/legacy_pickle/0.16.2/0.16.2_x86_64_darwin_2.7.10.pickle create mode 100644 pandas/io/tests/data/legacy_pickle/0.16.2/0.16.2_x86_64_linux_2.7.10.pickle create mode 100644 pandas/io/tests/data/legacy_pickle/0.16.2/0.16.2_x86_64_linux_3.4.3.pickle create mode 100644 pandas/io/tests/data/salary.table.gz create mode 100644 pandas/io/tests/data/stata14_118.dta delete mode 100644 pandas/io/tests/generate_legacy_pickles.py create mode 100644 pandas/io/tests/generate_legacy_storage_files.py create mode 100644 pandas/io/tests/test_sas.py delete mode 100644 pandas/msgpack.pyx create mode 100644 pandas/msgpack/__init__.py create mode 100644 pandas/msgpack/_packer.pyx create mode 100644 pandas/msgpack/_unpacker.pyx create mode 100644 pandas/msgpack/_version.py create mode 100644 pandas/msgpack/exceptions.py create mode 100644 pandas/tests/test_graphics_others.py create mode 100644 pandas/tests/test_msgpack/test_extension.py create mode 100644 pandas/tests/test_msgpack/test_limits.py create mode 100644 pandas/tests/test_msgpack/test_newspec.py create mode 100644 pandas/tests/test_msgpack/test_unpack.py create mode 100644 scripts/api_rst_coverage.py create mode 100644 setup.cfg create mode 100644 vb_suite/categoricals.py create mode 100644 vb_suite/gil.py create mode 100644 versioneer.py diff --git a/.binstar.yml b/.binstar.yml index 6f7c2c5ba4c7a..c70add11c55b0 100644 --- a/.binstar.yml +++ b/.binstar.yml @@ -1,22 +1,21 @@ package: pandas user: jreback -platform: - #- osx-64 - #- linux-32 - - linux-64 - - win-64 - #- win-32 - -engine: - #- python=2.6 - - python=2.7 - #- python=3.3 - #- python=3.4 +install: + - conda config --add channels pandas before_script: - python -V +platform: + - linux-64 + #- linux-32 + - osx-64 + #- win-32 + - win-64 +engine: + - python=2.7 + #- python=3.4 script: - conda build conda.recipe --quiet @@ -27,12 +26,3 @@ build_targets: conda notifications: email: recipients: ['jeff@reback.net'] - ---- -platform: win-32 -engine: python=2.6 -exclude: true ---- -platform: win-64 -engine: python=2.6 -exclude: true diff --git a/.gitattributes b/.gitattributes index 0ef16e42a0660..736fa09d070fe 100644 --- a/.gitattributes +++ b/.gitattributes @@ -13,3 +13,4 @@ *.dta binary *.xls binary *.xlsx binary +pandas/_version.py export-subst diff --git a/.gitignore b/.gitignore index e8b557d68ac39..d33df2df6e548 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ .idea .vagrant .noseids +.ipynb_checkpoints # Compiled source # ################### @@ -41,6 +42,8 @@ doc/_build dist # Egg metadata *.egg-info +.eggs + # tox testing tool .tox # rope @@ -76,9 +79,9 @@ scikits *.c *.cpp -# Things specific to this project # -################################### -pandas/version.py +# Performance Testing # +####################### +asv_bench/ # Documentation generated files # ################################# diff --git a/.travis.yml b/.travis.yml index 246154310a50f..b867601ba0b96 100644 --- a/.travis.yml +++ b/.travis.yml @@ -86,13 +86,6 @@ matrix: - CLIPBOARD=xsel - BUILD_TYPE=conda - JOB_NAME: "34_slow" - - python: 3.2 - env: - - NOSE_ARGS="not slow and not network and not disabled" - - FULL_DEPS=true - - CLIPBOARD_GUI=qt4 - - BUILD_TYPE=pydata - - JOB_NAME: "32_nslow" - python: 2.7 env: - EXPERIMENTAL=true @@ -103,13 +96,6 @@ matrix: - BUILD_TYPE=pydata - PANDAS_TESTING_MODE="deprecate" allow_failures: - - python: 3.2 - env: - - NOSE_ARGS="not slow and not network and not disabled" - - FULL_DEPS=true - - CLIPBOARD_GUI=qt4 - - BUILD_TYPE=pydata - - JOB_NAME: "32_nslow" - python: 2.7 env: - NOSE_ARGS="slow and not network and not disabled" diff --git a/MANIFEST.in b/MANIFEST.in index 69174f7f05b98..2d26fbfd6adaf 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -24,3 +24,5 @@ global-exclude *.png # recursive-include doc/source * # recursive-include doc/sphinxext * # recursive-include LICENSES * +include versioneer.py +include pandas/_version.py diff --git a/README.md b/README.md index bba31fef7a939..947dfc5928249 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,45 @@ # pandas: powerful Python data analysis toolkit -[![Build Status](https://travis-ci.org/pydata/pandas.svg?branch=master)](https://travis-ci.org/pydata/pandas) -[![Join the chat at -https://gitter.im/pydata/pandas](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/pydata/pandas?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + + + + + + + + + + + + + + + + + + + + + + + + + +
Latest Releaselatest release
Package Statusstatus
Licenselicense
Build Status + + build status + +
Conda + + conda downloads + +
PyPI + + pypi downloads + +
+ +[![https://gitter.im/pydata/pandas](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/pydata/pandas?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) ## What is it diff --git a/asv_bench/asv.conf.json b/asv_bench/asv.conf.json new file mode 100644 index 0000000000000..760db2086b125 --- /dev/null +++ b/asv_bench/asv.conf.json @@ -0,0 +1,66 @@ +{ + // The version of the config file format. Do not change, unless + // you know what you are doing. + "version": 1, + + // The name of the project being benchmarked + "project": "pandas", + + // The project's homepage + "project_url": "http://pandas.pydata.org/", + + // The URL of the source code repository for the project being + // benchmarked + "repo": "..", + + // The tool to use to create environments. May be "conda", + // "virtualenv" or other value depending on the plugins in use. + // If missing or the empty string, the tool will be automatically + // determined by looking for tools on the PATH environment + // variable. + "environment_type": "conda", + + // the base URL to show a commit for the project. + "show_commit_url": "https://github.com/pydata/pandas/commit/", + + // The Pythons you'd like to test against. If not provided, defaults + // to the current version of Python used to run `asv`. + // "pythons": ["2.7", "3.4"], + "pythons": ["2.7"], + + // The matrix of dependencies to test. Each key is the name of a + // package (in PyPI) and the values are version numbers. An empty + // list indicates to just test against the default (latest) + // version. + "matrix": { + // To run against multiple versions, replace with + // "numpy": ["1.7", "1.9"], + "numpy": [], + "Cython": [], + "matplotlib": [], + "sqlalchemy": [], + "scipy": [], + "numexpr": [], + "pytables": [], + }, + + // The directory (relative to the current directory) that benchmarks are + // stored in. If not provided, defaults to "benchmarks" + // "benchmark_dir": "benchmarks", + + // The directory (relative to the current directory) to cache the Python + // environments in. If not provided, defaults to "env" + // "env_dir": "env", + + + // The directory (relative to the current directory) that raw benchmark + // results are stored in. If not provided, defaults to "results". + // "results_dir": "results", + + // The directory (relative to the current directory) that the html tree + // should be written to. If not provided, defaults to "html". + // "html_dir": "html", + + // The number of characters to retain in the commit hashes. + // "hash_length": 8 +} diff --git a/asv_bench/benchmarks/__init__.py b/asv_bench/benchmarks/__init__.py new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/asv_bench/benchmarks/attrs_caching.py b/asv_bench/benchmarks/attrs_caching.py new file mode 100644 index 0000000000000..ecb91923dc663 --- /dev/null +++ b/asv_bench/benchmarks/attrs_caching.py @@ -0,0 +1,23 @@ +from pandas_vb_common import * + + +class getattr_dataframe_index(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(10, 6)) + self.cur_index = self.df.index + + def time_getattr_dataframe_index(self): + self.foo = self.df.index + + +class setattr_dataframe_index(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(10, 6)) + self.cur_index = self.df.index + + def time_setattr_dataframe_index(self): + self.df.index = self.cur_index \ No newline at end of file diff --git a/asv_bench/benchmarks/binary_ops.py b/asv_bench/benchmarks/binary_ops.py new file mode 100644 index 0000000000000..13976014ec6f1 --- /dev/null +++ b/asv_bench/benchmarks/binary_ops.py @@ -0,0 +1,236 @@ +from pandas_vb_common import * +import pandas.computation.expressions as expr + + +class frame_add(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(20000, 100)) + self.df2 = DataFrame(np.random.randn(20000, 100)) + + def time_frame_add(self): + (self.df + self.df2) + + +class frame_add_no_ne(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(20000, 100)) + self.df2 = DataFrame(np.random.randn(20000, 100)) + expr.set_use_numexpr(False) + + def time_frame_add_no_ne(self): + (self.df + self.df2) + + def teardown(self): + expr.set_use_numexpr(True) + + +class frame_add_st(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(20000, 100)) + self.df2 = DataFrame(np.random.randn(20000, 100)) + expr.set_numexpr_threads(1) + + def time_frame_add_st(self): + (self.df + self.df2) + + def teardown(self): + expr.set_numexpr_threads() + + +class frame_float_div(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(1000, 1000)) + self.df2 = DataFrame(np.random.randn(1000, 1000)) + + def time_frame_float_div(self): + (self.df // self.df2) + + +class frame_float_div_by_zero(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(1000, 1000)) + + def time_frame_float_div_by_zero(self): + (self.df / 0) + + +class frame_float_floor_by_zero(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(1000, 1000)) + + def time_frame_float_floor_by_zero(self): + (self.df // 0) + + +class frame_float_mod(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(1000, 1000)) + self.df2 = DataFrame(np.random.randn(1000, 1000)) + + def time_frame_float_mod(self): + (self.df / self.df2) + + +class frame_int_div_by_zero(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.random_integers(np.iinfo(np.int16).min, np.iinfo(np.int16).max, size=(1000, 1000))) + + def time_frame_int_div_by_zero(self): + (self.df / 0) + + +class frame_int_mod(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.random_integers(np.iinfo(np.int16).min, np.iinfo(np.int16).max, size=(1000, 1000))) + self.df2 = DataFrame(np.random.random_integers(np.iinfo(np.int16).min, np.iinfo(np.int16).max, size=(1000, 1000))) + + def time_frame_int_mod(self): + (self.df / self.df2) + + +class frame_mult(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(20000, 100)) + self.df2 = DataFrame(np.random.randn(20000, 100)) + + def time_frame_mult(self): + (self.df * self.df2) + + +class frame_mult_no_ne(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(20000, 100)) + self.df2 = DataFrame(np.random.randn(20000, 100)) + expr.set_use_numexpr(False) + + def time_frame_mult_no_ne(self): + (self.df * self.df2) + + def teardown(self): + expr.set_use_numexpr(True) + + +class frame_mult_st(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(20000, 100)) + self.df2 = DataFrame(np.random.randn(20000, 100)) + expr.set_numexpr_threads(1) + + def time_frame_mult_st(self): + (self.df * self.df2) + + def teardown(self): + expr.set_numexpr_threads() + + +class frame_multi_and(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(20000, 100)) + self.df2 = DataFrame(np.random.randn(20000, 100)) + + def time_frame_multi_and(self): + self.df[((self.df > 0) & (self.df2 > 0))] + + +class frame_multi_and_no_ne(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(20000, 100)) + self.df2 = DataFrame(np.random.randn(20000, 100)) + expr.set_use_numexpr(False) + + def time_frame_multi_and_no_ne(self): + self.df[((self.df > 0) & (self.df2 > 0))] + + def teardown(self): + expr.set_use_numexpr(True) + + +class frame_multi_and_st(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(20000, 100)) + self.df2 = DataFrame(np.random.randn(20000, 100)) + expr.set_numexpr_threads(1) + + def time_frame_multi_and_st(self): + self.df[((self.df > 0) & (self.df2 > 0))] + + def teardown(self): + expr.set_numexpr_threads() + + +class series_timestamp_compare(object): + goal_time = 0.2 + + def setup(self): + self.N = 1000000 + self.halfway = ((self.N // 2) - 1) + self.s = Series(date_range('20010101', periods=self.N, freq='T')) + self.ts = self.s[self.halfway] + + def time_series_timestamp_compare(self): + (self.s <= self.ts) + + +class timestamp_ops_diff1(object): + goal_time = 0.2 + + def setup(self): + self.N = 1000000 + self.s = Series(date_range('20010101', periods=self.N, freq='s')) + + def time_timestamp_ops_diff1(self): + self.s.diff() + + +class timestamp_ops_diff2(object): + goal_time = 0.2 + + def setup(self): + self.N = 1000000 + self.s = Series(date_range('20010101', periods=self.N, freq='s')) + + def time_timestamp_ops_diff2(self): + (self.s - self.s.shift()) + + +class timestamp_series_compare(object): + goal_time = 0.2 + + def setup(self): + self.N = 1000000 + self.halfway = ((self.N // 2) - 1) + self.s = Series(date_range('20010101', periods=self.N, freq='T')) + self.ts = self.s[self.halfway] + + def time_timestamp_series_compare(self): + (self.ts >= self.s) \ No newline at end of file diff --git a/asv_bench/benchmarks/categoricals.py b/asv_bench/benchmarks/categoricals.py new file mode 100644 index 0000000000000..34caef221a340 --- /dev/null +++ b/asv_bench/benchmarks/categoricals.py @@ -0,0 +1,11 @@ +from pandas_vb_common import * + + +class concat_categorical(object): + goal_time = 0.2 + + def setup(self): + self.s = pd.Series((list('aabbcd') * 1000000)).astype('category') + + def time_concat_categorical(self): + concat([self.s, self.s]) \ No newline at end of file diff --git a/asv_bench/benchmarks/ctors.py b/asv_bench/benchmarks/ctors.py new file mode 100644 index 0000000000000..b48211b3db83e --- /dev/null +++ b/asv_bench/benchmarks/ctors.py @@ -0,0 +1,52 @@ +from pandas_vb_common import * + + +class frame_constructor_ndarray(object): + goal_time = 0.2 + + def setup(self): + self.arr = np.random.randn(100, 100) + + def time_frame_constructor_ndarray(self): + DataFrame(self.arr) + + +class ctor_index_array_string(object): + goal_time = 0.2 + + def setup(self): + self.data = np.array(['foo', 'bar', 'baz'], dtype=object) + + def time_ctor_index_array_string(self): + Index(self.data) + + +class series_constructor_ndarray(object): + goal_time = 0.2 + + def setup(self): + self.data = np.random.randn(100) + self.index = Index(np.arange(100)) + + def time_series_constructor_ndarray(self): + Series(self.data, index=self.index) + + +class dtindex_from_series_ctor(object): + goal_time = 0.2 + + def setup(self): + self.s = Series(([Timestamp('20110101'), Timestamp('20120101'), Timestamp('20130101')] * 1000)) + + def time_dtindex_from_series_ctor(self): + DatetimeIndex(self.s) + + +class index_from_series_ctor(object): + goal_time = 0.2 + + def setup(self): + self.s = Series(([Timestamp('20110101'), Timestamp('20120101'), Timestamp('20130101')] * 1000)) + + def time_index_from_series_ctor(self): + Index(self.s) \ No newline at end of file diff --git a/asv_bench/benchmarks/eval.py b/asv_bench/benchmarks/eval.py new file mode 100644 index 0000000000000..397312355aa47 --- /dev/null +++ b/asv_bench/benchmarks/eval.py @@ -0,0 +1,239 @@ +from pandas_vb_common import * +import pandas.computation.expressions as expr +import pandas as pd + + +class eval_frame_add_all_threads(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(20000, 100)) + self.df2 = DataFrame(np.random.randn(20000, 100)) + self.df3 = DataFrame(np.random.randn(20000, 100)) + self.df4 = DataFrame(np.random.randn(20000, 100)) + + def time_eval_frame_add_all_threads(self): + pd.eval('df + df2 + df3 + df4') + + +class eval_frame_add_one_thread(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(20000, 100)) + self.df2 = DataFrame(np.random.randn(20000, 100)) + self.df3 = DataFrame(np.random.randn(20000, 100)) + self.df4 = DataFrame(np.random.randn(20000, 100)) + expr.set_numexpr_threads(1) + + def time_eval_frame_add_one_thread(self): + pd.eval('df + df2 + df3 + df4') + + +class eval_frame_add_python(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(20000, 100)) + self.df2 = DataFrame(np.random.randn(20000, 100)) + self.df3 = DataFrame(np.random.randn(20000, 100)) + self.df4 = DataFrame(np.random.randn(20000, 100)) + + def time_eval_frame_add_python(self): + pd.eval('df + df2 + df3 + df4', engine='python') + + +class eval_frame_add_python_one_thread(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(20000, 100)) + self.df2 = DataFrame(np.random.randn(20000, 100)) + self.df3 = DataFrame(np.random.randn(20000, 100)) + self.df4 = DataFrame(np.random.randn(20000, 100)) + expr.set_numexpr_threads(1) + + def time_eval_frame_add_python_one_thread(self): + pd.eval('df + df2 + df3 + df4', engine='python') + + +class eval_frame_and_all_threads(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(20000, 100)) + self.df2 = DataFrame(np.random.randn(20000, 100)) + self.df3 = DataFrame(np.random.randn(20000, 100)) + self.df4 = DataFrame(np.random.randn(20000, 100)) + + def time_eval_frame_and_all_threads(self): + pd.eval('(df > 0) & (df2 > 0) & (df3 > 0) & (df4 > 0)') + + +class eval_frame_and_python_one_thread(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(20000, 100)) + self.df2 = DataFrame(np.random.randn(20000, 100)) + self.df3 = DataFrame(np.random.randn(20000, 100)) + self.df4 = DataFrame(np.random.randn(20000, 100)) + expr.set_numexpr_threads(1) + + def time_eval_frame_and_python_one_thread(self): + pd.eval('(df > 0) & (df2 > 0) & (df3 > 0) & (df4 > 0)', engine='python') + + +class eval_frame_and_python(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(20000, 100)) + self.df2 = DataFrame(np.random.randn(20000, 100)) + self.df3 = DataFrame(np.random.randn(20000, 100)) + self.df4 = DataFrame(np.random.randn(20000, 100)) + + def time_eval_frame_and_python(self): + pd.eval('(df > 0) & (df2 > 0) & (df3 > 0) & (df4 > 0)', engine='python') + + +class eval_frame_chained_cmp_all_threads(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(20000, 100)) + self.df2 = DataFrame(np.random.randn(20000, 100)) + self.df3 = DataFrame(np.random.randn(20000, 100)) + self.df4 = DataFrame(np.random.randn(20000, 100)) + + def time_eval_frame_chained_cmp_all_threads(self): + pd.eval('df < df2 < df3 < df4') + + +class eval_frame_chained_cmp_python_one_thread(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(20000, 100)) + self.df2 = DataFrame(np.random.randn(20000, 100)) + self.df3 = DataFrame(np.random.randn(20000, 100)) + self.df4 = DataFrame(np.random.randn(20000, 100)) + expr.set_numexpr_threads(1) + + def time_eval_frame_chained_cmp_python_one_thread(self): + pd.eval('df < df2 < df3 < df4', engine='python') + + +class eval_frame_chained_cmp_python(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(20000, 100)) + self.df2 = DataFrame(np.random.randn(20000, 100)) + self.df3 = DataFrame(np.random.randn(20000, 100)) + self.df4 = DataFrame(np.random.randn(20000, 100)) + + def time_eval_frame_chained_cmp_python(self): + pd.eval('df < df2 < df3 < df4', engine='python') + + +class eval_frame_mult_all_threads(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(20000, 100)) + self.df2 = DataFrame(np.random.randn(20000, 100)) + self.df3 = DataFrame(np.random.randn(20000, 100)) + self.df4 = DataFrame(np.random.randn(20000, 100)) + + def time_eval_frame_mult_all_threads(self): + pd.eval('df * df2 * df3 * df4') + + +class eval_frame_mult_one_thread(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(20000, 100)) + self.df2 = DataFrame(np.random.randn(20000, 100)) + self.df3 = DataFrame(np.random.randn(20000, 100)) + self.df4 = DataFrame(np.random.randn(20000, 100)) + expr.set_numexpr_threads(1) + + def time_eval_frame_mult_one_thread(self): + pd.eval('df * df2 * df3 * df4') + + +class eval_frame_mult_python(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(20000, 100)) + self.df2 = DataFrame(np.random.randn(20000, 100)) + self.df3 = DataFrame(np.random.randn(20000, 100)) + self.df4 = DataFrame(np.random.randn(20000, 100)) + + def time_eval_frame_mult_python(self): + pd.eval('df * df2 * df3 * df4', engine='python') + + +class eval_frame_mult_python_one_thread(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(20000, 100)) + self.df2 = DataFrame(np.random.randn(20000, 100)) + self.df3 = DataFrame(np.random.randn(20000, 100)) + self.df4 = DataFrame(np.random.randn(20000, 100)) + expr.set_numexpr_threads(1) + + def time_eval_frame_mult_python_one_thread(self): + pd.eval('df * df2 * df3 * df4', engine='python') + + +class query_datetime_index(object): + goal_time = 0.2 + + def setup(self): + self.N = 1000000 + self.halfway = ((self.N // 2) - 1) + self.index = date_range('20010101', periods=self.N, freq='T') + self.s = Series(self.index) + self.ts = self.s.iloc[self.halfway] + self.df = DataFrame({'a': np.random.randn(self.N), }, index=self.index) + + def time_query_datetime_index(self): + self.df.query('index < @ts') + + +class query_datetime_series(object): + goal_time = 0.2 + + def setup(self): + self.N = 1000000 + self.halfway = ((self.N // 2) - 1) + self.index = date_range('20010101', periods=self.N, freq='T') + self.s = Series(self.index) + self.ts = self.s.iloc[self.halfway] + self.df = DataFrame({'dates': self.s.values, }) + + def time_query_datetime_series(self): + self.df.query('dates < @ts') + + +class query_with_boolean_selection(object): + goal_time = 0.2 + + def setup(self): + self.N = 1000000 + self.halfway = ((self.N // 2) - 1) + self.index = date_range('20010101', periods=self.N, freq='T') + self.s = Series(self.index) + self.ts = self.s.iloc[self.halfway] + self.N = 1000000 + self.df = DataFrame({'a': np.random.randn(self.N), }) + self.min_val = self.df['a'].min() + self.max_val = self.df['a'].max() + + def time_query_with_boolean_selection(self): + self.df.query('(a >= @min_val) & (a <= @max_val)') \ No newline at end of file diff --git a/asv_bench/benchmarks/frame_ctor.py b/asv_bench/benchmarks/frame_ctor.py new file mode 100644 index 0000000000000..2cb337e0e6b9d --- /dev/null +++ b/asv_bench/benchmarks/frame_ctor.py @@ -0,0 +1,1706 @@ +from pandas_vb_common import * +try: + from pandas.tseries.offsets import * +except: + from pandas.core.datetools import * + + +class frame_ctor_dtindex_BDayx1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(BDay(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_BDayx1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_BDayx2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(BDay(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_BDayx2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_BMonthBeginx1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(BMonthBegin(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_BMonthBeginx1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_BMonthBeginx2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(BMonthBegin(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_BMonthBeginx2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_BMonthEndx1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(BMonthEnd(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_BMonthEndx1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_BMonthEndx2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(BMonthEnd(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_BMonthEndx2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_BQuarterBeginx1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(BQuarterBegin(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_BQuarterBeginx1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_BQuarterBeginx2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(BQuarterBegin(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_BQuarterBeginx2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_BQuarterEndx1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(BQuarterEnd(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_BQuarterEndx1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_BQuarterEndx2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(BQuarterEnd(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_BQuarterEndx2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_BYearBeginx1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(BYearBegin(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_BYearBeginx1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_BYearBeginx2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(BYearBegin(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_BYearBeginx2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_BYearEndx1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(BYearEnd(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_BYearEndx1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_BYearEndx2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(BYearEnd(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_BYearEndx2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_BusinessDayx1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(BusinessDay(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_BusinessDayx1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_BusinessDayx2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(BusinessDay(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_BusinessDayx2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_BusinessHourx1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(BusinessHour(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_BusinessHourx1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_BusinessHourx2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(BusinessHour(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_BusinessHourx2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_CBMonthBeginx1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(CBMonthBegin(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_CBMonthBeginx1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_CBMonthBeginx2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(CBMonthBegin(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_CBMonthBeginx2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_CBMonthEndx1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(CBMonthEnd(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_CBMonthEndx1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_CBMonthEndx2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(CBMonthEnd(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_CBMonthEndx2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_CDayx1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(CDay(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_CDayx1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_CDayx2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(CDay(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_CDayx2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_CustomBusinessDayx1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(CustomBusinessDay(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_CustomBusinessDayx1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_CustomBusinessDayx2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(CustomBusinessDay(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_CustomBusinessDayx2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_DateOffsetx1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(DateOffset(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_DateOffsetx1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_DateOffsetx2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(DateOffset(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_DateOffsetx2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_Dayx1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(Day(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_Dayx1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_Dayx2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(Day(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_Dayx2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_Easterx1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(Easter(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_Easterx1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_Easterx2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(Easter(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_Easterx2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_FY5253Quarterx1__variation_last(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(FY5253Quarter(1, **{'startingMonth': 1, 'qtr_with_extra_week': 1, 'weekday': 1, 'variation': 'last', })) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_FY5253Quarterx1__variation_last(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_FY5253Quarterx1__variation_nearest(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(FY5253Quarter(1, **{'startingMonth': 1, 'qtr_with_extra_week': 1, 'weekday': 1, 'variation': 'nearest', })) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_FY5253Quarterx1__variation_nearest(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_FY5253Quarterx2__variation_last(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(FY5253Quarter(2, **{'startingMonth': 1, 'qtr_with_extra_week': 1, 'weekday': 1, 'variation': 'last', })) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_FY5253Quarterx2__variation_last(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_FY5253Quarterx2__variation_nearest(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(FY5253Quarter(2, **{'startingMonth': 1, 'qtr_with_extra_week': 1, 'weekday': 1, 'variation': 'nearest', })) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_FY5253Quarterx2__variation_nearest(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_FY5253x1__variation_last(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(FY5253(1, **{'startingMonth': 1, 'weekday': 1, 'variation': 'last', })) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_FY5253x1__variation_last(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_FY5253x1__variation_nearest(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(FY5253(1, **{'startingMonth': 1, 'weekday': 1, 'variation': 'nearest', })) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_FY5253x1__variation_nearest(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_FY5253x2__variation_last(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(FY5253(2, **{'startingMonth': 1, 'weekday': 1, 'variation': 'last', })) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_FY5253x2__variation_last(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_FY5253x2__variation_nearest(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(FY5253(2, **{'startingMonth': 1, 'weekday': 1, 'variation': 'nearest', })) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_FY5253x2__variation_nearest(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_Hourx1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(Hour(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_Hourx1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_Hourx2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(Hour(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_Hourx2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_LastWeekOfMonthx1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(LastWeekOfMonth(1, **{'week': 1, 'weekday': 1, })) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_LastWeekOfMonthx1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_LastWeekOfMonthx2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(LastWeekOfMonth(2, **{'week': 1, 'weekday': 1, })) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_LastWeekOfMonthx2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_Microx1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(Micro(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_Microx1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_Microx2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(Micro(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_Microx2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_Millix1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(Milli(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_Millix1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_Millix2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(Milli(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_Millix2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_Minutex1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(Minute(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_Minutex1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_Minutex2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(Minute(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_Minutex2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_MonthBeginx1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(MonthBegin(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_MonthBeginx1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_MonthBeginx2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(MonthBegin(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_MonthBeginx2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_MonthEndx1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(MonthEnd(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_MonthEndx1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_MonthEndx2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(MonthEnd(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_MonthEndx2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_Nanox1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(Nano(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_Nanox1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_Nanox2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(Nano(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_Nanox2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_QuarterBeginx1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(QuarterBegin(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_QuarterBeginx1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_QuarterBeginx2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(QuarterBegin(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_QuarterBeginx2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_QuarterEndx1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(QuarterEnd(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_QuarterEndx1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_QuarterEndx2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(QuarterEnd(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_QuarterEndx2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_Secondx1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(Second(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_Secondx1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_Secondx2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(Second(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_Secondx2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_WeekOfMonthx1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(WeekOfMonth(1, **{'week': 1, 'weekday': 1, })) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_WeekOfMonthx1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_WeekOfMonthx2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(WeekOfMonth(2, **{'week': 1, 'weekday': 1, })) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_WeekOfMonthx2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_Weekx1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(Week(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_Weekx1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_Weekx2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(Week(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_Weekx2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_YearBeginx1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(YearBegin(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_YearBeginx1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_YearBeginx2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(YearBegin(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_YearBeginx2(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_YearEndx1(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(YearEnd(1, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_YearEndx1(self): + DataFrame(self.d) + + +class frame_ctor_dtindex_YearEndx2(object): + goal_time = 0.2 + + def setup(self): + + def get_period_count(start_date, off): + self.ten_offsets_in_days = ((start_date + (off * 10)) - start_date).days + if (self.ten_offsets_in_days == 0): + return 1000 + else: + return min((9 * ((Timestamp.max - start_date).days // self.ten_offsets_in_days)), 1000) + + def get_index_for_offset(off): + self.start_date = Timestamp('1/1/1900') + return date_range(self.start_date, periods=min(1000, get_period_count(self.start_date, off)), freq=off) + self.idx = get_index_for_offset(YearEnd(2, **{})) + self.df = DataFrame(np.random.randn(len(self.idx), 10), index=self.idx) + self.d = dict([(col, self.df[col]) for col in self.df.columns]) + + def time_frame_ctor_dtindex_YearEndx2(self): + DataFrame(self.d) + + +class frame_ctor_list_of_dict(object): + goal_time = 0.2 + + def setup(self): + (N, K) = (5000, 50) + self.index = tm.makeStringIndex(N) + self.columns = tm.makeStringIndex(K) + self.frame = DataFrame(np.random.randn(N, K), index=self.index, columns=self.columns) + try: + self.data = self.frame.to_dict() + except: + self.data = self.frame.toDict() + self.some_dict = self.data.values()[0] + self.dict_list = [dict(zip(self.columns, row)) for row in self.frame.values] + + def time_frame_ctor_list_of_dict(self): + DataFrame(self.dict_list) + + +class frame_ctor_nested_dict(object): + goal_time = 0.2 + + def setup(self): + (N, K) = (5000, 50) + self.index = tm.makeStringIndex(N) + self.columns = tm.makeStringIndex(K) + self.frame = DataFrame(np.random.randn(N, K), index=self.index, columns=self.columns) + try: + self.data = self.frame.to_dict() + except: + self.data = self.frame.toDict() + self.some_dict = self.data.values()[0] + self.dict_list = [dict(zip(self.columns, row)) for row in self.frame.values] + + def time_frame_ctor_nested_dict(self): + DataFrame(self.data) + + +class frame_ctor_nested_dict_int64(object): + goal_time = 0.2 + + def setup(self): + self.data = dict(((i, dict(((j, float(j)) for j in xrange(100)))) for i in xrange(2000))) + + def time_frame_ctor_nested_dict_int64(self): + DataFrame(self.data) + + +class frame_from_series(object): + goal_time = 0.2 + + def setup(self): + self.mi = MultiIndex.from_tuples([(x, y) for x in range(100) for y in range(100)]) + self.s = Series(randn(10000), index=self.mi) + + def time_frame_from_series(self): + DataFrame(self.s) + + +class frame_get_numeric_data(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(randn(10000, 25)) + self.df['foo'] = 'bar' + self.df['bar'] = 'baz' + self.df = self.df.consolidate() + + def time_frame_get_numeric_data(self): + self.df._get_numeric_data() + + +class series_ctor_from_dict(object): + goal_time = 0.2 + + def setup(self): + (N, K) = (5000, 50) + self.index = tm.makeStringIndex(N) + self.columns = tm.makeStringIndex(K) + self.frame = DataFrame(np.random.randn(N, K), index=self.index, columns=self.columns) + try: + self.data = self.frame.to_dict() + except: + self.data = self.frame.toDict() + self.some_dict = self.data.values()[0] + self.dict_list = [dict(zip(self.columns, row)) for row in self.frame.values] + + def time_series_ctor_from_dict(self): + Series(self.some_dict) \ No newline at end of file diff --git a/asv_bench/benchmarks/frame_methods.py b/asv_bench/benchmarks/frame_methods.py new file mode 100644 index 0000000000000..2bd51201b45ca --- /dev/null +++ b/asv_bench/benchmarks/frame_methods.py @@ -0,0 +1,936 @@ +from pandas_vb_common import * + + +class frame_apply_axis_1(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(1000, 100)) + + def time_frame_apply_axis_1(self): + self.df.apply((lambda x: (x + 1)), axis=1) + + +class frame_apply_lambda_mean(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(1000, 100)) + + def time_frame_apply_lambda_mean(self): + self.df.apply((lambda x: x.sum())) + + +class frame_apply_np_mean(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(1000, 100)) + + def time_frame_apply_np_mean(self): + self.df.apply(np.mean) + + +class frame_apply_pass_thru(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(1000, 100)) + + def time_frame_apply_pass_thru(self): + self.df.apply((lambda x: x)) + + +class frame_apply_ref_by_name(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(1000, 3), columns=list('ABC')) + + def time_frame_apply_ref_by_name(self): + self.df.apply((lambda x: (x['A'] + x['B'])), axis=1) + + +class frame_apply_user_func(object): + goal_time = 0.2 + + def setup(self): + self.s = Series(np.arange(1028.0)) + self.df = DataFrame({i: self.s for i in range(1028)}) + + def time_frame_apply_user_func(self): + self.df.apply((lambda x: np.corrcoef(x, self.s)[(0, 1)])) + + +class frame_assign_timeseries_index(object): + goal_time = 0.2 + + def setup(self): + self.idx = date_range('1/1/2000', periods=100000, freq='D') + self.df = DataFrame(randn(100000, 1), columns=['A'], index=self.idx) + + def f(x): + self.x = self.x.copy() + self.x['date'] = self.x.index + + def time_frame_assign_timeseries_index(self): + f(self.df) + + +class frame_boolean_row_select(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(randn(10000, 100)) + self.bool_arr = np.zeros(10000, dtype=bool) + self.bool_arr[:1000] = True + + def time_frame_boolean_row_select(self): + self.df[self.bool_arr] + + +class frame_count_level_axis0_mixed_dtypes_multi(object): + goal_time = 0.2 + + def setup(self): + self.data = np.random.randn(10000, 1000) + self.df = DataFrame(self.data) + self.df.ix[50:1000, 20:50] = np.nan + self.df.ix[2000:3000] = np.nan + self.df.ix[:, 60:70] = np.nan + self.df['foo'] = 'bar' + self.df.index = MultiIndex.from_tuples(self.df.index.map((lambda x: (x, x)))) + self.df.columns = MultiIndex.from_tuples(self.df.columns.map((lambda x: (x, x)))) + + def time_frame_count_level_axis0_mixed_dtypes_multi(self): + self.df.count(axis=0, level=1) + + +class frame_count_level_axis0_multi(object): + goal_time = 0.2 + + def setup(self): + self.data = np.random.randn(10000, 1000) + self.df = DataFrame(self.data) + self.df.ix[50:1000, 20:50] = np.nan + self.df.ix[2000:3000] = np.nan + self.df.ix[:, 60:70] = np.nan + self.df.index = MultiIndex.from_tuples(self.df.index.map((lambda x: (x, x)))) + self.df.columns = MultiIndex.from_tuples(self.df.columns.map((lambda x: (x, x)))) + + def time_frame_count_level_axis0_multi(self): + self.df.count(axis=0, level=1) + + +class frame_count_level_axis1_mixed_dtypes_multi(object): + goal_time = 0.2 + + def setup(self): + self.data = np.random.randn(10000, 1000) + self.df = DataFrame(self.data) + self.df.ix[50:1000, 20:50] = np.nan + self.df.ix[2000:3000] = np.nan + self.df.ix[:, 60:70] = np.nan + self.df['foo'] = 'bar' + self.df.index = MultiIndex.from_tuples(self.df.index.map((lambda x: (x, x)))) + self.df.columns = MultiIndex.from_tuples(self.df.columns.map((lambda x: (x, x)))) + + def time_frame_count_level_axis1_mixed_dtypes_multi(self): + self.df.count(axis=1, level=1) + + +class frame_count_level_axis1_multi(object): + goal_time = 0.2 + + def setup(self): + self.data = np.random.randn(10000, 1000) + self.df = DataFrame(self.data) + self.df.ix[50:1000, 20:50] = np.nan + self.df.ix[2000:3000] = np.nan + self.df.ix[:, 60:70] = np.nan + self.df.index = MultiIndex.from_tuples(self.df.index.map((lambda x: (x, x)))) + self.df.columns = MultiIndex.from_tuples(self.df.columns.map((lambda x: (x, x)))) + + def time_frame_count_level_axis1_multi(self): + self.df.count(axis=1, level=1) + + +class frame_dropna_axis0_all(object): + goal_time = 0.2 + + def setup(self): + self.data = np.random.randn(10000, 1000) + self.df = DataFrame(self.data) + self.df.ix[50:1000, 20:50] = np.nan + self.df.ix[2000:3000] = np.nan + self.df.ix[:, 60:70] = np.nan + + def time_frame_dropna_axis0_all(self): + self.df.dropna(how='all', axis=0) + + +class frame_dropna_axis0_all_mixed_dtypes(object): + goal_time = 0.2 + + def setup(self): + self.data = np.random.randn(10000, 1000) + self.df = DataFrame(self.data) + self.df.ix[50:1000, 20:50] = np.nan + self.df.ix[2000:3000] = np.nan + self.df.ix[:, 60:70] = np.nan + self.df['foo'] = 'bar' + + def time_frame_dropna_axis0_all_mixed_dtypes(self): + self.df.dropna(how='all', axis=0) + + +class frame_dropna_axis0_any(object): + goal_time = 0.2 + + def setup(self): + self.data = np.random.randn(10000, 1000) + self.df = DataFrame(self.data) + self.df.ix[50:1000, 20:50] = np.nan + self.df.ix[2000:3000] = np.nan + self.df.ix[:, 60:70] = np.nan + + def time_frame_dropna_axis0_any(self): + self.df.dropna(how='any', axis=0) + + +class frame_dropna_axis0_any_mixed_dtypes(object): + goal_time = 0.2 + + def setup(self): + self.data = np.random.randn(10000, 1000) + self.df = DataFrame(self.data) + self.df.ix[50:1000, 20:50] = np.nan + self.df.ix[2000:3000] = np.nan + self.df.ix[:, 60:70] = np.nan + self.df['foo'] = 'bar' + + def time_frame_dropna_axis0_any_mixed_dtypes(self): + self.df.dropna(how='any', axis=0) + + +class frame_dropna_axis1_all(object): + goal_time = 0.2 + + def setup(self): + self.data = np.random.randn(10000, 1000) + self.df = DataFrame(self.data) + self.df.ix[50:1000, 20:50] = np.nan + self.df.ix[2000:3000] = np.nan + self.df.ix[:, 60:70] = np.nan + + def time_frame_dropna_axis1_all(self): + self.df.dropna(how='all', axis=1) + + +class frame_dropna_axis1_all_mixed_dtypes(object): + goal_time = 0.2 + + def setup(self): + self.data = np.random.randn(10000, 1000) + self.df = DataFrame(self.data) + self.df.ix[50:1000, 20:50] = np.nan + self.df.ix[2000:3000] = np.nan + self.df.ix[:, 60:70] = np.nan + self.df['foo'] = 'bar' + + def time_frame_dropna_axis1_all_mixed_dtypes(self): + self.df.dropna(how='all', axis=1) + + +class frame_dropna_axis1_any(object): + goal_time = 0.2 + + def setup(self): + self.data = np.random.randn(10000, 1000) + self.df = DataFrame(self.data) + self.df.ix[50:1000, 20:50] = np.nan + self.df.ix[2000:3000] = np.nan + self.df.ix[:, 60:70] = np.nan + + def time_frame_dropna_axis1_any(self): + self.df.dropna(how='any', axis=1) + + +class frame_dropna_axis1_any_mixed_dtypes(object): + goal_time = 0.2 + + def setup(self): + self.data = np.random.randn(10000, 1000) + self.df = DataFrame(self.data) + self.df.ix[50:1000, 20:50] = np.nan + self.df.ix[2000:3000] = np.nan + self.df.ix[:, 60:70] = np.nan + self.df['foo'] = 'bar' + + def time_frame_dropna_axis1_any_mixed_dtypes(self): + self.df.dropna(how='any', axis=1) + + +class frame_dtypes(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(1000, 1000)) + + def time_frame_dtypes(self): + self.df.dtypes + + +class frame_duplicated(object): + goal_time = 0.2 + + def setup(self): + self.n = (1 << 20) + self.t = date_range('2015-01-01', freq='S', periods=(self.n // 64)) + self.xs = np.random.randn((self.n // 64)).round(2) + self.df = DataFrame({'a': np.random.randint(((-1) << 8), (1 << 8), self.n), 'b': np.random.choice(self.t, self.n), 'c': np.random.choice(self.xs, self.n), }) + + def time_frame_duplicated(self): + self.df.duplicated() + + +class frame_fancy_lookup(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(10000, 8), columns=list('abcdefgh')) + self.df['foo'] = 'bar' + self.row_labels = list(self.df.index[::10])[:900] + self.col_labels = (list(self.df.columns) * 100) + self.row_labels_all = np.array((list(self.df.index) * len(self.df.columns)), dtype='object') + self.col_labels_all = np.array((list(self.df.columns) * len(self.df.index)), dtype='object') + + def time_frame_fancy_lookup(self): + self.df.lookup(self.row_labels, self.col_labels) + + +class frame_fancy_lookup_all(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(10000, 8), columns=list('abcdefgh')) + self.df['foo'] = 'bar' + self.row_labels = list(self.df.index[::10])[:900] + self.col_labels = (list(self.df.columns) * 100) + self.row_labels_all = np.array((list(self.df.index) * len(self.df.columns)), dtype='object') + self.col_labels_all = np.array((list(self.df.columns) * len(self.df.index)), dtype='object') + + def time_frame_fancy_lookup_all(self): + self.df.lookup(self.row_labels_all, self.col_labels_all) + + +class frame_fillna_inplace(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(randn(10000, 100)) + self.df.values[::2] = np.nan + + def time_frame_fillna_inplace(self): + self.df.fillna(0, inplace=True) + + +class frame_float_equal(object): + goal_time = 0.2 + + def setup(self): + + def make_pair(frame): + self.df = frame + self.df2 = self.df.copy() + self.df2.ix[((-1), (-1))] = np.nan + return (self.df, self.df2) + + def test_equal(name): + (self.df, self.df2) = pairs[name] + return self.df.equals(self.df) + + def test_unequal(name): + (self.df, self.df2) = pairs[name] + return self.df.equals(self.df2) + self.float_df = DataFrame(np.random.randn(1000, 1000)) + self.object_df = DataFrame(([(['foo'] * 1000)] * 1000)) + self.nonunique_cols = self.object_df.copy() + self.nonunique_cols.columns = (['A'] * len(self.nonunique_cols.columns)) + self.pairs = dict([(name, make_pair(frame)) for (name, frame) in (('float_df', self.float_df), ('object_df', self.object_df), ('nonunique_cols', self.nonunique_cols))]) + + def time_frame_float_equal(self): + test_equal('float_df') + + +class frame_float_unequal(object): + goal_time = 0.2 + + def setup(self): + + def make_pair(frame): + self.df = frame + self.df2 = self.df.copy() + self.df2.ix[((-1), (-1))] = np.nan + return (self.df, self.df2) + + def test_equal(name): + (self.df, self.df2) = pairs[name] + return self.df.equals(self.df) + + def test_unequal(name): + (self.df, self.df2) = pairs[name] + return self.df.equals(self.df2) + self.float_df = DataFrame(np.random.randn(1000, 1000)) + self.object_df = DataFrame(([(['foo'] * 1000)] * 1000)) + self.nonunique_cols = self.object_df.copy() + self.nonunique_cols.columns = (['A'] * len(self.nonunique_cols.columns)) + self.pairs = dict([(name, make_pair(frame)) for (name, frame) in (('float_df', self.float_df), ('object_df', self.object_df), ('nonunique_cols', self.nonunique_cols))]) + + def time_frame_float_unequal(self): + test_unequal('float_df') + + +class frame_from_records_generator(object): + goal_time = 0.2 + + def setup(self): + + def get_data(n=100000): + return ((x, (x * 20), (x * 100)) for x in xrange(n)) + + def time_frame_from_records_generator(self): + self.df = DataFrame.from_records(get_data()) + + +class frame_from_records_generator_nrows(object): + goal_time = 0.2 + + def setup(self): + + def get_data(n=100000): + return ((x, (x * 20), (x * 100)) for x in xrange(n)) + + def time_frame_from_records_generator_nrows(self): + self.df = DataFrame.from_records(get_data(), nrows=1000) + + +class frame_get_dtype_counts(object): + goal_time = 0.2 + + def setup(self): + self.df = pandas.DataFrame(np.random.randn(10, 10000)) + + def time_frame_get_dtype_counts(self): + self.df.get_dtype_counts() + + +class frame_getitem_single_column(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(randn(10000, 1000)) + self.df2 = DataFrame(randn(3000, 1), columns=['A']) + self.df3 = DataFrame(randn(3000, 1)) + + def f(): + if hasattr(self.df, '_item_cache'): + self.df._item_cache.clear() + for (name, col) in self.df.iteritems(): + pass + + def g(): + for (name, col) in self.df.iteritems(): + pass + + def h(): + for i in xrange(10000): + self.df2['A'] + + def j(): + for i in xrange(10000): + self.df3[0] + + def time_frame_getitem_single_column(self): + h() + + +class frame_getitem_single_column2(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(randn(10000, 1000)) + self.df2 = DataFrame(randn(3000, 1), columns=['A']) + self.df3 = DataFrame(randn(3000, 1)) + + def f(): + if hasattr(self.df, '_item_cache'): + self.df._item_cache.clear() + for (name, col) in self.df.iteritems(): + pass + + def g(): + for (name, col) in self.df.iteritems(): + pass + + def h(): + for i in xrange(10000): + self.df2['A'] + + def j(): + for i in xrange(10000): + self.df3[0] + + def time_frame_getitem_single_column2(self): + j() + + +class frame_html_repr_trunc_mi(object): + goal_time = 0.2 + + def setup(self): + self.nrows = 10000 + self.data = randn(self.nrows, 10) + self.idx = MultiIndex.from_arrays(np.tile(randn(3, (self.nrows / 100)), 100)) + self.df = DataFrame(self.data, index=self.idx) + + def time_frame_html_repr_trunc_mi(self): + self.df._repr_html_() + + +class frame_html_repr_trunc_si(object): + goal_time = 0.2 + + def setup(self): + self.nrows = 10000 + self.data = randn(self.nrows, 10) + self.idx = randn(self.nrows) + self.df = DataFrame(self.data, index=self.idx) + + def time_frame_html_repr_trunc_si(self): + self.df._repr_html_() + + +class frame_insert_100_columns_begin(object): + goal_time = 0.2 + + def setup(self): + self.N = 1000 + + def f(K=100): + self.df = DataFrame(index=range(self.N)) + self.new_col = np.random.randn(self.N) + for i in range(K): + self.df.insert(0, i, self.new_col) + + def time_frame_insert_100_columns_begin(self): + f() + + +class frame_insert_500_columns_end(object): + goal_time = 0.2 + + def setup(self): + self.N = 1000 + + def f(K=500): + self.df = DataFrame(index=range(self.N)) + self.new_col = np.random.randn(self.N) + for i in range(K): + self.df[i] = self.new_col + + def time_frame_insert_500_columns_end(self): + f() + + +class frame_interpolate(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(randn(10000, 100)) + self.df.values[::2] = np.nan + + def time_frame_interpolate(self): + self.df.interpolate() + + +class frame_interpolate_some_good(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame({'A': np.arange(0, 10000), 'B': np.random.randint(0, 100, 10000), 'C': randn(10000), 'D': randn(10000), }) + self.df.loc[1::5, 'A'] = np.nan + self.df.loc[1::5, 'C'] = np.nan + + def time_frame_interpolate_some_good(self): + self.df.interpolate() + + +class frame_interpolate_some_good_infer(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame({'A': np.arange(0, 10000), 'B': np.random.randint(0, 100, 10000), 'C': randn(10000), 'D': randn(10000), }) + self.df.loc[1::5, 'A'] = np.nan + self.df.loc[1::5, 'C'] = np.nan + + def time_frame_interpolate_some_good_infer(self): + self.df.interpolate(downcast='infer') + + +class frame_isnull(object): + goal_time = 0.2 + + def setup(self): + self.data = np.random.randn(1000, 1000) + self.df = DataFrame(self.data) + + def time_frame_isnull(self): + isnull(self.df) + + +class frame_iteritems(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(randn(10000, 1000)) + self.df2 = DataFrame(randn(3000, 1), columns=['A']) + self.df3 = DataFrame(randn(3000, 1)) + + def f(): + if hasattr(self.df, '_item_cache'): + self.df._item_cache.clear() + for (name, col) in self.df.iteritems(): + pass + + def g(): + for (name, col) in self.df.iteritems(): + pass + + def h(): + for i in xrange(10000): + self.df2['A'] + + def j(): + for i in xrange(10000): + self.df3[0] + + def time_frame_iteritems(self): + f() + + +class frame_iteritems_cached(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(randn(10000, 1000)) + self.df2 = DataFrame(randn(3000, 1), columns=['A']) + self.df3 = DataFrame(randn(3000, 1)) + + def f(): + if hasattr(self.df, '_item_cache'): + self.df._item_cache.clear() + for (name, col) in self.df.iteritems(): + pass + + def g(): + for (name, col) in self.df.iteritems(): + pass + + def h(): + for i in xrange(10000): + self.df2['A'] + + def j(): + for i in xrange(10000): + self.df3[0] + + def time_frame_iteritems_cached(self): + g() + + +class frame_mask_bools(object): + goal_time = 0.2 + + def setup(self): + self.data = np.random.randn(1000, 500) + self.df = DataFrame(self.data) + self.df = self.df.where((self.df > 0)) + self.bools = (self.df > 0) + self.mask = isnull(self.df) + + def time_frame_mask_bools(self): + self.bools.mask(self.mask) + + +class frame_mask_floats(object): + goal_time = 0.2 + + def setup(self): + self.data = np.random.randn(1000, 500) + self.df = DataFrame(self.data) + self.df = self.df.where((self.df > 0)) + self.bools = (self.df > 0) + self.mask = isnull(self.df) + + def time_frame_mask_floats(self): + self.bools.astype(float).mask(self.mask) + + +class frame_nonunique_equal(object): + goal_time = 0.2 + + def setup(self): + + def make_pair(frame): + self.df = frame + self.df2 = self.df.copy() + self.df2.ix[((-1), (-1))] = np.nan + return (self.df, self.df2) + + def test_equal(name): + (self.df, self.df2) = pairs[name] + return self.df.equals(self.df) + + def test_unequal(name): + (self.df, self.df2) = pairs[name] + return self.df.equals(self.df2) + self.float_df = DataFrame(np.random.randn(1000, 1000)) + self.object_df = DataFrame(([(['foo'] * 1000)] * 1000)) + self.nonunique_cols = self.object_df.copy() + self.nonunique_cols.columns = (['A'] * len(self.nonunique_cols.columns)) + self.pairs = dict([(name, make_pair(frame)) for (name, frame) in (('float_df', self.float_df), ('object_df', self.object_df), ('nonunique_cols', self.nonunique_cols))]) + + def time_frame_nonunique_equal(self): + test_equal('nonunique_cols') + + +class frame_nonunique_unequal(object): + goal_time = 0.2 + + def setup(self): + + def make_pair(frame): + self.df = frame + self.df2 = self.df.copy() + self.df2.ix[((-1), (-1))] = np.nan + return (self.df, self.df2) + + def test_equal(name): + (self.df, self.df2) = pairs[name] + return self.df.equals(self.df) + + def test_unequal(name): + (self.df, self.df2) = pairs[name] + return self.df.equals(self.df2) + self.float_df = DataFrame(np.random.randn(1000, 1000)) + self.object_df = DataFrame(([(['foo'] * 1000)] * 1000)) + self.nonunique_cols = self.object_df.copy() + self.nonunique_cols.columns = (['A'] * len(self.nonunique_cols.columns)) + self.pairs = dict([(name, make_pair(frame)) for (name, frame) in (('float_df', self.float_df), ('object_df', self.object_df), ('nonunique_cols', self.nonunique_cols))]) + + def time_frame_nonunique_unequal(self): + test_unequal('nonunique_cols') + + +class frame_object_equal(object): + goal_time = 0.2 + + def setup(self): + + def make_pair(frame): + self.df = frame + self.df2 = self.df.copy() + self.df2.ix[((-1), (-1))] = np.nan + return (self.df, self.df2) + + def test_equal(name): + (self.df, self.df2) = pairs[name] + return self.df.equals(self.df) + + def test_unequal(name): + (self.df, self.df2) = pairs[name] + return self.df.equals(self.df2) + self.float_df = DataFrame(np.random.randn(1000, 1000)) + self.object_df = DataFrame(([(['foo'] * 1000)] * 1000)) + self.nonunique_cols = self.object_df.copy() + self.nonunique_cols.columns = (['A'] * len(self.nonunique_cols.columns)) + self.pairs = dict([(name, make_pair(frame)) for (name, frame) in (('float_df', self.float_df), ('object_df', self.object_df), ('nonunique_cols', self.nonunique_cols))]) + + def time_frame_object_equal(self): + test_equal('object_df') + + +class frame_object_unequal(object): + goal_time = 0.2 + + def setup(self): + + def make_pair(frame): + self.df = frame + self.df2 = self.df.copy() + self.df2.ix[((-1), (-1))] = np.nan + return (self.df, self.df2) + + def test_equal(name): + (self.df, self.df2) = pairs[name] + return self.df.equals(self.df) + + def test_unequal(name): + (self.df, self.df2) = pairs[name] + return self.df.equals(self.df2) + self.float_df = DataFrame(np.random.randn(1000, 1000)) + self.object_df = DataFrame(([(['foo'] * 1000)] * 1000)) + self.nonunique_cols = self.object_df.copy() + self.nonunique_cols.columns = (['A'] * len(self.nonunique_cols.columns)) + self.pairs = dict([(name, make_pair(frame)) for (name, frame) in (('float_df', self.float_df), ('object_df', self.object_df), ('nonunique_cols', self.nonunique_cols))]) + + def time_frame_object_unequal(self): + test_unequal('object_df') + + +class frame_reindex_axis0(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(randn(10000, 10000)) + self.idx = np.arange(4000, 7000) + + def time_frame_reindex_axis0(self): + self.df.reindex(self.idx) + + +class frame_reindex_axis1(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(randn(10000, 10000)) + self.idx = np.arange(4000, 7000) + + def time_frame_reindex_axis1(self): + self.df.reindex(columns=self.idx) + + +class frame_reindex_both_axes(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(randn(10000, 10000)) + self.idx = np.arange(4000, 7000) + + def time_frame_reindex_both_axes(self): + self.df.reindex(index=self.idx, columns=self.idx) + + +class frame_reindex_both_axes_ix(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(randn(10000, 10000)) + self.idx = np.arange(4000, 7000) + + def time_frame_reindex_both_axes_ix(self): + self.df.ix[(self.idx, self.idx)] + + +class frame_reindex_upcast(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(dict([(c, {0: randint(0, 2, 1000).astype(np.bool_), 1: randint(0, 1000, 1000).astype(np.int16), 2: randint(0, 1000, 1000).astype(np.int32), 3: randint(0, 1000, 1000).astype(np.int64), }[randint(0, 4)]) for c in range(1000)])) + + def time_frame_reindex_upcast(self): + self.df.reindex(permutation(range(1200))) + + +class frame_repr_tall(object): + goal_time = 0.2 + + def setup(self): + self.df = pandas.DataFrame(np.random.randn(10000, 10)) + + def time_frame_repr_tall(self): + repr(self.df) + + +class frame_repr_wide(object): + goal_time = 0.2 + + def setup(self): + self.df = pandas.DataFrame(np.random.randn(10, 10000)) + + def time_frame_repr_wide(self): + repr(self.df) + + +class frame_shift_axis0(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.rand(10000, 500)) + + def time_frame_shift_axis0(self): + self.df.shift(1, axis=0) + + +class frame_shift_axis_1(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.rand(10000, 500)) + + def time_frame_shift_axis_1(self): + self.df.shift(1, axis=1) + + +class frame_to_html_mixed(object): + goal_time = 0.2 + + def setup(self): + self.nrows = 500 + self.df = DataFrame(randn(self.nrows, 10)) + self.df[0] = period_range('2000', '2010', self.nrows) + self.df[1] = range(self.nrows) + + def time_frame_to_html_mixed(self): + self.df.to_html() + + +class frame_to_string_floats(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(randn(100, 10)) + + def time_frame_to_string_floats(self): + self.df.to_string() + + +class frame_xs_col(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(randn(1, 100000)) + + def time_frame_xs_col(self): + self.df.xs(50000, axis=1) + + +class frame_xs_row(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(randn(100000, 1)) + + def time_frame_xs_row(self): + self.df.xs(50000) + + +class series_string_vector_slice(object): + goal_time = 0.2 + + def setup(self): + self.s = Series((['abcdefg', np.nan] * 500000)) + + def time_series_string_vector_slice(self): + self.s.str[:5] \ No newline at end of file diff --git a/asv_bench/benchmarks/gil.py b/asv_bench/benchmarks/gil.py new file mode 100644 index 0000000000000..b0486617a52af --- /dev/null +++ b/asv_bench/benchmarks/gil.py @@ -0,0 +1,267 @@ +from pandas_vb_common import * +from pandas.core import common as com +from pandas.util.testing import test_parallel + + +class nogil_groupby_count_2(object): + goal_time = 0.2 + + def setup(self): + self.N = 1000000 + self.ngroups = 1000 + np.random.seed(1234) + self.df = DataFrame({'key': np.random.randint(0, self.ngroups, size=self.N), 'data': np.random.randn(self.N), }) + + @test_parallel(num_threads=2) + def pg2(): + self.df.groupby('key')['data'].count() + + def time_nogil_groupby_count_2(self): + pg2() + + +class nogil_groupby_last_2(object): + goal_time = 0.2 + + def setup(self): + self.N = 1000000 + self.ngroups = 1000 + np.random.seed(1234) + self.df = DataFrame({'key': np.random.randint(0, self.ngroups, size=self.N), 'data': np.random.randn(self.N), }) + + @test_parallel(num_threads=2) + def pg2(): + self.df.groupby('key')['data'].last() + + def time_nogil_groupby_last_2(self): + pg2() + + +class nogil_groupby_max_2(object): + goal_time = 0.2 + + def setup(self): + self.N = 1000000 + self.ngroups = 1000 + np.random.seed(1234) + self.df = DataFrame({'key': np.random.randint(0, self.ngroups, size=self.N), 'data': np.random.randn(self.N), }) + + @test_parallel(num_threads=2) + def pg2(): + self.df.groupby('key')['data'].max() + + def time_nogil_groupby_max_2(self): + pg2() + + +class nogil_groupby_mean_2(object): + goal_time = 0.2 + + def setup(self): + self.N = 1000000 + self.ngroups = 1000 + np.random.seed(1234) + self.df = DataFrame({'key': np.random.randint(0, self.ngroups, size=self.N), 'data': np.random.randn(self.N), }) + + @test_parallel(num_threads=2) + def pg2(): + self.df.groupby('key')['data'].mean() + + def time_nogil_groupby_mean_2(self): + pg2() + + +class nogil_groupby_min_2(object): + goal_time = 0.2 + + def setup(self): + self.N = 1000000 + self.ngroups = 1000 + np.random.seed(1234) + self.df = DataFrame({'key': np.random.randint(0, self.ngroups, size=self.N), 'data': np.random.randn(self.N), }) + + @test_parallel(num_threads=2) + def pg2(): + self.df.groupby('key')['data'].min() + + def time_nogil_groupby_min_2(self): + pg2() + + +class nogil_groupby_prod_2(object): + goal_time = 0.2 + + def setup(self): + self.N = 1000000 + self.ngroups = 1000 + np.random.seed(1234) + self.df = DataFrame({'key': np.random.randint(0, self.ngroups, size=self.N), 'data': np.random.randn(self.N), }) + + @test_parallel(num_threads=2) + def pg2(): + self.df.groupby('key')['data'].prod() + + def time_nogil_groupby_prod_2(self): + pg2() + + +class nogil_groupby_sum_2(object): + goal_time = 0.2 + + def setup(self): + self.N = 1000000 + self.ngroups = 1000 + np.random.seed(1234) + self.df = DataFrame({'key': np.random.randint(0, self.ngroups, size=self.N), 'data': np.random.randn(self.N), }) + + @test_parallel(num_threads=2) + def pg2(): + self.df.groupby('key')['data'].sum() + + def time_nogil_groupby_sum_2(self): + pg2() + + +class nogil_groupby_sum_4(object): + goal_time = 0.2 + + def setup(self): + self.N = 1000000 + self.ngroups = 1000 + np.random.seed(1234) + self.df = DataFrame({'key': np.random.randint(0, self.ngroups, size=self.N), 'data': np.random.randn(self.N), }) + + def f(): + self.df.groupby('key')['data'].sum() + + def g2(): + for i in range(2): + f() + + def g4(): + for i in range(4): + f() + + def g8(): + for i in range(8): + f() + + @test_parallel(num_threads=2) + def pg2(): + f() + + @test_parallel(num_threads=4) + def pg4(): + f() + + @test_parallel(num_threads=8) + def pg8(): + f() + + def time_nogil_groupby_sum_4(self): + pg4() + + +class nogil_groupby_sum_8(object): + goal_time = 0.2 + + def setup(self): + self.N = 1000000 + self.ngroups = 1000 + np.random.seed(1234) + self.df = DataFrame({'key': np.random.randint(0, self.ngroups, size=self.N), 'data': np.random.randn(self.N), }) + + def f(): + self.df.groupby('key')['data'].sum() + + def g2(): + for i in range(2): + f() + + def g4(): + for i in range(4): + f() + + def g8(): + for i in range(8): + f() + + @test_parallel(num_threads=2) + def pg2(): + f() + + @test_parallel(num_threads=4) + def pg4(): + f() + + @test_parallel(num_threads=8) + def pg8(): + f() + + def time_nogil_groupby_sum_8(self): + pg8() + + +class nogil_groupby_var_2(object): + goal_time = 0.2 + + def setup(self): + self.N = 1000000 + self.ngroups = 1000 + np.random.seed(1234) + self.df = DataFrame({'key': np.random.randint(0, self.ngroups, size=self.N), 'data': np.random.randn(self.N), }) + + @test_parallel(num_threads=2) + def pg2(): + self.df.groupby('key')['data'].var() + + def time_nogil_groupby_var_2(self): + pg2() + + +class nogil_take1d_float64(object): + goal_time = 0.2 + + def setup(self): + self.N = 1000000 + self.ngroups = 1000 + np.random.seed(1234) + self.df = DataFrame({'key': np.random.randint(0, self.ngroups, size=self.N), 'data': np.random.randn(self.N), }) + self.N = 10000000.0 + self.df = DataFrame({'int64': np.arange(self.N, dtype='int64'), 'float64': np.arange(self.N, dtype='float64'), }) + self.indexer = np.arange(100, (len(self.df) - 100)) + + @test_parallel(num_threads=2) + def take_1d_pg2_int64(): + com.take_1d(self.df.int64.values, self.indexer) + + @test_parallel(num_threads=2) + def take_1d_pg2_float64(): + com.take_1d(self.df.float64.values, self.indexer) + + def time_nogil_take1d_float64(self): + take_1d_pg2_int64() + + +class nogil_take1d_int64(object): + goal_time = 0.2 + + def setup(self): + self.N = 1000000 + self.ngroups = 1000 + np.random.seed(1234) + self.df = DataFrame({'key': np.random.randint(0, self.ngroups, size=self.N), 'data': np.random.randn(self.N), }) + self.N = 10000000.0 + self.df = DataFrame({'int64': np.arange(self.N, dtype='int64'), 'float64': np.arange(self.N, dtype='float64'), }) + self.indexer = np.arange(100, (len(self.df) - 100)) + + @test_parallel(num_threads=2) + def take_1d_pg2_int64(): + com.take_1d(self.df.int64.values, self.indexer) + + @test_parallel(num_threads=2) + def take_1d_pg2_float64(): + com.take_1d(self.df.float64.values, self.indexer) + + def time_nogil_take1d_int64(self): + take_1d_pg2_float64() \ No newline at end of file diff --git a/asv_bench/benchmarks/groupby.py b/asv_bench/benchmarks/groupby.py new file mode 100644 index 0000000000000..4f1f4e46b4a31 --- /dev/null +++ b/asv_bench/benchmarks/groupby.py @@ -0,0 +1,1683 @@ +from pandas_vb_common import * +from itertools import product +from string import ascii_letters, digits + + +class groupby_agg_builtins1(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(27182) + self.n = 100000 + self.df = DataFrame(np.random.randint(1, (self.n / 100), (self.n, 3)), columns=['jim', 'joe', 'jolie']) + + def time_groupby_agg_builtins1(self): + self.df.groupby('jim').agg([sum, min, max]) + + +class groupby_agg_builtins2(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(27182) + self.n = 100000 + self.df = DataFrame(np.random.randint(1, (self.n / 100), (self.n, 3)), columns=['jim', 'joe', 'jolie']) + + def time_groupby_agg_builtins2(self): + self.df.groupby(['jim', 'joe']).agg([sum, min, max]) + + +class groupby_apply_dict_return(object): + goal_time = 0.2 + + def setup(self): + self.labels = np.arange(1000).repeat(10) + self.data = Series(randn(len(self.labels))) + self.f = (lambda x: {'first': x.values[0], 'last': x.values[(-1)], }) + + def time_groupby_apply_dict_return(self): + self.data.groupby(self.labels).apply(self.f) + + +class groupby_dt_size(object): + goal_time = 0.2 + + def setup(self): + self.n = 100000 + self.offsets = np.random.randint(self.n, size=self.n).astype('timedelta64[ns]') + self.dates = (np.datetime64('now') + self.offsets) + self.df = DataFrame({'key1': np.random.randint(0, 500, size=self.n), 'key2': np.random.randint(0, 100, size=self.n), 'value1': np.random.randn(self.n), 'value2': np.random.randn(self.n), 'value3': np.random.randn(self.n), 'dates': self.dates, }) + + def time_groupby_dt_size(self): + self.df.groupby(['dates']).size() + + +class groupby_dt_timegrouper_size(object): + goal_time = 0.2 + + def setup(self): + self.n = 100000 + self.offsets = np.random.randint(self.n, size=self.n).astype('timedelta64[ns]') + self.dates = (np.datetime64('now') + self.offsets) + self.df = DataFrame({'key1': np.random.randint(0, 500, size=self.n), 'key2': np.random.randint(0, 100, size=self.n), 'value1': np.random.randn(self.n), 'value2': np.random.randn(self.n), 'value3': np.random.randn(self.n), 'dates': self.dates, }) + + def time_groupby_dt_timegrouper_size(self): + self.df.groupby(TimeGrouper(key='dates', freq='M')).size() + + +class groupby_first_datetimes(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame({'a': date_range('1/1/2011', periods=100000, freq='s'), 'b': range(100000), }) + + def time_groupby_first_datetimes(self): + self.df.groupby('b').first() + + +class groupby_first_float32(object): + goal_time = 0.2 + + def setup(self): + self.labels = np.arange(10000).repeat(10) + self.data = Series(randn(len(self.labels))) + self.data[::3] = np.nan + self.data[1::3] = np.nan + self.data2 = Series(randn(len(self.labels)), dtype='float32') + self.data2[::3] = np.nan + self.data2[1::3] = np.nan + self.labels = self.labels.take(np.random.permutation(len(self.labels))) + + def time_groupby_first_float32(self): + self.data2.groupby(self.labels).first() + + +class groupby_first_float64(object): + goal_time = 0.2 + + def setup(self): + self.labels = np.arange(10000).repeat(10) + self.data = Series(randn(len(self.labels))) + self.data[::3] = np.nan + self.data[1::3] = np.nan + self.data2 = Series(randn(len(self.labels)), dtype='float32') + self.data2[::3] = np.nan + self.data2[1::3] = np.nan + self.labels = self.labels.take(np.random.permutation(len(self.labels))) + + def time_groupby_first_float64(self): + self.data.groupby(self.labels).first() + + +class groupby_first_object(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame({'a': (['foo'] * 100000), 'b': range(100000), }) + + def time_groupby_first_object(self): + self.df.groupby('b').first() + + +class groupby_frame_apply(object): + goal_time = 0.2 + + def setup(self): + self.N = 10000 + self.labels = np.random.randint(0, 2000, size=self.N) + self.labels2 = np.random.randint(0, 3, size=self.N) + self.df = DataFrame({'key': self.labels, 'key2': self.labels2, 'value1': randn(self.N), 'value2': (['foo', 'bar', 'baz', 'qux'] * (self.N / 4)), }) + + def f(g): + return 1 + + def time_groupby_frame_apply(self): + self.df.groupby(['key', 'key2']).apply(f) + + +class groupby_frame_apply_overhead(object): + goal_time = 0.2 + + def setup(self): + self.N = 10000 + self.labels = np.random.randint(0, 2000, size=self.N) + self.labels2 = np.random.randint(0, 3, size=self.N) + self.df = DataFrame({'key': self.labels, 'key2': self.labels2, 'value1': randn(self.N), 'value2': (['foo', 'bar', 'baz', 'qux'] * (self.N / 4)), }) + + def f(g): + return 1 + + def time_groupby_frame_apply_overhead(self): + self.df.groupby('key').apply(f) + + +class groupby_frame_cython_many_columns(object): + goal_time = 0.2 + + def setup(self): + self.labels = np.random.randint(0, 100, size=1000) + self.df = DataFrame(randn(1000, 1000)) + + def time_groupby_frame_cython_many_columns(self): + self.df.groupby(self.labels).sum() + + +class groupby_frame_median(object): + goal_time = 0.2 + + def setup(self): + self.data = np.random.randn(100000, 2) + self.labels = np.random.randint(0, 1000, size=100000) + self.df = DataFrame(self.data) + + def time_groupby_frame_median(self): + self.df.groupby(self.labels).median() + + +class groupby_frame_nth_any(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randint(1, 100, (10000, 2))) + + def time_groupby_frame_nth_any(self): + self.df.groupby(0).nth(0, dropna='any') + + +class groupby_frame_nth_none(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randint(1, 100, (10000, 2))) + + def time_groupby_frame_nth_none(self): + self.df.groupby(0).nth(0) + + +class groupby_frame_singlekey_integer(object): + goal_time = 0.2 + + def setup(self): + self.data = np.random.randn(100000, 1) + self.labels = np.random.randint(0, 1000, size=100000) + self.df = DataFrame(self.data) + + def time_groupby_frame_singlekey_integer(self): + self.df.groupby(self.labels).sum() + + +class groupby_indices(object): + goal_time = 0.2 + + def setup(self): + try: + self.rng = date_range('1/1/2000', '12/31/2005', freq='H') + (year, month, day) = (self.rng.year, self.rng.month, self.rng.day) + except: + self.rng = date_range('1/1/2000', '12/31/2000', offset=datetools.Hour()) + self.year = self.rng.map((lambda x: x.year)) + self.month = self.rng.map((lambda x: x.month)) + self.day = self.rng.map((lambda x: x.day)) + self.ts = Series(np.random.randn(len(self.rng)), index=self.rng) + + def time_groupby_indices(self): + len(self.ts.groupby([self.year, self.month, self.day])) + + +class groupby_int64_overflow(object): + goal_time = 0.2 + + def setup(self): + self.arr = np.random.randint(((-1) << 12), (1 << 12), ((1 << 17), 5)) + self.i = np.random.choice(len(self.arr), (len(self.arr) * 5)) + self.arr = np.vstack((self.arr, self.arr[self.i])) + self.i = np.random.permutation(len(self.arr)) + self.arr = self.arr[self.i] + self.df = DataFrame(self.arr, columns=list('abcde')) + (self.df['jim'], self.df['joe']) = (np.random.randn(2, len(self.df)) * 10) + + def time_groupby_int64_overflow(self): + self.df.groupby(list('abcde')).max() + + +class groupby_int_count(object): + goal_time = 0.2 + + def setup(self): + self.n = 10000 + self.df = DataFrame({'key1': randint(0, 500, size=self.n), 'key2': randint(0, 100, size=self.n), 'ints': randint(0, 1000, size=self.n), 'ints2': randint(0, 1000, size=self.n), }) + + def time_groupby_int_count(self): + self.df.groupby(['key1', 'key2']).count() + + +class groupby_last_datetimes(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame({'a': date_range('1/1/2011', periods=100000, freq='s'), 'b': range(100000), }) + + def time_groupby_last_datetimes(self): + self.df.groupby('b').last() + + +class groupby_last_float32(object): + goal_time = 0.2 + + def setup(self): + self.labels = np.arange(10000).repeat(10) + self.data = Series(randn(len(self.labels))) + self.data[::3] = np.nan + self.data[1::3] = np.nan + self.data2 = Series(randn(len(self.labels)), dtype='float32') + self.data2[::3] = np.nan + self.data2[1::3] = np.nan + self.labels = self.labels.take(np.random.permutation(len(self.labels))) + + def time_groupby_last_float32(self): + self.data2.groupby(self.labels).last() + + +class groupby_last_float64(object): + goal_time = 0.2 + + def setup(self): + self.labels = np.arange(10000).repeat(10) + self.data = Series(randn(len(self.labels))) + self.data[::3] = np.nan + self.data[1::3] = np.nan + self.data2 = Series(randn(len(self.labels)), dtype='float32') + self.data2[::3] = np.nan + self.data2[1::3] = np.nan + self.labels = self.labels.take(np.random.permutation(len(self.labels))) + + def time_groupby_last_float64(self): + self.data.groupby(self.labels).last() + + +class groupby_last_object(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame({'a': (['foo'] * 100000), 'b': range(100000), }) + + def time_groupby_last_object(self): + self.df.groupby('b').last() + + +class groupby_multi_count(object): + goal_time = 0.2 + + def setup(self): + self.n = 10000 + self.offsets = np.random.randint(self.n, size=self.n).astype('timedelta64[ns]') + self.dates = (np.datetime64('now') + self.offsets) + self.dates[(np.random.rand(self.n) > 0.5)] = np.datetime64('nat') + self.offsets[(np.random.rand(self.n) > 0.5)] = np.timedelta64('nat') + self.value2 = np.random.randn(self.n) + self.value2[(np.random.rand(self.n) > 0.5)] = np.nan + self.obj = tm.choice(list('ab'), size=self.n).astype(object) + self.obj[(np.random.randn(self.n) > 0.5)] = np.nan + self.df = DataFrame({'key1': np.random.randint(0, 500, size=self.n), 'key2': np.random.randint(0, 100, size=self.n), 'dates': self.dates, 'value2': self.value2, 'value3': np.random.randn(self.n), 'ints': np.random.randint(0, 1000, size=self.n), 'obj': self.obj, 'offsets': self.offsets, }) + + def time_groupby_multi_count(self): + self.df.groupby(['key1', 'key2']).count() + + +class groupby_multi_cython(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.ngroups = 100 + + def get_test_data(ngroups=100, n=self.N): + self.unique_groups = range(self.ngroups) + self.arr = np.asarray(np.tile(self.unique_groups, (n / self.ngroups)), dtype=object) + if (len(self.arr) < n): + self.arr = np.asarray((list(self.arr) + self.unique_groups[:(n - len(self.arr))]), dtype=object) + random.shuffle(self.arr) + return self.arr + self.df = DataFrame({'key1': get_test_data(ngroups=self.ngroups), 'key2': get_test_data(ngroups=self.ngroups), 'data1': np.random.randn(self.N), 'data2': np.random.randn(self.N), }) + + def f(): + self.df.groupby(['key1', 'key2']).agg((lambda x: x.values.sum())) + self.simple_series = Series(np.random.randn(self.N)) + self.key1 = self.df['key1'] + + def time_groupby_multi_cython(self): + self.df.groupby(['key1', 'key2']).sum() + + +class groupby_multi_different_functions(object): + goal_time = 0.2 + + def setup(self): + self.fac1 = np.array(['A', 'B', 'C'], dtype='O') + self.fac2 = np.array(['one', 'two'], dtype='O') + self.df = DataFrame({'key1': self.fac1.take(np.random.randint(0, 3, size=100000)), 'key2': self.fac2.take(np.random.randint(0, 2, size=100000)), 'value1': np.random.randn(100000), 'value2': np.random.randn(100000), 'value3': np.random.randn(100000), }) + + def time_groupby_multi_different_functions(self): + self.df.groupby(['key1', 'key2']).agg({'value1': 'mean', 'value2': 'var', 'value3': 'sum', }) + + +class groupby_multi_different_numpy_functions(object): + goal_time = 0.2 + + def setup(self): + self.fac1 = np.array(['A', 'B', 'C'], dtype='O') + self.fac2 = np.array(['one', 'two'], dtype='O') + self.df = DataFrame({'key1': self.fac1.take(np.random.randint(0, 3, size=100000)), 'key2': self.fac2.take(np.random.randint(0, 2, size=100000)), 'value1': np.random.randn(100000), 'value2': np.random.randn(100000), 'value3': np.random.randn(100000), }) + + def time_groupby_multi_different_numpy_functions(self): + self.df.groupby(['key1', 'key2']).agg({'value1': np.mean, 'value2': np.var, 'value3': np.sum, }) + + +class groupby_multi_index(object): + goal_time = 0.2 + + def setup(self): + self.n = (((5 * 7) * 11) * (1 << 9)) + self.alpha = list(map(''.join, product((ascii_letters + digits), repeat=4))) + self.f = (lambda k: np.repeat(np.random.choice(self.alpha, (self.n // k)), k)) + self.df = DataFrame({'a': self.f(11), 'b': self.f(7), 'c': self.f(5), 'd': self.f(1), }) + self.df['joe'] = (np.random.randn(len(self.df)) * 10).round(3) + self.i = np.random.permutation(len(self.df)) + self.df = self.df.iloc[self.i].reset_index(drop=True).copy() + + def time_groupby_multi_index(self): + self.df.groupby(list('abcd')).max() + + +class groupby_multi_python(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.ngroups = 100 + + def get_test_data(ngroups=100, n=self.N): + self.unique_groups = range(self.ngroups) + self.arr = np.asarray(np.tile(self.unique_groups, (n / self.ngroups)), dtype=object) + if (len(self.arr) < n): + self.arr = np.asarray((list(self.arr) + self.unique_groups[:(n - len(self.arr))]), dtype=object) + random.shuffle(self.arr) + return self.arr + self.df = DataFrame({'key1': get_test_data(ngroups=self.ngroups), 'key2': get_test_data(ngroups=self.ngroups), 'data1': np.random.randn(self.N), 'data2': np.random.randn(self.N), }) + + def f(): + self.df.groupby(['key1', 'key2']).agg((lambda x: x.values.sum())) + self.simple_series = Series(np.random.randn(self.N)) + self.key1 = self.df['key1'] + + def time_groupby_multi_python(self): + self.df.groupby(['key1', 'key2'])['data1'].agg((lambda x: x.values.sum())) + + +class groupby_multi_series_op(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.ngroups = 100 + + def get_test_data(ngroups=100, n=self.N): + self.unique_groups = range(self.ngroups) + self.arr = np.asarray(np.tile(self.unique_groups, (n / self.ngroups)), dtype=object) + if (len(self.arr) < n): + self.arr = np.asarray((list(self.arr) + self.unique_groups[:(n - len(self.arr))]), dtype=object) + random.shuffle(self.arr) + return self.arr + self.df = DataFrame({'key1': get_test_data(ngroups=self.ngroups), 'key2': get_test_data(ngroups=self.ngroups), 'data1': np.random.randn(self.N), 'data2': np.random.randn(self.N), }) + + def f(): + self.df.groupby(['key1', 'key2']).agg((lambda x: x.values.sum())) + self.simple_series = Series(np.random.randn(self.N)) + self.key1 = self.df['key1'] + + def time_groupby_multi_series_op(self): + self.df.groupby(['key1', 'key2'])['data1'].agg(np.std) + + +class groupby_multi_size(object): + goal_time = 0.2 + + def setup(self): + self.n = 100000 + self.offsets = np.random.randint(self.n, size=self.n).astype('timedelta64[ns]') + self.dates = (np.datetime64('now') + self.offsets) + self.df = DataFrame({'key1': np.random.randint(0, 500, size=self.n), 'key2': np.random.randint(0, 100, size=self.n), 'value1': np.random.randn(self.n), 'value2': np.random.randn(self.n), 'value3': np.random.randn(self.n), 'dates': self.dates, }) + + def time_groupby_multi_size(self): + self.df.groupby(['key1', 'key2']).size() + + +class groupby_ngroups_10000_all(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_all(self): + self.df.groupby('value')['timestamp'].all() + + +class groupby_ngroups_10000_any(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_any(self): + self.df.groupby('value')['timestamp'].any() + + +class groupby_ngroups_10000_count(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_count(self): + self.df.groupby('value')['timestamp'].count() + + +class groupby_ngroups_10000_cumcount(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_cumcount(self): + self.df.groupby('value')['timestamp'].cumcount() + + +class groupby_ngroups_10000_cummax(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_cummax(self): + self.df.groupby('value')['timestamp'].cummax() + + +class groupby_ngroups_10000_cummin(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_cummin(self): + self.df.groupby('value')['timestamp'].cummin() + + +class groupby_ngroups_10000_cumprod(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_cumprod(self): + self.df.groupby('value')['timestamp'].cumprod() + + +class groupby_ngroups_10000_cumsum(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_cumsum(self): + self.df.groupby('value')['timestamp'].cumsum() + + +class groupby_ngroups_10000_describe(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_describe(self): + self.df.groupby('value')['timestamp'].describe() + + +class groupby_ngroups_10000_diff(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_diff(self): + self.df.groupby('value')['timestamp'].diff() + + +class groupby_ngroups_10000_first(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_first(self): + self.df.groupby('value')['timestamp'].first() + + +class groupby_ngroups_10000_head(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_head(self): + self.df.groupby('value')['timestamp'].head() + + +class groupby_ngroups_10000_last(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_last(self): + self.df.groupby('value')['timestamp'].last() + + +class groupby_ngroups_10000_mad(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_mad(self): + self.df.groupby('value')['timestamp'].mad() + + +class groupby_ngroups_10000_max(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_max(self): + self.df.groupby('value')['timestamp'].max() + + +class groupby_ngroups_10000_mean(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_mean(self): + self.df.groupby('value')['timestamp'].mean() + + +class groupby_ngroups_10000_median(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_median(self): + self.df.groupby('value')['timestamp'].median() + + +class groupby_ngroups_10000_min(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_min(self): + self.df.groupby('value')['timestamp'].min() + + +class groupby_ngroups_10000_nunique(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_nunique(self): + self.df.groupby('value')['timestamp'].nunique() + + +class groupby_ngroups_10000_pct_change(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_pct_change(self): + self.df.groupby('value')['timestamp'].pct_change() + + +class groupby_ngroups_10000_prod(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_prod(self): + self.df.groupby('value')['timestamp'].prod() + + +class groupby_ngroups_10000_rank(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_rank(self): + self.df.groupby('value')['timestamp'].rank() + + +class groupby_ngroups_10000_sem(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_sem(self): + self.df.groupby('value')['timestamp'].sem() + + +class groupby_ngroups_10000_size(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_size(self): + self.df.groupby('value')['timestamp'].size() + + +class groupby_ngroups_10000_skew(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_skew(self): + self.df.groupby('value')['timestamp'].skew() + + +class groupby_ngroups_10000_std(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_std(self): + self.df.groupby('value')['timestamp'].std() + + +class groupby_ngroups_10000_sum(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_sum(self): + self.df.groupby('value')['timestamp'].sum() + + +class groupby_ngroups_10000_tail(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_tail(self): + self.df.groupby('value')['timestamp'].tail() + + +class groupby_ngroups_10000_unique(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_unique(self): + self.df.groupby('value')['timestamp'].unique() + + +class groupby_ngroups_10000_value_counts(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_value_counts(self): + self.df.groupby('value')['timestamp'].value_counts() + + +class groupby_ngroups_10000_var(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 10000 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_10000_var(self): + self.df.groupby('value')['timestamp'].var() + + +class groupby_ngroups_100_all(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_all(self): + self.df.groupby('value')['timestamp'].all() + + +class groupby_ngroups_100_any(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_any(self): + self.df.groupby('value')['timestamp'].any() + + +class groupby_ngroups_100_count(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_count(self): + self.df.groupby('value')['timestamp'].count() + + +class groupby_ngroups_100_cumcount(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_cumcount(self): + self.df.groupby('value')['timestamp'].cumcount() + + +class groupby_ngroups_100_cummax(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_cummax(self): + self.df.groupby('value')['timestamp'].cummax() + + +class groupby_ngroups_100_cummin(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_cummin(self): + self.df.groupby('value')['timestamp'].cummin() + + +class groupby_ngroups_100_cumprod(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_cumprod(self): + self.df.groupby('value')['timestamp'].cumprod() + + +class groupby_ngroups_100_cumsum(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_cumsum(self): + self.df.groupby('value')['timestamp'].cumsum() + + +class groupby_ngroups_100_describe(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_describe(self): + self.df.groupby('value')['timestamp'].describe() + + +class groupby_ngroups_100_diff(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_diff(self): + self.df.groupby('value')['timestamp'].diff() + + +class groupby_ngroups_100_first(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_first(self): + self.df.groupby('value')['timestamp'].first() + + +class groupby_ngroups_100_head(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_head(self): + self.df.groupby('value')['timestamp'].head() + + +class groupby_ngroups_100_last(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_last(self): + self.df.groupby('value')['timestamp'].last() + + +class groupby_ngroups_100_mad(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_mad(self): + self.df.groupby('value')['timestamp'].mad() + + +class groupby_ngroups_100_max(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_max(self): + self.df.groupby('value')['timestamp'].max() + + +class groupby_ngroups_100_mean(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_mean(self): + self.df.groupby('value')['timestamp'].mean() + + +class groupby_ngroups_100_median(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_median(self): + self.df.groupby('value')['timestamp'].median() + + +class groupby_ngroups_100_min(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_min(self): + self.df.groupby('value')['timestamp'].min() + + +class groupby_ngroups_100_nunique(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_nunique(self): + self.df.groupby('value')['timestamp'].nunique() + + +class groupby_ngroups_100_pct_change(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_pct_change(self): + self.df.groupby('value')['timestamp'].pct_change() + + +class groupby_ngroups_100_prod(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_prod(self): + self.df.groupby('value')['timestamp'].prod() + + +class groupby_ngroups_100_rank(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_rank(self): + self.df.groupby('value')['timestamp'].rank() + + +class groupby_ngroups_100_sem(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_sem(self): + self.df.groupby('value')['timestamp'].sem() + + +class groupby_ngroups_100_size(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_size(self): + self.df.groupby('value')['timestamp'].size() + + +class groupby_ngroups_100_skew(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_skew(self): + self.df.groupby('value')['timestamp'].skew() + + +class groupby_ngroups_100_std(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_std(self): + self.df.groupby('value')['timestamp'].std() + + +class groupby_ngroups_100_sum(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_sum(self): + self.df.groupby('value')['timestamp'].sum() + + +class groupby_ngroups_100_tail(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_tail(self): + self.df.groupby('value')['timestamp'].tail() + + +class groupby_ngroups_100_unique(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_unique(self): + self.df.groupby('value')['timestamp'].unique() + + +class groupby_ngroups_100_value_counts(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_value_counts(self): + self.df.groupby('value')['timestamp'].value_counts() + + +class groupby_ngroups_100_var(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.ngroups = 100 + self.size = (self.ngroups * 2) + self.rng = np.arange(self.ngroups) + self.df = DataFrame(dict(timestamp=self.rng.take(np.random.randint(0, self.ngroups, size=self.size)), value=np.random.randint(0, self.size, size=self.size))) + + def time_groupby_ngroups_100_var(self): + self.df.groupby('value')['timestamp'].var() + + +class groupby_nth_datetimes_any(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame({'a': date_range('1/1/2011', periods=100000, freq='s'), 'b': range(100000), }) + + def time_groupby_nth_datetimes_any(self): + self.df.groupby('b').nth(0, dropna='all') + + +class groupby_nth_datetimes_none(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame({'a': date_range('1/1/2011', periods=100000, freq='s'), 'b': range(100000), }) + + def time_groupby_nth_datetimes_none(self): + self.df.groupby('b').nth(0) + + +class groupby_nth_float32_any(object): + goal_time = 0.2 + + def setup(self): + self.labels = np.arange(10000).repeat(10) + self.data = Series(randn(len(self.labels))) + self.data[::3] = np.nan + self.data[1::3] = np.nan + self.data2 = Series(randn(len(self.labels)), dtype='float32') + self.data2[::3] = np.nan + self.data2[1::3] = np.nan + self.labels = self.labels.take(np.random.permutation(len(self.labels))) + + def time_groupby_nth_float32_any(self): + self.data2.groupby(self.labels).nth(0, dropna='all') + + +class groupby_nth_float32_none(object): + goal_time = 0.2 + + def setup(self): + self.labels = np.arange(10000).repeat(10) + self.data = Series(randn(len(self.labels))) + self.data[::3] = np.nan + self.data[1::3] = np.nan + self.data2 = Series(randn(len(self.labels)), dtype='float32') + self.data2[::3] = np.nan + self.data2[1::3] = np.nan + self.labels = self.labels.take(np.random.permutation(len(self.labels))) + + def time_groupby_nth_float32_none(self): + self.data2.groupby(self.labels).nth(0) + + +class groupby_nth_float64_any(object): + goal_time = 0.2 + + def setup(self): + self.labels = np.arange(10000).repeat(10) + self.data = Series(randn(len(self.labels))) + self.data[::3] = np.nan + self.data[1::3] = np.nan + self.data2 = Series(randn(len(self.labels)), dtype='float32') + self.data2[::3] = np.nan + self.data2[1::3] = np.nan + self.labels = self.labels.take(np.random.permutation(len(self.labels))) + + def time_groupby_nth_float64_any(self): + self.data.groupby(self.labels).nth(0, dropna='all') + + +class groupby_nth_float64_none(object): + goal_time = 0.2 + + def setup(self): + self.labels = np.arange(10000).repeat(10) + self.data = Series(randn(len(self.labels))) + self.data[::3] = np.nan + self.data[1::3] = np.nan + self.data2 = Series(randn(len(self.labels)), dtype='float32') + self.data2[::3] = np.nan + self.data2[1::3] = np.nan + self.labels = self.labels.take(np.random.permutation(len(self.labels))) + + def time_groupby_nth_float64_none(self): + self.data.groupby(self.labels).nth(0) + + +class groupby_nth_object_any(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame({'a': (['foo'] * 100000), 'b': range(100000), }) + + def time_groupby_nth_object_any(self): + self.df.groupby('b').nth(0, dropna='any') + + +class groupby_nth_object_none(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame({'a': (['foo'] * 100000), 'b': range(100000), }) + + def time_groupby_nth_object_none(self): + self.df.groupby('b').nth(0) + + +class groupby_pivot_table(object): + goal_time = 0.2 + + def setup(self): + self.fac1 = np.array(['A', 'B', 'C'], dtype='O') + self.fac2 = np.array(['one', 'two'], dtype='O') + self.ind1 = np.random.randint(0, 3, size=100000) + self.ind2 = np.random.randint(0, 2, size=100000) + self.df = DataFrame({'key1': self.fac1.take(self.ind1), 'key2': self.fac2.take(self.ind2), 'key3': self.fac2.take(self.ind2), 'value1': np.random.randn(100000), 'value2': np.random.randn(100000), 'value3': np.random.randn(100000), }) + + def time_groupby_pivot_table(self): + self.df.pivot_table(index='key1', columns=['key2', 'key3']) + + +class groupby_series_nth_any(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randint(1, 100, (10000, 2))) + + def time_groupby_series_nth_any(self): + self.df[1].groupby(self.df[0]).nth(0, dropna='any') + + +class groupby_series_nth_none(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randint(1, 100, (10000, 2))) + + def time_groupby_series_nth_none(self): + self.df[1].groupby(self.df[0]).nth(0) + + +class groupby_series_simple_cython(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.ngroups = 100 + + def get_test_data(ngroups=100, n=self.N): + self.unique_groups = range(self.ngroups) + self.arr = np.asarray(np.tile(self.unique_groups, (n / self.ngroups)), dtype=object) + if (len(self.arr) < n): + self.arr = np.asarray((list(self.arr) + self.unique_groups[:(n - len(self.arr))]), dtype=object) + random.shuffle(self.arr) + return self.arr + self.df = DataFrame({'key1': get_test_data(ngroups=self.ngroups), 'key2': get_test_data(ngroups=self.ngroups), 'data1': np.random.randn(self.N), 'data2': np.random.randn(self.N), }) + + def f(): + self.df.groupby(['key1', 'key2']).agg((lambda x: x.values.sum())) + self.simple_series = Series(np.random.randn(self.N)) + self.key1 = self.df['key1'] + + def time_groupby_series_simple_cython(self): + self.df.groupby('key1').rank(pct=True) + + +class groupby_simple_compress_timing(object): + goal_time = 0.2 + + def setup(self): + self.data = np.random.randn(1000000, 2) + self.labels = np.random.randint(0, 1000, size=1000000) + self.df = DataFrame(self.data) + + def time_groupby_simple_compress_timing(self): + self.df.groupby(self.labels).mean() + + +class groupby_sum_booleans(object): + goal_time = 0.2 + + def setup(self): + self.N = 500 + self.df = DataFrame({'ii': range(self.N), 'bb': [True for x in range(self.N)], }) + + def time_groupby_sum_booleans(self): + self.df.groupby('ii').sum() + + +class groupby_sum_multiindex(object): + goal_time = 0.2 + + def setup(self): + self.N = 50 + self.df = DataFrame({'A': (range(self.N) * 2), 'B': range((self.N * 2)), 'C': 1, }).set_index(['A', 'B']) + + def time_groupby_sum_multiindex(self): + self.df.groupby(level=[0, 1]).sum() + + +class groupby_transform(object): + goal_time = 0.2 + + def setup(self): + self.n_dates = 400 + self.n_securities = 250 + self.n_columns = 3 + self.share_na = 0.1 + self.dates = date_range('1997-12-31', periods=self.n_dates, freq='B') + self.dates = Index(map((lambda x: (((x.year * 10000) + (x.month * 100)) + x.day)), self.dates)) + self.secid_min = int('10000000', 16) + self.secid_max = int('F0000000', 16) + self.step = ((self.secid_max - self.secid_min) // (self.n_securities - 1)) + self.security_ids = map((lambda x: hex(x)[2:10].upper()), range(self.secid_min, (self.secid_max + 1), self.step)) + self.data_index = MultiIndex(levels=[self.dates.values, self.security_ids], labels=[[i for i in xrange(self.n_dates) for _ in xrange(self.n_securities)], (range(self.n_securities) * self.n_dates)], names=['date', 'security_id']) + self.n_data = len(self.data_index) + self.columns = Index(['factor{}'.format(i) for i in xrange(1, (self.n_columns + 1))]) + self.data = DataFrame(np.random.randn(self.n_data, self.n_columns), index=self.data_index, columns=self.columns) + self.step = int((self.n_data * self.share_na)) + for column_index in xrange(self.n_columns): + self.index = column_index + while (self.index < self.n_data): + self.data.set_value(self.data_index[self.index], self.columns[column_index], np.nan) + self.index += self.step + self.f_fillna = (lambda x: x.fillna(method='pad')) + + def time_groupby_transform(self): + self.data.groupby(level='security_id').transform(self.f_fillna) + + +class groupby_transform_multi_key1(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(2718281) + self.n = 20000 + self.df = DataFrame(np.random.randint(1, self.n, (self.n, 3)), columns=['jim', 'joe', 'jolie']) + + def time_groupby_transform_multi_key1(self): + self.df.groupby(['jim', 'joe'])['jolie'].transform('max') + + +class groupby_transform_multi_key2(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(2718281) + self.n = 20000 + self.df = DataFrame(np.random.randint(1, self.n, (self.n, 3)), columns=['jim', 'joe', 'jolie']) + self.df['jim'] = self.df['joe'] + + def time_groupby_transform_multi_key2(self): + self.df.groupby(['jim', 'joe'])['jolie'].transform('max') + + +class groupby_transform_multi_key3(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(2718281) + self.n = 200000 + self.df = DataFrame(np.random.randint(1, (self.n / 10), (self.n, 3)), columns=['jim', 'joe', 'jolie']) + + def time_groupby_transform_multi_key3(self): + self.df.groupby(['jim', 'joe'])['jolie'].transform('max') + + +class groupby_transform_multi_key4(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(2718281) + self.n = 200000 + self.df = DataFrame(np.random.randint(1, (self.n / 10), (self.n, 3)), columns=['jim', 'joe', 'jolie']) + self.df['jim'] = self.df['joe'] + + def time_groupby_transform_multi_key4(self): + self.df.groupby(['jim', 'joe'])['jolie'].transform('max') + + +class groupby_transform_series(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(0) + self.N = 120000 + self.N_TRANSITIONS = 1400 + self.transition_points = np.random.permutation(np.arange(self.N))[:self.N_TRANSITIONS] + self.transition_points.sort() + self.transitions = np.zeros((self.N,), dtype=np.bool) + self.transitions[self.transition_points] = True + self.g = self.transitions.cumsum() + self.df = DataFrame({'signal': np.random.rand(self.N), }) + + def time_groupby_transform_series(self): + self.df['signal'].groupby(self.g).transform(np.mean) + + +class groupby_transform_series2(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(0) + self.df = DataFrame({'id': (np.arange(100000) / 3), 'val': np.random.randn(100000), }) + + def time_groupby_transform_series2(self): + self.df.groupby('id')['val'].transform(np.mean) + + +class groupby_transform_ufunc(object): + goal_time = 0.2 + + def setup(self): + self.n_dates = 400 + self.n_securities = 250 + self.n_columns = 3 + self.share_na = 0.1 + self.dates = date_range('1997-12-31', periods=self.n_dates, freq='B') + self.dates = Index(map((lambda x: (((x.year * 10000) + (x.month * 100)) + x.day)), self.dates)) + self.secid_min = int('10000000', 16) + self.secid_max = int('F0000000', 16) + self.step = ((self.secid_max - self.secid_min) // (self.n_securities - 1)) + self.security_ids = map((lambda x: hex(x)[2:10].upper()), range(self.secid_min, (self.secid_max + 1), self.step)) + self.data_index = MultiIndex(levels=[self.dates.values, self.security_ids], labels=[[i for i in xrange(self.n_dates) for _ in xrange(self.n_securities)], (range(self.n_securities) * self.n_dates)], names=['date', 'security_id']) + self.n_data = len(self.data_index) + self.columns = Index(['factor{}'.format(i) for i in xrange(1, (self.n_columns + 1))]) + self.data = DataFrame(np.random.randn(self.n_data, self.n_columns), index=self.data_index, columns=self.columns) + self.step = int((self.n_data * self.share_na)) + for column_index in xrange(self.n_columns): + self.index = column_index + while (self.index < self.n_data): + self.data.set_value(self.data_index[self.index], self.columns[column_index], np.nan) + self.index += self.step + self.f_fillna = (lambda x: x.fillna(method='pad')) + + def time_groupby_transform_ufunc(self): + self.data.groupby(level='date').transform(np.max) + + +class series_value_counts_int64(object): + goal_time = 0.2 + + def setup(self): + self.s = Series(np.random.randint(0, 1000, size=100000)) + + def time_series_value_counts_int64(self): + self.s.value_counts() + + +class series_value_counts_strings(object): + goal_time = 0.2 + + def setup(self): + self.K = 1000 + self.N = 100000 + self.uniques = tm.makeStringIndex(self.K).values + self.s = Series(np.tile(self.uniques, (self.N // self.K))) + + def time_series_value_counts_strings(self): + self.s.value_counts() \ No newline at end of file diff --git a/asv_bench/benchmarks/hdfstore_bench.py b/asv_bench/benchmarks/hdfstore_bench.py new file mode 100644 index 0000000000000..9e36f735f8608 --- /dev/null +++ b/asv_bench/benchmarks/hdfstore_bench.py @@ -0,0 +1,351 @@ +from pandas_vb_common import * +import os + + +class query_store_table(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.h5' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.index = date_range('1/1/2000', periods=25000) + self.df = DataFrame({'float1': randn(25000), 'float2': randn(25000), }, index=self.index) + remove(self.f) + self.store = HDFStore(self.f) + self.store.append('df12', self.df) + + def time_query_store_table(self): + self.store.select('df12', [('index', '>', self.df.index[10000]), ('index', '<', self.df.index[15000])]) + + def teardown(self): + self.store.close() + + +class query_store_table_wide(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.h5' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.index = date_range('1/1/2000', periods=25000) + self.df = DataFrame(np.random.randn(25000, 100), index=self.index) + remove(self.f) + self.store = HDFStore(self.f) + self.store.append('df11', self.df) + + def time_query_store_table_wide(self): + self.store.select('df11', [('index', '>', self.df.index[10000]), ('index', '<', self.df.index[15000])]) + + def teardown(self): + self.store.close() + + +class read_store(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.h5' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.index = tm.makeStringIndex(25000) + self.df = DataFrame({'float1': randn(25000), 'float2': randn(25000), }, index=self.index) + remove(self.f) + self.store = HDFStore(self.f) + self.store.put('df1', self.df) + + def time_read_store(self): + self.store.get('df1') + + def teardown(self): + self.store.close() + + +class read_store_mixed(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.h5' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.index = tm.makeStringIndex(25000) + self.df = DataFrame({'float1': randn(25000), 'float2': randn(25000), 'string1': (['foo'] * 25000), 'bool1': ([True] * 25000), 'int1': np.random.randint(0, 250000, size=25000), }, index=self.index) + remove(self.f) + self.store = HDFStore(self.f) + self.store.put('df3', self.df) + + def time_read_store_mixed(self): + self.store.get('df3') + + def teardown(self): + self.store.close() + + +class read_store_table(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.h5' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.index = tm.makeStringIndex(25000) + self.df = DataFrame({'float1': randn(25000), 'float2': randn(25000), }, index=self.index) + remove(self.f) + self.store = HDFStore(self.f) + self.store.append('df7', self.df) + + def time_read_store_table(self): + self.store.select('df7') + + def teardown(self): + self.store.close() + + +class read_store_table_mixed(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.h5' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 10000 + self.index = tm.makeStringIndex(self.N) + self.df = DataFrame({'float1': randn(self.N), 'float2': randn(self.N), 'string1': (['foo'] * self.N), 'bool1': ([True] * self.N), 'int1': np.random.randint(0, self.N, size=self.N), }, index=self.index) + remove(self.f) + self.store = HDFStore(self.f) + self.store.append('df5', self.df) + + def time_read_store_table_mixed(self): + self.store.select('df5') + + def teardown(self): + self.store.close() + + +class read_store_table_panel(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.h5' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.p = Panel(randn(20, 1000, 25), items=[('Item%03d' % i) for i in xrange(20)], major_axis=date_range('1/1/2000', periods=1000), minor_axis=[('E%03d' % i) for i in xrange(25)]) + remove(self.f) + self.store = HDFStore(self.f) + self.store.append('p1', self.p) + + def time_read_store_table_panel(self): + self.store.select('p1') + + def teardown(self): + self.store.close() + + +class read_store_table_wide(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.h5' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.df = DataFrame(np.random.randn(25000, 100)) + remove(self.f) + self.store = HDFStore(self.f) + self.store.append('df9', self.df) + + def time_read_store_table_wide(self): + self.store.select('df9') + + def teardown(self): + self.store.close() + + +class write_store(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.h5' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.index = tm.makeStringIndex(25000) + self.df = DataFrame({'float1': randn(25000), 'float2': randn(25000), }, index=self.index) + remove(self.f) + self.store = HDFStore(self.f) + + def time_write_store(self): + self.store.put('df2', self.df) + + def teardown(self): + self.store.close() + + +class write_store_mixed(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.h5' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.index = tm.makeStringIndex(25000) + self.df = DataFrame({'float1': randn(25000), 'float2': randn(25000), 'string1': (['foo'] * 25000), 'bool1': ([True] * 25000), 'int1': np.random.randint(0, 250000, size=25000), }, index=self.index) + remove(self.f) + self.store = HDFStore(self.f) + + def time_write_store_mixed(self): + self.store.put('df4', self.df) + + def teardown(self): + self.store.close() + + +class write_store_table(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.h5' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.index = tm.makeStringIndex(25000) + self.df = DataFrame({'float1': randn(25000), 'float2': randn(25000), }, index=self.index) + remove(self.f) + self.store = HDFStore(self.f) + + def time_write_store_table(self): + self.store.append('df8', self.df) + + def teardown(self): + self.store.close() + + +class write_store_table_dc(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.h5' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.df = DataFrame(np.random.randn(10000, 10), columns=[('C%03d' % i) for i in xrange(10)]) + remove(self.f) + self.store = HDFStore(self.f) + + def time_write_store_table_dc(self): + self.store.append('df15', self.df, data_columns=True) + + def teardown(self): + self.store.close() + + +class write_store_table_mixed(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.h5' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.index = tm.makeStringIndex(25000) + self.df = DataFrame({'float1': randn(25000), 'float2': randn(25000), 'string1': (['foo'] * 25000), 'bool1': ([True] * 25000), 'int1': np.random.randint(0, 25000, size=25000), }, index=self.index) + remove(self.f) + self.store = HDFStore(self.f) + + def time_write_store_table_mixed(self): + self.store.append('df6', self.df) + + def teardown(self): + self.store.close() + + +class write_store_table_panel(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.h5' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.p = Panel(randn(20, 1000, 25), items=[('Item%03d' % i) for i in xrange(20)], major_axis=date_range('1/1/2000', periods=1000), minor_axis=[('E%03d' % i) for i in xrange(25)]) + remove(self.f) + self.store = HDFStore(self.f) + + def time_write_store_table_panel(self): + self.store.append('p2', self.p) + + def teardown(self): + self.store.close() + + +class write_store_table_wide(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.h5' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.df = DataFrame(np.random.randn(25000, 100)) + remove(self.f) + self.store = HDFStore(self.f) + + def time_write_store_table_wide(self): + self.store.append('df10', self.df) + + def teardown(self): + self.store.close() \ No newline at end of file diff --git a/asv_bench/benchmarks/index_object.py b/asv_bench/benchmarks/index_object.py new file mode 100644 index 0000000000000..9c181c92195ea --- /dev/null +++ b/asv_bench/benchmarks/index_object.py @@ -0,0 +1,292 @@ +from pandas_vb_common import * + + +class datetime_index_intersection(object): + goal_time = 0.2 + + def setup(self): + self.rng = date_range('1/1/2000', periods=10000, freq='T') + self.rng2 = self.rng[:(-1)] + + def time_datetime_index_intersection(self): + self.rng.intersection(self.rng2) + + +class datetime_index_repr(object): + goal_time = 0.2 + + def setup(self): + self.dr = pd.date_range('20000101', freq='D', periods=100000) + + def time_datetime_index_repr(self): + self.dr._is_dates_only + + +class datetime_index_union(object): + goal_time = 0.2 + + def setup(self): + self.rng = date_range('1/1/2000', periods=10000, freq='T') + self.rng2 = self.rng[:(-1)] + + def time_datetime_index_union(self): + self.rng.union(self.rng2) + + +class index_datetime_intersection(object): + goal_time = 0.2 + + def setup(self): + self.rng = DatetimeIndex(start='1/1/2000', periods=10000, freq=datetools.Minute()) + if (self.rng.dtype == object): + self.rng = self.rng.view(Index) + else: + self.rng = self.rng.asobject + self.rng2 = self.rng[:(-1)] + + def time_index_datetime_intersection(self): + self.rng.intersection(self.rng2) + + +class index_datetime_union(object): + goal_time = 0.2 + + def setup(self): + self.rng = DatetimeIndex(start='1/1/2000', periods=10000, freq=datetools.Minute()) + if (self.rng.dtype == object): + self.rng = self.rng.view(Index) + else: + self.rng = self.rng.asobject + self.rng2 = self.rng[:(-1)] + + def time_index_datetime_union(self): + self.rng.union(self.rng2) + + +class index_float64_boolean_indexer(object): + goal_time = 0.2 + + def setup(self): + self.idx = tm.makeFloatIndex(1000000) + self.mask = ((np.arange(self.idx.size) % 3) == 0) + self.series_mask = Series(self.mask) + + def time_index_float64_boolean_indexer(self): + self.idx[self.mask] + + +class index_float64_boolean_series_indexer(object): + goal_time = 0.2 + + def setup(self): + self.idx = tm.makeFloatIndex(1000000) + self.mask = ((np.arange(self.idx.size) % 3) == 0) + self.series_mask = Series(self.mask) + + def time_index_float64_boolean_series_indexer(self): + self.idx[self.series_mask] + + +class index_float64_construct(object): + goal_time = 0.2 + + def setup(self): + self.baseidx = np.arange(1000000.0) + + def time_index_float64_construct(self): + Index(self.baseidx) + + +class index_float64_div(object): + goal_time = 0.2 + + def setup(self): + self.idx = tm.makeFloatIndex(1000000) + self.mask = ((np.arange(self.idx.size) % 3) == 0) + self.series_mask = Series(self.mask) + + def time_index_float64_div(self): + (self.idx / 2) + + +class index_float64_get(object): + goal_time = 0.2 + + def setup(self): + self.idx = tm.makeFloatIndex(1000000) + self.mask = ((np.arange(self.idx.size) % 3) == 0) + self.series_mask = Series(self.mask) + + def time_index_float64_get(self): + self.idx[1] + + +class index_float64_mul(object): + goal_time = 0.2 + + def setup(self): + self.idx = tm.makeFloatIndex(1000000) + self.mask = ((np.arange(self.idx.size) % 3) == 0) + self.series_mask = Series(self.mask) + + def time_index_float64_mul(self): + (self.idx * 2) + + +class index_float64_slice_indexer_basic(object): + goal_time = 0.2 + + def setup(self): + self.idx = tm.makeFloatIndex(1000000) + self.mask = ((np.arange(self.idx.size) % 3) == 0) + self.series_mask = Series(self.mask) + + def time_index_float64_slice_indexer_basic(self): + self.idx[:(-1)] + + +class index_float64_slice_indexer_even(object): + goal_time = 0.2 + + def setup(self): + self.idx = tm.makeFloatIndex(1000000) + self.mask = ((np.arange(self.idx.size) % 3) == 0) + self.series_mask = Series(self.mask) + + def time_index_float64_slice_indexer_even(self): + self.idx[::2] + + +class index_int64_intersection(object): + goal_time = 0.2 + + def setup(self): + self.N = 1000000 + self.options = np.arange(self.N) + self.left = Index(self.options.take(np.random.permutation(self.N)[:(self.N // 2)])) + self.right = Index(self.options.take(np.random.permutation(self.N)[:(self.N // 2)])) + + def time_index_int64_intersection(self): + self.left.intersection(self.right) + + +class index_int64_union(object): + goal_time = 0.2 + + def setup(self): + self.N = 1000000 + self.options = np.arange(self.N) + self.left = Index(self.options.take(np.random.permutation(self.N)[:(self.N // 2)])) + self.right = Index(self.options.take(np.random.permutation(self.N)[:(self.N // 2)])) + + def time_index_int64_union(self): + self.left.union(self.right) + + +class index_str_boolean_indexer(object): + goal_time = 0.2 + + def setup(self): + self.idx = tm.makeStringIndex(1000000) + self.mask = ((np.arange(1000000) % 3) == 0) + self.series_mask = Series(self.mask) + + def time_index_str_boolean_indexer(self): + self.idx[self.mask] + + +class index_str_boolean_series_indexer(object): + goal_time = 0.2 + + def setup(self): + self.idx = tm.makeStringIndex(1000000) + self.mask = ((np.arange(1000000) % 3) == 0) + self.series_mask = Series(self.mask) + + def time_index_str_boolean_series_indexer(self): + self.idx[self.series_mask] + + +class index_str_slice_indexer_basic(object): + goal_time = 0.2 + + def setup(self): + self.idx = tm.makeStringIndex(1000000) + self.mask = ((np.arange(1000000) % 3) == 0) + self.series_mask = Series(self.mask) + + def time_index_str_slice_indexer_basic(self): + self.idx[:(-1)] + + +class index_str_slice_indexer_even(object): + goal_time = 0.2 + + def setup(self): + self.idx = tm.makeStringIndex(1000000) + self.mask = ((np.arange(1000000) % 3) == 0) + self.series_mask = Series(self.mask) + + def time_index_str_slice_indexer_even(self): + self.idx[::2] + + +class multiindex_duplicated(object): + goal_time = 0.2 + + def setup(self): + (n, k) = (200, 5000) + self.levels = [np.arange(n), tm.makeStringIndex(n).values, (1000 + np.arange(n))] + self.labels = [np.random.choice(n, (k * n)) for lev in self.levels] + self.mi = MultiIndex(levels=self.levels, labels=self.labels) + + def time_multiindex_duplicated(self): + self.mi.duplicated() + + +class multiindex_from_product(object): + goal_time = 0.2 + + def setup(self): + self.iterables = [tm.makeStringIndex(10000), xrange(20)] + + def time_multiindex_from_product(self): + MultiIndex.from_product(self.iterables) + + +class multiindex_sortlevel_int64(object): + goal_time = 0.2 + + def setup(self): + self.n = ((((3 * 5) * 7) * 11) * (1 << 10)) + (low, high) = (((-1) << 12), (1 << 12)) + self.f = (lambda k: np.repeat(np.random.randint(low, high, (self.n // k)), k)) + self.i = np.random.permutation(self.n) + self.mi = MultiIndex.from_arrays([self.f(11), self.f(7), self.f(5), self.f(3), self.f(1)])[self.i] + + def time_multiindex_sortlevel_int64(self): + self.mi.sortlevel() + + +class multiindex_with_datetime_level_full(object): + goal_time = 0.2 + + def setup(self): + self.level1 = range(1000) + self.level2 = date_range(start='1/1/2012', periods=100) + self.mi = MultiIndex.from_product([self.level1, self.level2]) + + def time_multiindex_with_datetime_level_full(self): + self.mi.copy().values + + +class multiindex_with_datetime_level_sliced(object): + goal_time = 0.2 + + def setup(self): + self.level1 = range(1000) + self.level2 = date_range(start='1/1/2012', periods=100) + self.mi = MultiIndex.from_product([self.level1, self.level2]) + + def time_multiindex_with_datetime_level_sliced(self): + self.mi[:10].values \ No newline at end of file diff --git a/asv_bench/benchmarks/indexing.py b/asv_bench/benchmarks/indexing.py new file mode 100644 index 0000000000000..e76a87ab881c9 --- /dev/null +++ b/asv_bench/benchmarks/indexing.py @@ -0,0 +1,458 @@ +from pandas_vb_common import * +import pandas.computation.expressions as expr + + +class dataframe_getitem_scalar(object): + goal_time = 0.2 + + def setup(self): + self.index = tm.makeStringIndex(1000) + self.columns = tm.makeStringIndex(30) + self.df = DataFrame(np.random.rand(1000, 30), index=self.index, columns=self.columns) + self.idx = self.index[100] + self.col = self.columns[10] + + def time_dataframe_getitem_scalar(self): + self.df[self.col][self.idx] + + +class datamatrix_getitem_scalar(object): + goal_time = 0.2 + + def setup(self): + try: + self.klass = DataMatrix + except: + self.klass = DataFrame + self.index = tm.makeStringIndex(1000) + self.columns = tm.makeStringIndex(30) + self.df = self.klass(np.random.rand(1000, 30), index=self.index, columns=self.columns) + self.idx = self.index[100] + self.col = self.columns[10] + + def time_datamatrix_getitem_scalar(self): + self.df[self.col][self.idx] + + +class series_get_value(object): + goal_time = 0.2 + + def setup(self): + self.index = tm.makeStringIndex(1000) + self.s = Series(np.random.rand(1000), index=self.index) + self.idx = self.index[100] + + def time_series_get_value(self): + self.s.get_value(self.idx) + + +class time_series_getitem_scalar(object): + goal_time = 0.2 + + def setup(self): + tm.N = 1000 + self.ts = tm.makeTimeSeries() + self.dt = self.ts.index[500] + + def time_time_series_getitem_scalar(self): + self.ts[self.dt] + + +class frame_iloc_big(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(dict(A=(['foo'] * 1000000))) + + def time_frame_iloc_big(self): + self.df.iloc[:100, 0] + + +class frame_iloc_dups(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame({'A': ([0.1] * 3000), 'B': ([1] * 3000), }) + self.idx = (np.array(range(30)) * 99) + self.df2 = DataFrame({'A': ([0.1] * 1000), 'B': ([1] * 1000), }) + self.df2 = concat([self.df2, (2 * self.df2), (3 * self.df2)]) + + def time_frame_iloc_dups(self): + self.df2.iloc[self.idx] + + +class frame_loc_dups(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame({'A': ([0.1] * 3000), 'B': ([1] * 3000), }) + self.idx = (np.array(range(30)) * 99) + self.df2 = DataFrame({'A': ([0.1] * 1000), 'B': ([1] * 1000), }) + self.df2 = concat([self.df2, (2 * self.df2), (3 * self.df2)]) + + def time_frame_loc_dups(self): + self.df2.loc[self.idx] + + +class frame_xs_mi_ix(object): + goal_time = 0.2 + + def setup(self): + self.mi = MultiIndex.from_tuples([(x, y) for x in range(1000) for y in range(1000)]) + self.s = Series(np.random.randn(1000000), index=self.mi) + self.df = DataFrame(self.s) + + def time_frame_xs_mi_ix(self): + self.df.ix[999] + + +class indexing_dataframe_boolean(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(50000, 100)) + self.df2 = DataFrame(np.random.randn(50000, 100)) + + def time_indexing_dataframe_boolean(self): + (self.df > self.df2) + + +class indexing_dataframe_boolean_no_ne(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(50000, 100)) + self.df2 = DataFrame(np.random.randn(50000, 100)) + expr.set_use_numexpr(False) + + def time_indexing_dataframe_boolean_no_ne(self): + (self.df > self.df2) + + def teardown(self): + expr.set_use_numexpr(True) + + +class indexing_dataframe_boolean_rows(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(10000, 4), columns=['A', 'B', 'C', 'D']) + self.indexer = (self.df['B'] > 0) + self.obj_indexer = self.indexer.astype('O') + + def time_indexing_dataframe_boolean_rows(self): + self.df[self.indexer] + + +class indexing_dataframe_boolean_rows_object(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(10000, 4), columns=['A', 'B', 'C', 'D']) + self.indexer = (self.df['B'] > 0) + self.obj_indexer = self.indexer.astype('O') + + def time_indexing_dataframe_boolean_rows_object(self): + self.df[self.obj_indexer] + + +class indexing_dataframe_boolean_st(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(50000, 100)) + self.df2 = DataFrame(np.random.randn(50000, 100)) + expr.set_numexpr_threads(1) + + def time_indexing_dataframe_boolean_st(self): + (self.df > self.df2) + + def teardown(self): + expr.set_numexpr_threads() + + +class indexing_frame_get_value(object): + goal_time = 0.2 + + def setup(self): + self.index = tm.makeStringIndex(1000) + self.columns = tm.makeStringIndex(30) + self.df = DataFrame(np.random.randn(1000, 30), index=self.index, columns=self.columns) + self.idx = self.index[100] + self.col = self.columns[10] + + def time_indexing_frame_get_value(self): + self.df.get_value(self.idx, self.col) + + +class indexing_frame_get_value_ix(object): + goal_time = 0.2 + + def setup(self): + self.index = tm.makeStringIndex(1000) + self.columns = tm.makeStringIndex(30) + self.df = DataFrame(np.random.randn(1000, 30), index=self.index, columns=self.columns) + self.idx = self.index[100] + self.col = self.columns[10] + + def time_indexing_frame_get_value_ix(self): + self.df.ix[(self.idx, self.col)] + + +class indexing_panel_subset(object): + goal_time = 0.2 + + def setup(self): + self.p = Panel(np.random.randn(100, 100, 100)) + self.inds = range(0, 100, 10) + + def time_indexing_panel_subset(self): + self.p.ix[(self.inds, self.inds, self.inds)] + + +class multiindex_slicers(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(1234) + self.idx = pd.IndexSlice + self.n = 100000 + self.mdt = pandas.DataFrame() + self.mdt['A'] = np.random.choice(range(10000, 45000, 1000), self.n) + self.mdt['B'] = np.random.choice(range(10, 400), self.n) + self.mdt['C'] = np.random.choice(range(1, 150), self.n) + self.mdt['D'] = np.random.choice(range(10000, 45000), self.n) + self.mdt['x'] = np.random.choice(range(400), self.n) + self.mdt['y'] = np.random.choice(range(25), self.n) + self.test_A = 25000 + self.test_B = 25 + self.test_C = 40 + self.test_D = 35000 + self.eps_A = 5000 + self.eps_B = 5 + self.eps_C = 5 + self.eps_D = 5000 + self.mdt2 = self.mdt.set_index(['A', 'B', 'C', 'D']).sortlevel() + + def time_multiindex_slicers(self): + self.mdt2.loc[self.idx[(self.test_A - self.eps_A):(self.test_A + self.eps_A), (self.test_B - self.eps_B):(self.test_B + self.eps_B), (self.test_C - self.eps_C):(self.test_C + self.eps_C), (self.test_D - self.eps_D):(self.test_D + self.eps_D)], :] + + +class series_getitem_array(object): + goal_time = 0.2 + + def setup(self): + self.s = Series(np.random.rand(1000000)) + + def time_series_getitem_array(self): + self.s[np.arange(10000)] + + +class series_getitem_label_slice(object): + goal_time = 0.2 + + def setup(self): + self.index = tm.makeStringIndex(1000000) + self.s = Series(np.random.rand(1000000), index=self.index) + self.lbl = self.s.index[800000] + + def time_series_getitem_label_slice(self): + self.s[:self.lbl] + + +class series_getitem_list_like(object): + goal_time = 0.2 + + def setup(self): + self.s = Series(np.random.rand(1000000)) + + def time_series_getitem_list_like(self): + self.s[[800000]] + + +class series_getitem_pos_slice(object): + goal_time = 0.2 + + def setup(self): + self.index = tm.makeStringIndex(1000000) + self.s = Series(np.random.rand(1000000), index=self.index) + + def time_series_getitem_pos_slice(self): + self.s[:800000] + + +class series_getitem_scalar(object): + goal_time = 0.2 + + def setup(self): + self.s = Series(np.random.rand(1000000)) + + def time_series_getitem_scalar(self): + self.s[800000] + + +class series_getitem_slice(object): + goal_time = 0.2 + + def setup(self): + self.s = Series(np.random.rand(1000000)) + + def time_series_getitem_slice(self): + self.s[:800000] + + +class series_iloc_array(object): + goal_time = 0.2 + + def setup(self): + self.s = Series(np.random.rand(1000000)) + + def time_series_iloc_array(self): + self.s.iloc[np.arange(10000)] + + +class series_iloc_list_like(object): + goal_time = 0.2 + + def setup(self): + self.s = Series(np.random.rand(1000000)) + + def time_series_iloc_list_like(self): + self.s.iloc[[800000]] + + +class series_iloc_scalar(object): + goal_time = 0.2 + + def setup(self): + self.s = Series(np.random.rand(1000000)) + + def time_series_iloc_scalar(self): + self.s.iloc[800000] + + +class series_iloc_slice(object): + goal_time = 0.2 + + def setup(self): + self.s = Series(np.random.rand(1000000)) + + def time_series_iloc_slice(self): + self.s.iloc[:800000] + + +class series_ix_array(object): + goal_time = 0.2 + + def setup(self): + self.s = Series(np.random.rand(1000000)) + + def time_series_ix_array(self): + self.s.ix[np.arange(10000)] + + +class series_ix_list_like(object): + goal_time = 0.2 + + def setup(self): + self.s = Series(np.random.rand(1000000)) + + def time_series_ix_list_like(self): + self.s.ix[[800000]] + + +class series_ix_scalar(object): + goal_time = 0.2 + + def setup(self): + self.s = Series(np.random.rand(1000000)) + + def time_series_ix_scalar(self): + self.s.ix[800000] + + +class series_ix_slice(object): + goal_time = 0.2 + + def setup(self): + self.s = Series(np.random.rand(1000000)) + + def time_series_ix_slice(self): + self.s.ix[:800000] + + +class series_loc_array(object): + goal_time = 0.2 + + def setup(self): + self.s = Series(np.random.rand(1000000)) + + def time_series_loc_array(self): + self.s.loc[np.arange(10000)] + + +class series_loc_list_like(object): + goal_time = 0.2 + + def setup(self): + self.s = Series(np.random.rand(1000000)) + + def time_series_loc_list_like(self): + self.s.loc[[800000]] + + +class series_loc_scalar(object): + goal_time = 0.2 + + def setup(self): + self.s = Series(np.random.rand(1000000)) + + def time_series_loc_scalar(self): + self.s.loc[800000] + + +class series_loc_slice(object): + goal_time = 0.2 + + def setup(self): + self.s = Series(np.random.rand(1000000)) + + def time_series_loc_slice(self): + self.s.loc[:800000] + + +class series_xs_mi_ix(object): + goal_time = 0.2 + + def setup(self): + self.mi = MultiIndex.from_tuples([(x, y) for x in range(1000) for y in range(1000)]) + self.s = Series(np.random.randn(1000000), index=self.mi) + + def time_series_xs_mi_ix(self): + self.s.ix[999] + + +class sort_level_one(object): + goal_time = 0.2 + + def setup(self): + self.a = np.repeat(np.arange(100), 1000) + self.b = np.tile(np.arange(1000), 100) + self.midx = MultiIndex.from_arrays([self.a, self.b]) + self.midx = self.midx.take(np.random.permutation(np.arange(100000))) + + def time_sort_level_one(self): + self.midx.sortlevel(1) + + +class sort_level_zero(object): + goal_time = 0.2 + + def setup(self): + self.a = np.repeat(np.arange(100), 1000) + self.b = np.tile(np.arange(1000), 100) + self.midx = MultiIndex.from_arrays([self.a, self.b]) + self.midx = self.midx.take(np.random.permutation(np.arange(100000))) + + def time_sort_level_zero(self): + self.midx.sortlevel(0) \ No newline at end of file diff --git a/asv_bench/benchmarks/inference.py b/asv_bench/benchmarks/inference.py new file mode 100644 index 0000000000000..2addc810a218f --- /dev/null +++ b/asv_bench/benchmarks/inference.py @@ -0,0 +1,138 @@ +from pandas_vb_common import * +import pandas as pd + + +class dtype_infer_datetime64(object): + goal_time = 0.2 + + def setup(self): + self.N = 500000 + self.df_int64 = DataFrame(dict(A=np.arange(self.N, dtype='int64'), B=np.arange(self.N, dtype='int64'))) + self.df_int32 = DataFrame(dict(A=np.arange(self.N, dtype='int32'), B=np.arange(self.N, dtype='int32'))) + self.df_uint32 = DataFrame(dict(A=np.arange(self.N, dtype='uint32'), B=np.arange(self.N, dtype='uint32'))) + self.df_float64 = DataFrame(dict(A=np.arange(self.N, dtype='float64'), B=np.arange(self.N, dtype='float64'))) + self.df_float32 = DataFrame(dict(A=np.arange(self.N, dtype='float32'), B=np.arange(self.N, dtype='float32'))) + self.df_datetime64 = DataFrame(dict(A=pd.to_datetime(np.arange(self.N, dtype='int64'), unit='ms'), B=pd.to_datetime(np.arange(self.N, dtype='int64'), unit='ms'))) + self.df_timedelta64 = DataFrame(dict(A=(self.df_datetime64['A'] - self.df_datetime64['B']), B=self.df_datetime64['B'])) + + def time_dtype_infer_datetime64(self): + (self.df_datetime64['A'] - self.df_datetime64['B']) + + +class dtype_infer_float32(object): + goal_time = 0.2 + + def setup(self): + self.N = 500000 + self.df_int64 = DataFrame(dict(A=np.arange(self.N, dtype='int64'), B=np.arange(self.N, dtype='int64'))) + self.df_int32 = DataFrame(dict(A=np.arange(self.N, dtype='int32'), B=np.arange(self.N, dtype='int32'))) + self.df_uint32 = DataFrame(dict(A=np.arange(self.N, dtype='uint32'), B=np.arange(self.N, dtype='uint32'))) + self.df_float64 = DataFrame(dict(A=np.arange(self.N, dtype='float64'), B=np.arange(self.N, dtype='float64'))) + self.df_float32 = DataFrame(dict(A=np.arange(self.N, dtype='float32'), B=np.arange(self.N, dtype='float32'))) + self.df_datetime64 = DataFrame(dict(A=pd.to_datetime(np.arange(self.N, dtype='int64'), unit='ms'), B=pd.to_datetime(np.arange(self.N, dtype='int64'), unit='ms'))) + self.df_timedelta64 = DataFrame(dict(A=(self.df_datetime64['A'] - self.df_datetime64['B']), B=self.df_datetime64['B'])) + + def time_dtype_infer_float32(self): + (self.df_float32['A'] + self.df_float32['B']) + + +class dtype_infer_float64(object): + goal_time = 0.2 + + def setup(self): + self.N = 500000 + self.df_int64 = DataFrame(dict(A=np.arange(self.N, dtype='int64'), B=np.arange(self.N, dtype='int64'))) + self.df_int32 = DataFrame(dict(A=np.arange(self.N, dtype='int32'), B=np.arange(self.N, dtype='int32'))) + self.df_uint32 = DataFrame(dict(A=np.arange(self.N, dtype='uint32'), B=np.arange(self.N, dtype='uint32'))) + self.df_float64 = DataFrame(dict(A=np.arange(self.N, dtype='float64'), B=np.arange(self.N, dtype='float64'))) + self.df_float32 = DataFrame(dict(A=np.arange(self.N, dtype='float32'), B=np.arange(self.N, dtype='float32'))) + self.df_datetime64 = DataFrame(dict(A=pd.to_datetime(np.arange(self.N, dtype='int64'), unit='ms'), B=pd.to_datetime(np.arange(self.N, dtype='int64'), unit='ms'))) + self.df_timedelta64 = DataFrame(dict(A=(self.df_datetime64['A'] - self.df_datetime64['B']), B=self.df_datetime64['B'])) + + def time_dtype_infer_float64(self): + (self.df_float64['A'] + self.df_float64['B']) + + +class dtype_infer_int32(object): + goal_time = 0.2 + + def setup(self): + self.N = 500000 + self.df_int64 = DataFrame(dict(A=np.arange(self.N, dtype='int64'), B=np.arange(self.N, dtype='int64'))) + self.df_int32 = DataFrame(dict(A=np.arange(self.N, dtype='int32'), B=np.arange(self.N, dtype='int32'))) + self.df_uint32 = DataFrame(dict(A=np.arange(self.N, dtype='uint32'), B=np.arange(self.N, dtype='uint32'))) + self.df_float64 = DataFrame(dict(A=np.arange(self.N, dtype='float64'), B=np.arange(self.N, dtype='float64'))) + self.df_float32 = DataFrame(dict(A=np.arange(self.N, dtype='float32'), B=np.arange(self.N, dtype='float32'))) + self.df_datetime64 = DataFrame(dict(A=pd.to_datetime(np.arange(self.N, dtype='int64'), unit='ms'), B=pd.to_datetime(np.arange(self.N, dtype='int64'), unit='ms'))) + self.df_timedelta64 = DataFrame(dict(A=(self.df_datetime64['A'] - self.df_datetime64['B']), B=self.df_datetime64['B'])) + + def time_dtype_infer_int32(self): + (self.df_int32['A'] + self.df_int32['B']) + + +class dtype_infer_int64(object): + goal_time = 0.2 + + def setup(self): + self.N = 500000 + self.df_int64 = DataFrame(dict(A=np.arange(self.N, dtype='int64'), B=np.arange(self.N, dtype='int64'))) + self.df_int32 = DataFrame(dict(A=np.arange(self.N, dtype='int32'), B=np.arange(self.N, dtype='int32'))) + self.df_uint32 = DataFrame(dict(A=np.arange(self.N, dtype='uint32'), B=np.arange(self.N, dtype='uint32'))) + self.df_float64 = DataFrame(dict(A=np.arange(self.N, dtype='float64'), B=np.arange(self.N, dtype='float64'))) + self.df_float32 = DataFrame(dict(A=np.arange(self.N, dtype='float32'), B=np.arange(self.N, dtype='float32'))) + self.df_datetime64 = DataFrame(dict(A=pd.to_datetime(np.arange(self.N, dtype='int64'), unit='ms'), B=pd.to_datetime(np.arange(self.N, dtype='int64'), unit='ms'))) + self.df_timedelta64 = DataFrame(dict(A=(self.df_datetime64['A'] - self.df_datetime64['B']), B=self.df_datetime64['B'])) + + def time_dtype_infer_int64(self): + (self.df_int64['A'] + self.df_int64['B']) + + +class dtype_infer_timedelta64_1(object): + goal_time = 0.2 + + def setup(self): + self.N = 500000 + self.df_int64 = DataFrame(dict(A=np.arange(self.N, dtype='int64'), B=np.arange(self.N, dtype='int64'))) + self.df_int32 = DataFrame(dict(A=np.arange(self.N, dtype='int32'), B=np.arange(self.N, dtype='int32'))) + self.df_uint32 = DataFrame(dict(A=np.arange(self.N, dtype='uint32'), B=np.arange(self.N, dtype='uint32'))) + self.df_float64 = DataFrame(dict(A=np.arange(self.N, dtype='float64'), B=np.arange(self.N, dtype='float64'))) + self.df_float32 = DataFrame(dict(A=np.arange(self.N, dtype='float32'), B=np.arange(self.N, dtype='float32'))) + self.df_datetime64 = DataFrame(dict(A=pd.to_datetime(np.arange(self.N, dtype='int64'), unit='ms'), B=pd.to_datetime(np.arange(self.N, dtype='int64'), unit='ms'))) + self.df_timedelta64 = DataFrame(dict(A=(self.df_datetime64['A'] - self.df_datetime64['B']), B=self.df_datetime64['B'])) + + def time_dtype_infer_timedelta64_1(self): + (self.df_timedelta64['A'] + self.df_timedelta64['B']) + + +class dtype_infer_timedelta64_2(object): + goal_time = 0.2 + + def setup(self): + self.N = 500000 + self.df_int64 = DataFrame(dict(A=np.arange(self.N, dtype='int64'), B=np.arange(self.N, dtype='int64'))) + self.df_int32 = DataFrame(dict(A=np.arange(self.N, dtype='int32'), B=np.arange(self.N, dtype='int32'))) + self.df_uint32 = DataFrame(dict(A=np.arange(self.N, dtype='uint32'), B=np.arange(self.N, dtype='uint32'))) + self.df_float64 = DataFrame(dict(A=np.arange(self.N, dtype='float64'), B=np.arange(self.N, dtype='float64'))) + self.df_float32 = DataFrame(dict(A=np.arange(self.N, dtype='float32'), B=np.arange(self.N, dtype='float32'))) + self.df_datetime64 = DataFrame(dict(A=pd.to_datetime(np.arange(self.N, dtype='int64'), unit='ms'), B=pd.to_datetime(np.arange(self.N, dtype='int64'), unit='ms'))) + self.df_timedelta64 = DataFrame(dict(A=(self.df_datetime64['A'] - self.df_datetime64['B']), B=self.df_datetime64['B'])) + + def time_dtype_infer_timedelta64_2(self): + (self.df_timedelta64['A'] + self.df_timedelta64['A']) + + +class dtype_infer_uint32(object): + goal_time = 0.2 + + def setup(self): + self.N = 500000 + self.df_int64 = DataFrame(dict(A=np.arange(self.N, dtype='int64'), B=np.arange(self.N, dtype='int64'))) + self.df_int32 = DataFrame(dict(A=np.arange(self.N, dtype='int32'), B=np.arange(self.N, dtype='int32'))) + self.df_uint32 = DataFrame(dict(A=np.arange(self.N, dtype='uint32'), B=np.arange(self.N, dtype='uint32'))) + self.df_float64 = DataFrame(dict(A=np.arange(self.N, dtype='float64'), B=np.arange(self.N, dtype='float64'))) + self.df_float32 = DataFrame(dict(A=np.arange(self.N, dtype='float32'), B=np.arange(self.N, dtype='float32'))) + self.df_datetime64 = DataFrame(dict(A=pd.to_datetime(np.arange(self.N, dtype='int64'), unit='ms'), B=pd.to_datetime(np.arange(self.N, dtype='int64'), unit='ms'))) + self.df_timedelta64 = DataFrame(dict(A=(self.df_datetime64['A'] - self.df_datetime64['B']), B=self.df_datetime64['B'])) + + def time_dtype_infer_uint32(self): + (self.df_uint32['A'] + self.df_uint32['B']) \ No newline at end of file diff --git a/asv_bench/benchmarks/io_bench.py b/asv_bench/benchmarks/io_bench.py new file mode 100644 index 0000000000000..9eee932de8b7c --- /dev/null +++ b/asv_bench/benchmarks/io_bench.py @@ -0,0 +1,135 @@ +from pandas_vb_common import * +from pandas import concat, Timestamp +from StringIO import StringIO + + +class frame_to_csv(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(3000, 30)) + + def time_frame_to_csv(self): + self.df.to_csv('__test__.csv') + + +class frame_to_csv2(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame({'A': range(50000), }) + self.df['B'] = (self.df.A + 1.0) + self.df['C'] = (self.df.A + 2.0) + self.df['D'] = (self.df.A + 3.0) + + def time_frame_to_csv2(self): + self.df.to_csv('__test__.csv') + + +class frame_to_csv_date_formatting(object): + goal_time = 0.2 + + def setup(self): + self.rng = date_range('1/1/2000', periods=1000) + self.data = DataFrame(self.rng, index=self.rng) + + def time_frame_to_csv_date_formatting(self): + self.data.to_csv('__test__.csv', date_format='%Y%m%d') + + +class frame_to_csv_mixed(object): + goal_time = 0.2 + + def setup(self): + + def create_cols(name): + return [('%s%03d' % (name, i)) for i in xrange(5)] + self.df_float = DataFrame(np.random.randn(5000, 5), dtype='float64', columns=create_cols('float')) + self.df_int = DataFrame(np.random.randn(5000, 5), dtype='int64', columns=create_cols('int')) + self.df_bool = DataFrame(True, index=self.df_float.index, columns=create_cols('bool')) + self.df_object = DataFrame('foo', index=self.df_float.index, columns=create_cols('object')) + self.df_dt = DataFrame(Timestamp('20010101'), index=self.df_float.index, columns=create_cols('date')) + self.df_float.ix[30:500, 1:3] = np.nan + self.df = concat([self.df_float, self.df_int, self.df_bool, self.df_object, self.df_dt], axis=1) + + def time_frame_to_csv_mixed(self): + self.df.to_csv('__test__.csv') + + +class read_csv_infer_datetime_format_custom(object): + goal_time = 0.2 + + def setup(self): + self.rng = date_range('1/1/2000', periods=1000) + self.data = '\n'.join(self.rng.map((lambda x: x.strftime('%m/%d/%Y %H:%M:%S.%f')))) + + def time_read_csv_infer_datetime_format_custom(self): + read_csv(StringIO(self.data), header=None, names=['foo'], parse_dates=['foo'], infer_datetime_format=True) + + +class read_csv_infer_datetime_format_iso8601(object): + goal_time = 0.2 + + def setup(self): + self.rng = date_range('1/1/2000', periods=1000) + self.data = '\n'.join(self.rng.map((lambda x: x.strftime('%Y-%m-%d %H:%M:%S')))) + + def time_read_csv_infer_datetime_format_iso8601(self): + read_csv(StringIO(self.data), header=None, names=['foo'], parse_dates=['foo'], infer_datetime_format=True) + + +class read_csv_infer_datetime_format_ymd(object): + goal_time = 0.2 + + def setup(self): + self.rng = date_range('1/1/2000', periods=1000) + self.data = '\n'.join(self.rng.map((lambda x: x.strftime('%Y%m%d')))) + + def time_read_csv_infer_datetime_format_ymd(self): + read_csv(StringIO(self.data), header=None, names=['foo'], parse_dates=['foo'], infer_datetime_format=True) + + +class read_csv_skiprows(object): + goal_time = 0.2 + + def setup(self): + self.index = tm.makeStringIndex(20000) + self.df = DataFrame({'float1': randn(20000), 'float2': randn(20000), 'string1': (['foo'] * 20000), 'bool1': ([True] * 20000), 'int1': np.random.randint(0, 200000, size=20000), }, index=self.index) + self.df.to_csv('__test__.csv') + + def time_read_csv_skiprows(self): + read_csv('__test__.csv', skiprows=10000) + + +class read_csv_standard(object): + goal_time = 0.2 + + def setup(self): + self.index = tm.makeStringIndex(10000) + self.df = DataFrame({'float1': randn(10000), 'float2': randn(10000), 'string1': (['foo'] * 10000), 'bool1': ([True] * 10000), 'int1': np.random.randint(0, 100000, size=10000), }, index=self.index) + self.df.to_csv('__test__.csv') + + def time_read_csv_standard(self): + read_csv('__test__.csv') + + +class read_parse_dates_iso8601(object): + goal_time = 0.2 + + def setup(self): + self.rng = date_range('1/1/2000', periods=1000) + self.data = '\n'.join(self.rng.map((lambda x: x.strftime('%Y-%m-%d %H:%M:%S')))) + + def time_read_parse_dates_iso8601(self): + read_csv(StringIO(self.data), header=None, names=['foo'], parse_dates=['foo']) + + +class write_csv_standard(object): + goal_time = 0.2 + + def setup(self): + self.index = tm.makeStringIndex(10000) + self.df = DataFrame({'float1': randn(10000), 'float2': randn(10000), 'string1': (['foo'] * 10000), 'bool1': ([True] * 10000), 'int1': np.random.randint(0, 100000, size=10000), }, index=self.index) + + def time_write_csv_standard(self): + self.df.to_csv('__test__.csv') \ No newline at end of file diff --git a/asv_bench/benchmarks/io_sql.py b/asv_bench/benchmarks/io_sql.py new file mode 100644 index 0000000000000..e75e691b61c96 --- /dev/null +++ b/asv_bench/benchmarks/io_sql.py @@ -0,0 +1,215 @@ +from pandas_vb_common import * +from sqlalchemy import create_engine +import sqlite3 +import sqlalchemy + + +class sql_datetime_read_and_parse_sqlalchemy(object): + goal_time = 0.2 + + def setup(self): + self.engine = create_engine('sqlite:///:memory:') + self.con = sqlite3.connect(':memory:') + self.df = DataFrame({'float': randn(10000), 'datetime': date_range('2000-01-01', periods=10000, freq='s'), }) + self.df['datetime_string'] = self.df['datetime'].map(str) + self.df.to_sql('test_type', self.engine, if_exists='replace') + self.df[['float', 'datetime_string']].to_sql('test_type', self.con, if_exists='replace') + + def time_sql_datetime_read_and_parse_sqlalchemy(self): + read_sql_table('test_type', self.engine, columns=['datetime_string'], parse_dates=['datetime_string']) + + +class sql_datetime_read_as_native_sqlalchemy(object): + goal_time = 0.2 + + def setup(self): + self.engine = create_engine('sqlite:///:memory:') + self.con = sqlite3.connect(':memory:') + self.df = DataFrame({'float': randn(10000), 'datetime': date_range('2000-01-01', periods=10000, freq='s'), }) + self.df['datetime_string'] = self.df['datetime'].map(str) + self.df.to_sql('test_type', self.engine, if_exists='replace') + self.df[['float', 'datetime_string']].to_sql('test_type', self.con, if_exists='replace') + + def time_sql_datetime_read_as_native_sqlalchemy(self): + read_sql_table('test_type', self.engine, columns=['datetime']) + + +class sql_datetime_write_sqlalchemy(object): + goal_time = 0.2 + + def setup(self): + self.engine = create_engine('sqlite:///:memory:') + self.con = sqlite3.connect(':memory:') + self.df = DataFrame({'float': randn(10000), 'string': (['foo'] * 10000), 'bool': ([True] * 10000), 'datetime': date_range('2000-01-01', periods=10000, freq='s'), }) + self.df.loc[1000:3000, 'float'] = np.nan + + def time_sql_datetime_write_sqlalchemy(self): + self.df[['datetime']].to_sql('test_datetime', self.engine, if_exists='replace') + + +class sql_float_read_query_fallback(object): + goal_time = 0.2 + + def setup(self): + self.engine = create_engine('sqlite:///:memory:') + self.con = sqlite3.connect(':memory:') + self.df = DataFrame({'float': randn(10000), 'datetime': date_range('2000-01-01', periods=10000, freq='s'), }) + self.df['datetime_string'] = self.df['datetime'].map(str) + self.df.to_sql('test_type', self.engine, if_exists='replace') + self.df[['float', 'datetime_string']].to_sql('test_type', self.con, if_exists='replace') + + def time_sql_float_read_query_fallback(self): + read_sql_query('SELECT float FROM test_type', self.con) + + +class sql_float_read_query_sqlalchemy(object): + goal_time = 0.2 + + def setup(self): + self.engine = create_engine('sqlite:///:memory:') + self.con = sqlite3.connect(':memory:') + self.df = DataFrame({'float': randn(10000), 'datetime': date_range('2000-01-01', periods=10000, freq='s'), }) + self.df['datetime_string'] = self.df['datetime'].map(str) + self.df.to_sql('test_type', self.engine, if_exists='replace') + self.df[['float', 'datetime_string']].to_sql('test_type', self.con, if_exists='replace') + + def time_sql_float_read_query_sqlalchemy(self): + read_sql_query('SELECT float FROM test_type', self.engine) + + +class sql_float_read_table_sqlalchemy(object): + goal_time = 0.2 + + def setup(self): + self.engine = create_engine('sqlite:///:memory:') + self.con = sqlite3.connect(':memory:') + self.df = DataFrame({'float': randn(10000), 'datetime': date_range('2000-01-01', periods=10000, freq='s'), }) + self.df['datetime_string'] = self.df['datetime'].map(str) + self.df.to_sql('test_type', self.engine, if_exists='replace') + self.df[['float', 'datetime_string']].to_sql('test_type', self.con, if_exists='replace') + + def time_sql_float_read_table_sqlalchemy(self): + read_sql_table('test_type', self.engine, columns=['float']) + + +class sql_float_write_fallback(object): + goal_time = 0.2 + + def setup(self): + self.engine = create_engine('sqlite:///:memory:') + self.con = sqlite3.connect(':memory:') + self.df = DataFrame({'float': randn(10000), 'string': (['foo'] * 10000), 'bool': ([True] * 10000), 'datetime': date_range('2000-01-01', periods=10000, freq='s'), }) + self.df.loc[1000:3000, 'float'] = np.nan + + def time_sql_float_write_fallback(self): + self.df[['float']].to_sql('test_float', self.con, if_exists='replace') + + +class sql_float_write_sqlalchemy(object): + goal_time = 0.2 + + def setup(self): + self.engine = create_engine('sqlite:///:memory:') + self.con = sqlite3.connect(':memory:') + self.df = DataFrame({'float': randn(10000), 'string': (['foo'] * 10000), 'bool': ([True] * 10000), 'datetime': date_range('2000-01-01', periods=10000, freq='s'), }) + self.df.loc[1000:3000, 'float'] = np.nan + + def time_sql_float_write_sqlalchemy(self): + self.df[['float']].to_sql('test_float', self.engine, if_exists='replace') + + +class sql_read_query_fallback(object): + goal_time = 0.2 + + def setup(self): + self.engine = create_engine('sqlite:///:memory:') + self.con = sqlite3.connect(':memory:') + self.index = tm.makeStringIndex(10000) + self.df = DataFrame({'float1': randn(10000), 'float2': randn(10000), 'string1': (['foo'] * 10000), 'bool1': ([True] * 10000), 'int1': np.random.randint(0, 100000, size=10000), }, index=self.index) + self.df.to_sql('test2', self.engine, if_exists='replace') + self.df.to_sql('test2', self.con, if_exists='replace') + + def time_sql_read_query_fallback(self): + read_sql_query('SELECT * FROM test2', self.con) + + +class sql_read_query_sqlalchemy(object): + goal_time = 0.2 + + def setup(self): + self.engine = create_engine('sqlite:///:memory:') + self.con = sqlite3.connect(':memory:') + self.index = tm.makeStringIndex(10000) + self.df = DataFrame({'float1': randn(10000), 'float2': randn(10000), 'string1': (['foo'] * 10000), 'bool1': ([True] * 10000), 'int1': np.random.randint(0, 100000, size=10000), }, index=self.index) + self.df.to_sql('test2', self.engine, if_exists='replace') + self.df.to_sql('test2', self.con, if_exists='replace') + + def time_sql_read_query_sqlalchemy(self): + read_sql_query('SELECT * FROM test2', self.engine) + + +class sql_read_table_sqlalchemy(object): + goal_time = 0.2 + + def setup(self): + self.engine = create_engine('sqlite:///:memory:') + self.con = sqlite3.connect(':memory:') + self.index = tm.makeStringIndex(10000) + self.df = DataFrame({'float1': randn(10000), 'float2': randn(10000), 'string1': (['foo'] * 10000), 'bool1': ([True] * 10000), 'int1': np.random.randint(0, 100000, size=10000), }, index=self.index) + self.df.to_sql('test2', self.engine, if_exists='replace') + self.df.to_sql('test2', self.con, if_exists='replace') + + def time_sql_read_table_sqlalchemy(self): + read_sql_table('test2', self.engine) + + +class sql_string_write_fallback(object): + goal_time = 0.2 + + def setup(self): + self.engine = create_engine('sqlite:///:memory:') + self.con = sqlite3.connect(':memory:') + self.df = DataFrame({'float': randn(10000), 'string': (['foo'] * 10000), 'bool': ([True] * 10000), 'datetime': date_range('2000-01-01', periods=10000, freq='s'), }) + self.df.loc[1000:3000, 'float'] = np.nan + + def time_sql_string_write_fallback(self): + self.df[['string']].to_sql('test_string', self.con, if_exists='replace') + + +class sql_string_write_sqlalchemy(object): + goal_time = 0.2 + + def setup(self): + self.engine = create_engine('sqlite:///:memory:') + self.con = sqlite3.connect(':memory:') + self.df = DataFrame({'float': randn(10000), 'string': (['foo'] * 10000), 'bool': ([True] * 10000), 'datetime': date_range('2000-01-01', periods=10000, freq='s'), }) + self.df.loc[1000:3000, 'float'] = np.nan + + def time_sql_string_write_sqlalchemy(self): + self.df[['string']].to_sql('test_string', self.engine, if_exists='replace') + + +class sql_write_fallback(object): + goal_time = 0.2 + + def setup(self): + self.engine = create_engine('sqlite:///:memory:') + self.con = sqlite3.connect(':memory:') + self.index = tm.makeStringIndex(10000) + self.df = DataFrame({'float1': randn(10000), 'float2': randn(10000), 'string1': (['foo'] * 10000), 'bool1': ([True] * 10000), 'int1': np.random.randint(0, 100000, size=10000), }, index=self.index) + + def time_sql_write_fallback(self): + self.df.to_sql('test1', self.con, if_exists='replace') + + +class sql_write_sqlalchemy(object): + goal_time = 0.2 + + def setup(self): + self.engine = create_engine('sqlite:///:memory:') + self.con = sqlite3.connect(':memory:') + self.index = tm.makeStringIndex(10000) + self.df = DataFrame({'float1': randn(10000), 'float2': randn(10000), 'string1': (['foo'] * 10000), 'bool1': ([True] * 10000), 'int1': np.random.randint(0, 100000, size=10000), }, index=self.index) + + def time_sql_write_sqlalchemy(self): + self.df.to_sql('test1', self.engine, if_exists='replace') \ No newline at end of file diff --git a/asv_bench/benchmarks/join_merge.py b/asv_bench/benchmarks/join_merge.py new file mode 100644 index 0000000000000..08ae439e8fd5d --- /dev/null +++ b/asv_bench/benchmarks/join_merge.py @@ -0,0 +1,359 @@ +from pandas_vb_common import * + + +class append_frame_single_homogenous(object): + goal_time = 0.2 + + def setup(self): + self.df1 = pd.DataFrame(np.random.randn(10000, 4), columns=['A', 'B', 'C', 'D']) + self.df2 = self.df1.copy() + self.df2.index = np.arange(10000, 20000) + self.mdf1 = self.df1.copy() + self.mdf1['obj1'] = 'bar' + self.mdf1['obj2'] = 'bar' + self.mdf1['int1'] = 5 + try: + self.mdf1.consolidate(inplace=True) + except: + pass + self.mdf2 = self.mdf1.copy() + self.mdf2.index = self.df2.index + + def time_append_frame_single_homogenous(self): + self.df1.append(self.df2) + + +class append_frame_single_mixed(object): + goal_time = 0.2 + + def setup(self): + self.df1 = pd.DataFrame(np.random.randn(10000, 4), columns=['A', 'B', 'C', 'D']) + self.df2 = self.df1.copy() + self.df2.index = np.arange(10000, 20000) + self.mdf1 = self.df1.copy() + self.mdf1['obj1'] = 'bar' + self.mdf1['obj2'] = 'bar' + self.mdf1['int1'] = 5 + try: + self.mdf1.consolidate(inplace=True) + except: + pass + self.mdf2 = self.mdf1.copy() + self.mdf2.index = self.df2.index + + def time_append_frame_single_mixed(self): + self.mdf1.append(self.mdf2) + + +class concat_empty_frames1(object): + goal_time = 0.2 + + def setup(self): + self.df = pd.DataFrame(dict(A=range(10000)), index=date_range('20130101', periods=10000, freq='s')) + self.empty = pd.DataFrame() + + def time_concat_empty_frames1(self): + concat([self.df, self.empty]) + + +class concat_empty_frames2(object): + goal_time = 0.2 + + def setup(self): + self.df = pd.DataFrame(dict(A=range(10000)), index=date_range('20130101', periods=10000, freq='s')) + self.empty = pd.DataFrame() + + def time_concat_empty_frames2(self): + concat([self.empty, self.df]) + + +class concat_series_axis1(object): + goal_time = 0.2 + + def setup(self): + self.n = 1000 + self.indices = tm.makeStringIndex(1000) + self.s = Series(self.n, index=self.indices) + self.pieces = [self.s[i:(- i)] for i in range(1, 10)] + self.pieces = (self.pieces * 50) + + def time_concat_series_axis1(self): + concat(self.pieces, axis=1) + + +class concat_small_frames(object): + goal_time = 0.2 + + def setup(self): + self.df = pd.DataFrame(randn(5, 4)) + + def time_concat_small_frames(self): + concat(([self.df] * 1000)) + + +class i8merge(object): + goal_time = 0.2 + + def setup(self): + (low, high, n) = (((-1) << 10), (1 << 10), (1 << 20)) + self.left = pd.DataFrame(np.random.randint(low, high, (n, 7)), columns=list('ABCDEFG')) + self.left['left'] = self.left.sum(axis=1) + self.i = np.random.permutation(len(self.left)) + self.right = self.left.iloc[self.i].copy() + self.right.columns = (self.right.columns[:(-1)].tolist() + ['right']) + self.right.index = np.arange(len(self.right)) + self.right['right'] *= (-1) + + def time_i8merge(self): + merge(self.left, self.right, how='outer') + + +class join_dataframe_index_multi(object): + goal_time = 0.2 + + def setup(self): + self.level1 = tm.makeStringIndex(10).values + self.level2 = tm.makeStringIndex(1000).values + self.label1 = np.arange(10).repeat(1000) + self.label2 = np.tile(np.arange(1000), 10) + self.key1 = np.tile(self.level1.take(self.label1), 10) + self.key2 = np.tile(self.level2.take(self.label2), 10) + self.shuf = np.arange(100000) + random.shuffle(self.shuf) + try: + self.index2 = MultiIndex(levels=[self.level1, self.level2], labels=[self.label1, self.label2]) + self.index3 = MultiIndex(levels=[np.arange(10), np.arange(100), np.arange(100)], labels=[np.arange(10).repeat(10000), np.tile(np.arange(100).repeat(100), 10), np.tile(np.tile(np.arange(100), 100), 10)]) + self.df_multi = DataFrame(np.random.randn(len(self.index2), 4), index=self.index2, columns=['A', 'B', 'C', 'D']) + except: + pass + try: + self.DataFrame = DataMatrix + except: + pass + self.df = pd.DataFrame({'data1': np.random.randn(100000), 'data2': np.random.randn(100000), 'key1': self.key1, 'key2': self.key2, }) + self.df_key1 = pd.DataFrame(np.random.randn(len(self.level1), 4), index=self.level1, columns=['A', 'B', 'C', 'D']) + self.df_key2 = pd.DataFrame(np.random.randn(len(self.level2), 4), index=self.level2, columns=['A', 'B', 'C', 'D']) + self.df_shuf = self.df.reindex(self.df.index[self.shuf]) + + def time_join_dataframe_index_multi(self): + self.df.join(self.df_multi, on=['key1', 'key2']) + + +class join_dataframe_index_single_key_bigger(object): + goal_time = 0.2 + + def setup(self): + self.level1 = tm.makeStringIndex(10).values + self.level2 = tm.makeStringIndex(1000).values + self.label1 = np.arange(10).repeat(1000) + self.label2 = np.tile(np.arange(1000), 10) + self.key1 = np.tile(self.level1.take(self.label1), 10) + self.key2 = np.tile(self.level2.take(self.label2), 10) + self.shuf = np.arange(100000) + random.shuffle(self.shuf) + try: + self.index2 = MultiIndex(levels=[self.level1, self.level2], labels=[self.label1, self.label2]) + self.index3 = MultiIndex(levels=[np.arange(10), np.arange(100), np.arange(100)], labels=[np.arange(10).repeat(10000), np.tile(np.arange(100).repeat(100), 10), np.tile(np.tile(np.arange(100), 100), 10)]) + self.df_multi = DataFrame(np.random.randn(len(self.index2), 4), index=self.index2, columns=['A', 'B', 'C', 'D']) + except: + pass + try: + self.DataFrame = DataMatrix + except: + pass + self.df = pd.DataFrame({'data1': np.random.randn(100000), 'data2': np.random.randn(100000), 'key1': self.key1, 'key2': self.key2, }) + self.df_key1 = pd.DataFrame(np.random.randn(len(self.level1), 4), index=self.level1, columns=['A', 'B', 'C', 'D']) + self.df_key2 = pd.DataFrame(np.random.randn(len(self.level2), 4), index=self.level2, columns=['A', 'B', 'C', 'D']) + self.df_shuf = self.df.reindex(self.df.index[self.shuf]) + + def time_join_dataframe_index_single_key_bigger(self): + self.df.join(self.df_key2, on='key2') + + +class join_dataframe_index_single_key_bigger_sort(object): + goal_time = 0.2 + + def setup(self): + self.level1 = tm.makeStringIndex(10).values + self.level2 = tm.makeStringIndex(1000).values + self.label1 = np.arange(10).repeat(1000) + self.label2 = np.tile(np.arange(1000), 10) + self.key1 = np.tile(self.level1.take(self.label1), 10) + self.key2 = np.tile(self.level2.take(self.label2), 10) + self.shuf = np.arange(100000) + random.shuffle(self.shuf) + try: + self.index2 = MultiIndex(levels=[self.level1, self.level2], labels=[self.label1, self.label2]) + self.index3 = MultiIndex(levels=[np.arange(10), np.arange(100), np.arange(100)], labels=[np.arange(10).repeat(10000), np.tile(np.arange(100).repeat(100), 10), np.tile(np.tile(np.arange(100), 100), 10)]) + self.df_multi = DataFrame(np.random.randn(len(self.index2), 4), index=self.index2, columns=['A', 'B', 'C', 'D']) + except: + pass + try: + self.DataFrame = DataMatrix + except: + pass + self.df = pd.DataFrame({'data1': np.random.randn(100000), 'data2': np.random.randn(100000), 'key1': self.key1, 'key2': self.key2, }) + self.df_key1 = pd.DataFrame(np.random.randn(len(self.level1), 4), index=self.level1, columns=['A', 'B', 'C', 'D']) + self.df_key2 = pd.DataFrame(np.random.randn(len(self.level2), 4), index=self.level2, columns=['A', 'B', 'C', 'D']) + self.df_shuf = self.df.reindex(self.df.index[self.shuf]) + + def time_join_dataframe_index_single_key_bigger_sort(self): + self.df_shuf.join(self.df_key2, on='key2', sort=True) + + +class join_dataframe_index_single_key_small(object): + goal_time = 0.2 + + def setup(self): + self.level1 = tm.makeStringIndex(10).values + self.level2 = tm.makeStringIndex(1000).values + self.label1 = np.arange(10).repeat(1000) + self.label2 = np.tile(np.arange(1000), 10) + self.key1 = np.tile(self.level1.take(self.label1), 10) + self.key2 = np.tile(self.level2.take(self.label2), 10) + self.shuf = np.arange(100000) + random.shuffle(self.shuf) + try: + self.index2 = MultiIndex(levels=[self.level1, self.level2], labels=[self.label1, self.label2]) + self.index3 = MultiIndex(levels=[np.arange(10), np.arange(100), np.arange(100)], labels=[np.arange(10).repeat(10000), np.tile(np.arange(100).repeat(100), 10), np.tile(np.tile(np.arange(100), 100), 10)]) + self.df_multi = DataFrame(np.random.randn(len(self.index2), 4), index=self.index2, columns=['A', 'B', 'C', 'D']) + except: + pass + try: + self.DataFrame = DataMatrix + except: + pass + self.df = pd.DataFrame({'data1': np.random.randn(100000), 'data2': np.random.randn(100000), 'key1': self.key1, 'key2': self.key2, }) + self.df_key1 = pd.DataFrame(np.random.randn(len(self.level1), 4), index=self.level1, columns=['A', 'B', 'C', 'D']) + self.df_key2 = pd.DataFrame(np.random.randn(len(self.level2), 4), index=self.level2, columns=['A', 'B', 'C', 'D']) + self.df_shuf = self.df.reindex(self.df.index[self.shuf]) + + def time_join_dataframe_index_single_key_small(self): + self.df.join(self.df_key1, on='key1') + + +class join_dataframe_integer_2key(object): + goal_time = 0.2 + + def setup(self): + self.df = pd.DataFrame({'key1': np.tile(np.arange(500).repeat(10), 2), 'key2': np.tile(np.arange(250).repeat(10), 4), 'value': np.random.randn(10000), }) + self.df2 = pd.DataFrame({'key1': np.arange(500), 'value2': randn(500), }) + self.df3 = self.df[:5000] + + def time_join_dataframe_integer_2key(self): + merge(self.df, self.df3) + + +class join_dataframe_integer_key(object): + goal_time = 0.2 + + def setup(self): + self.df = pd.DataFrame({'key1': np.tile(np.arange(500).repeat(10), 2), 'key2': np.tile(np.arange(250).repeat(10), 4), 'value': np.random.randn(10000), }) + self.df2 = pd.DataFrame({'key1': np.arange(500), 'value2': randn(500), }) + self.df3 = self.df[:5000] + + def time_join_dataframe_integer_key(self): + merge(self.df, self.df2, on='key1') + + +class join_non_unique_equal(object): + goal_time = 0.2 + + def setup(self): + self.date_index = date_range('01-Jan-2013', '23-Jan-2013', freq='T') + self.daily_dates = self.date_index.to_period('D').to_timestamp('S', 'S') + self.fracofday = (self.date_index.view(np.ndarray) - self.daily_dates.view(np.ndarray)) + self.fracofday = (self.fracofday.astype('timedelta64[ns]').astype(np.float64) / 86400000000000.0) + self.fracofday = TimeSeries(self.fracofday, self.daily_dates) + self.index = date_range(self.date_index.min().to_period('A').to_timestamp('D', 'S'), self.date_index.max().to_period('A').to_timestamp('D', 'E'), freq='D') + self.temp = TimeSeries(1.0, self.index) + + def time_join_non_unique_equal(self): + (self.fracofday * self.temp[self.fracofday.index]) + + +class left_outer_join_index(object): + goal_time = 0.2 + + def setup(self): + np.random.seed(2718281) + self.n = 50000 + self.left = pd.DataFrame(np.random.randint(1, (self.n / 500), (self.n, 2)), columns=['jim', 'joe']) + self.right = pd.DataFrame(np.random.randint(1, (self.n / 500), (self.n, 2)), columns=['jolie', 'jolia']).set_index('jolie') + + def time_left_outer_join_index(self): + self.left.join(self.right, on='jim') + + +class merge_2intkey_nosort(object): + goal_time = 0.2 + + def setup(self): + self.N = 10000 + self.indices = tm.makeStringIndex(self.N).values + self.indices2 = tm.makeStringIndex(self.N).values + self.key = np.tile(self.indices[:8000], 10) + self.key2 = np.tile(self.indices2[:8000], 10) + self.left = pd.DataFrame({'key': self.key, 'key2': self.key2, 'value': np.random.randn(80000), }) + self.right = pd.DataFrame({'key': self.indices[2000:], 'key2': self.indices2[2000:], 'value2': np.random.randn(8000), }) + + def time_merge_2intkey_nosort(self): + merge(self.left, self.right, sort=False) + + +class merge_2intkey_sort(object): + goal_time = 0.2 + + def setup(self): + self.N = 10000 + self.indices = tm.makeStringIndex(self.N).values + self.indices2 = tm.makeStringIndex(self.N).values + self.key = np.tile(self.indices[:8000], 10) + self.key2 = np.tile(self.indices2[:8000], 10) + self.left = pd.DataFrame({'key': self.key, 'key2': self.key2, 'value': np.random.randn(80000), }) + self.right = pd.DataFrame({'key': self.indices[2000:], 'key2': self.indices2[2000:], 'value2': np.random.randn(8000), }) + + def time_merge_2intkey_sort(self): + merge(self.left, self.right, sort=True) + + +class series_align_int64_index(object): + goal_time = 0.2 + + def setup(self): + self.n = 1000000 + + def sample(values, k): + self.sampler = np.random.permutation(len(values)) + return values.take(self.sampler[:k]) + self.sz = 500000 + self.rng = np.arange(0, 10000000000000, 10000000) + self.stamps = (np.datetime64(datetime.now()).view('i8') + self.rng) + self.idx1 = np.sort(sample(self.stamps, self.sz)) + self.idx2 = np.sort(sample(self.stamps, self.sz)) + self.ts1 = Series(np.random.randn(self.sz), self.idx1) + self.ts2 = Series(np.random.randn(self.sz), self.idx2) + + def time_series_align_int64_index(self): + (self.ts1 + self.ts2) + + +class series_align_left_monotonic(object): + goal_time = 0.2 + + def setup(self): + self.n = 1000000 + + def sample(values, k): + self.sampler = np.random.permutation(len(values)) + return values.take(self.sampler[:k]) + self.sz = 500000 + self.rng = np.arange(0, 10000000000000, 10000000) + self.stamps = (np.datetime64(datetime.now()).view('i8') + self.rng) + self.idx1 = np.sort(sample(self.stamps, self.sz)) + self.idx2 = np.sort(sample(self.stamps, self.sz)) + self.ts1 = Series(np.random.randn(self.sz), self.idx1) + self.ts2 = Series(np.random.randn(self.sz), self.idx2) + + def time_series_align_left_monotonic(self): + self.ts1.align(self.ts2, join='left') \ No newline at end of file diff --git a/asv_bench/benchmarks/miscellaneous.py b/asv_bench/benchmarks/miscellaneous.py new file mode 100644 index 0000000000000..b9c02c85fb096 --- /dev/null +++ b/asv_bench/benchmarks/miscellaneous.py @@ -0,0 +1,30 @@ +from pandas_vb_common import * +from pandas.util.decorators import cache_readonly + + +class match_strings(object): + goal_time = 0.2 + + def setup(self): + self.uniques = tm.makeStringIndex(1000).values + self.all = self.uniques.repeat(10) + + def time_match_strings(self): + match(self.all, self.uniques) + + +class misc_cache_readonly(object): + goal_time = 0.2 + + def setup(self): + + + class Foo: + + @cache_readonly + def prop(self): + return 5 + self.obj = Foo() + + def time_misc_cache_readonly(self): + self.obj.prop \ No newline at end of file diff --git a/asv_bench/benchmarks/packers.py b/asv_bench/benchmarks/packers.py new file mode 100644 index 0000000000000..81fa7c2238d16 --- /dev/null +++ b/asv_bench/benchmarks/packers.py @@ -0,0 +1,857 @@ +from numpy.random import randint +import pandas as pd +from collections import OrderedDict +from pandas.compat import BytesIO +import sqlite3 +from pandas_vb_common import * +import os +from sqlalchemy import create_engine +import numpy as np +from random import randrange +from pandas.core import common as com + + +class packers_read_csv(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + self.df.to_csv(self.f) + + def time_packers_read_csv(self): + pd.read_csv(self.f) + + +class packers_read_excel(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + self.bio = BytesIO() + self.writer = pd.io.excel.ExcelWriter(self.bio, engine='xlsxwriter') + self.df[:2000].to_excel(self.writer) + self.writer.save() + + def time_packers_read_excel(self): + self.bio.seek(0) + pd.read_excel(self.bio) + + +class packers_read_hdf_store(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + self.df2.to_hdf(self.f, 'df') + + def time_packers_read_hdf_store(self): + pd.read_hdf(self.f, 'df') + + +class packers_read_hdf_table(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + self.df2.to_hdf(self.f, 'df', format='table') + + def time_packers_read_hdf_table(self): + pd.read_hdf(self.f, 'df') + + +class packers_read_json(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + self.df.to_json(self.f, orient='split') + self.df.index = np.arange(self.N) + + def time_packers_read_json(self): + pd.read_json(self.f, orient='split') + + +class packers_read_json_date_index(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + self.df.to_json(self.f, orient='split') + + def time_packers_read_json_date_index(self): + pd.read_json(self.f, orient='split') + + +class packers_read_pack(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + self.df2.to_msgpack(self.f) + + def time_packers_read_pack(self): + pd.read_msgpack(self.f) + + +class packers_read_pickle(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + self.df2.to_pickle(self.f) + + def time_packers_read_pickle(self): + pd.read_pickle(self.f) + + +class packers_read_sql(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + self.engine = create_engine('sqlite:///:memory:') + self.df2.to_sql('table', self.engine, if_exists='replace') + + def time_packers_read_sql(self): + pd.read_sql_table('table', self.engine) + + +class packers_read_stata(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + self.df.to_stata(self.f, {'index': 'tc', }) + + def time_packers_read_stata(self): + pd.read_stata(self.f) + + +class packers_read_stata_with_validation(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + self.df['int8_'] = [randint(np.iinfo(np.int8).min, (np.iinfo(np.int8).max - 27)) for _ in range(self.N)] + self.df['int16_'] = [randint(np.iinfo(np.int16).min, (np.iinfo(np.int16).max - 27)) for _ in range(self.N)] + self.df['int32_'] = [randint(np.iinfo(np.int32).min, (np.iinfo(np.int32).max - 27)) for _ in range(self.N)] + self.df['float32_'] = np.array(randn(self.N), dtype=np.float32) + self.df.to_stata(self.f, {'index': 'tc', }) + + def time_packers_read_stata_with_validation(self): + pd.read_stata(self.f) + + +class packers_write_csv(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + + def time_packers_write_csv(self): + self.df.to_csv(self.f) + + def teardown(self): + remove(self.f) + + +class packers_write_excel_openpyxl(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + self.bio = BytesIO() + + def time_packers_write_excel_openpyxl(self): + self.bio.seek(0) + self.writer = pd.io.excel.ExcelWriter(self.bio, engine='openpyxl') + self.df[:2000].to_excel(self.writer) + self.writer.save() + + +class packers_write_excel_xlsxwriter(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + self.bio = BytesIO() + + def time_packers_write_excel_xlsxwriter(self): + self.bio.seek(0) + self.writer = pd.io.excel.ExcelWriter(self.bio, engine='xlsxwriter') + self.df[:2000].to_excel(self.writer) + self.writer.save() + + +class packers_write_excel_xlwt(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + self.bio = BytesIO() + + def time_packers_write_excel_xlwt(self): + self.bio.seek(0) + self.writer = pd.io.excel.ExcelWriter(self.bio, engine='xlwt') + self.df[:2000].to_excel(self.writer) + self.writer.save() + + +class packers_write_hdf_store(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + + def time_packers_write_hdf_store(self): + self.df2.to_hdf(self.f, 'df') + + def teardown(self): + remove(self.f) + + +class packers_write_hdf_table(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + + def time_packers_write_hdf_table(self): + self.df2.to_hdf(self.f, 'df', table=True) + + def teardown(self): + remove(self.f) + + +class packers_write_json(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + self.df.index = np.arange(self.N) + + def time_packers_write_json(self): + self.df.to_json(self.f, orient='split') + + def teardown(self): + remove(self.f) + + +class packers_write_json_T(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + self.df.index = np.arange(self.N) + + def time_packers_write_json_T(self): + self.df.to_json(self.f, orient='columns') + + def teardown(self): + remove(self.f) + + +class packers_write_json_date_index(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + + def time_packers_write_json_date_index(self): + self.df.to_json(self.f, orient='split') + + def teardown(self): + remove(self.f) + + +class packers_write_json_mixed_delta_int_tstamp(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + self.cols = [(lambda i: ('{0}_timedelta'.format(i), [pd.Timedelta(('%d seconds' % randrange(1000000.0))) for _ in range(self.N)])), (lambda i: ('{0}_int'.format(i), randint(100000000.0, size=self.N))), (lambda i: ('{0}_timestamp'.format(i), [pd.Timestamp((1418842918083256000 + randrange(1000000000.0, 1e+18, 200))) for _ in range(self.N)]))] + self.df_mixed = DataFrame(OrderedDict([self.cols[(i % len(self.cols))](i) for i in range(self.C)]), index=self.index) + + def time_packers_write_json_mixed_delta_int_tstamp(self): + self.df_mixed.to_json(self.f, orient='split') + + def teardown(self): + remove(self.f) + + +class packers_write_json_mixed_float_int(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + self.cols = [(lambda i: ('{0}_float'.format(i), randn(self.N))), (lambda i: ('{0}_int'.format(i), randint(100000000.0, size=self.N)))] + self.df_mixed = DataFrame(OrderedDict([self.cols[(i % len(self.cols))](i) for i in range(self.C)]), index=self.index) + + def time_packers_write_json_mixed_float_int(self): + self.df_mixed.to_json(self.f, orient='index') + + def teardown(self): + remove(self.f) + + +class packers_write_json_mixed_float_int_T(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + self.cols = [(lambda i: ('{0}_float'.format(i), randn(self.N))), (lambda i: ('{0}_int'.format(i), randint(100000000.0, size=self.N)))] + self.df_mixed = DataFrame(OrderedDict([self.cols[(i % len(self.cols))](i) for i in range(self.C)]), index=self.index) + + def time_packers_write_json_mixed_float_int_T(self): + self.df_mixed.to_json(self.f, orient='columns') + + def teardown(self): + remove(self.f) + + +class packers_write_json_mixed_float_int_str(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + self.cols = [(lambda i: ('{0}_float'.format(i), randn(self.N))), (lambda i: ('{0}_int'.format(i), randint(100000000.0, size=self.N))), (lambda i: ('{0}_str'.format(i), [('%08x' % randrange((16 ** 8))) for _ in range(self.N)]))] + self.df_mixed = DataFrame(OrderedDict([self.cols[(i % len(self.cols))](i) for i in range(self.C)]), index=self.index) + + def time_packers_write_json_mixed_float_int_str(self): + self.df_mixed.to_json(self.f, orient='split') + + def teardown(self): + remove(self.f) + + +class packers_write_pack(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + + def time_packers_write_pack(self): + self.df2.to_msgpack(self.f) + + def teardown(self): + remove(self.f) + + +class packers_write_pickle(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + + def time_packers_write_pickle(self): + self.df2.to_pickle(self.f) + + def teardown(self): + remove(self.f) + + +class packers_write_sql(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + self.engine = create_engine('sqlite:///:memory:') + + def time_packers_write_sql(self): + self.df2.to_sql('table', self.engine, if_exists='replace') + + +class packers_write_stata(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + self.df.to_stata(self.f, {'index': 'tc', }) + + def time_packers_write_stata(self): + self.df.to_stata(self.f, {'index': 'tc', }) + + def teardown(self): + remove(self.f) + + +class packers_write_stata_with_validation(object): + goal_time = 0.2 + + def setup(self): + self.f = '__test__.msg' + + def remove(f): + try: + os.remove(self.f) + except: + pass + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.N = 100000 + self.C = 5 + self.index = date_range('20000101', periods=self.N, freq='H') + self.df2 = DataFrame(dict([('float{0}'.format(i), randn(self.N)) for i in range(self.C)]), index=self.index) + self.df2['object'] = [('%08x' % randrange((16 ** 8))) for _ in range(self.N)] + remove(self.f) + self.df['int8_'] = [randint(np.iinfo(np.int8).min, (np.iinfo(np.int8).max - 27)) for _ in range(self.N)] + self.df['int16_'] = [randint(np.iinfo(np.int16).min, (np.iinfo(np.int16).max - 27)) for _ in range(self.N)] + self.df['int32_'] = [randint(np.iinfo(np.int32).min, (np.iinfo(np.int32).max - 27)) for _ in range(self.N)] + self.df['float32_'] = np.array(randn(self.N), dtype=np.float32) + self.df.to_stata(self.f, {'index': 'tc', }) + + def time_packers_write_stata_with_validation(self): + self.df.to_stata(self.f, {'index': 'tc', }) + + def teardown(self): + remove(self.f) \ No newline at end of file diff --git a/asv_bench/benchmarks/pandas_vb_common.py b/asv_bench/benchmarks/pandas_vb_common.py new file mode 120000 index 0000000000000..6e2e449a4c00a --- /dev/null +++ b/asv_bench/benchmarks/pandas_vb_common.py @@ -0,0 +1 @@ +../../vb_suite/pandas_vb_common.py \ No newline at end of file diff --git a/asv_bench/benchmarks/panel_ctor.py b/asv_bench/benchmarks/panel_ctor.py new file mode 100644 index 0000000000000..c755cb122a0bf --- /dev/null +++ b/asv_bench/benchmarks/panel_ctor.py @@ -0,0 +1,64 @@ +from pandas_vb_common import * + + +class panel_from_dict_all_different_indexes(object): + goal_time = 0.2 + + def setup(self): + self.data_frames = {} + self.start = datetime(1990, 1, 1) + self.end = datetime(2012, 1, 1) + for x in xrange(100): + self.end += timedelta(days=1) + self.dr = np.asarray(date_range(self.start, self.end)) + self.df = DataFrame({'a': ([0] * len(self.dr)), 'b': ([1] * len(self.dr)), 'c': ([2] * len(self.dr)), }, index=self.dr) + self.data_frames[x] = self.df + + def time_panel_from_dict_all_different_indexes(self): + Panel.from_dict(self.data_frames) + + +class panel_from_dict_equiv_indexes(object): + goal_time = 0.2 + + def setup(self): + self.data_frames = {} + for x in xrange(100): + self.dr = np.asarray(DatetimeIndex(start=datetime(1990, 1, 1), end=datetime(2012, 1, 1), freq=datetools.Day(1))) + self.df = DataFrame({'a': ([0] * len(self.dr)), 'b': ([1] * len(self.dr)), 'c': ([2] * len(self.dr)), }, index=self.dr) + self.data_frames[x] = self.df + + def time_panel_from_dict_equiv_indexes(self): + Panel.from_dict(self.data_frames) + + +class panel_from_dict_same_index(object): + goal_time = 0.2 + + def setup(self): + self.dr = np.asarray(DatetimeIndex(start=datetime(1990, 1, 1), end=datetime(2012, 1, 1), freq=datetools.Day(1))) + self.data_frames = {} + for x in xrange(100): + self.df = DataFrame({'a': ([0] * len(self.dr)), 'b': ([1] * len(self.dr)), 'c': ([2] * len(self.dr)), }, index=self.dr) + self.data_frames[x] = self.df + + def time_panel_from_dict_same_index(self): + Panel.from_dict(self.data_frames) + + +class panel_from_dict_two_different_indexes(object): + goal_time = 0.2 + + def setup(self): + self.data_frames = {} + self.start = datetime(1990, 1, 1) + self.end = datetime(2012, 1, 1) + for x in xrange(100): + if (x == 50): + self.end += timedelta(days=1) + self.dr = np.asarray(date_range(self.start, self.end)) + self.df = DataFrame({'a': ([0] * len(self.dr)), 'b': ([1] * len(self.dr)), 'c': ([2] * len(self.dr)), }, index=self.dr) + self.data_frames[x] = self.df + + def time_panel_from_dict_two_different_indexes(self): + Panel.from_dict(self.data_frames) \ No newline at end of file diff --git a/asv_bench/benchmarks/panel_methods.py b/asv_bench/benchmarks/panel_methods.py new file mode 100644 index 0000000000000..4145b68dca997 --- /dev/null +++ b/asv_bench/benchmarks/panel_methods.py @@ -0,0 +1,56 @@ +from pandas_vb_common import * + + +class panel_pct_change_items(object): + goal_time = 0.2 + + def setup(self): + self.index = date_range(start='2000', freq='D', periods=1000) + self.panel = Panel(np.random.randn(100, len(self.index), 1000)) + + def time_panel_pct_change_items(self): + self.panel.pct_change(1, axis='items') + + +class panel_pct_change_major(object): + goal_time = 0.2 + + def setup(self): + self.index = date_range(start='2000', freq='D', periods=1000) + self.panel = Panel(np.random.randn(100, len(self.index), 1000)) + + def time_panel_pct_change_major(self): + self.panel.pct_change(1, axis='major') + + +class panel_pct_change_minor(object): + goal_time = 0.2 + + def setup(self): + self.index = date_range(start='2000', freq='D', periods=1000) + self.panel = Panel(np.random.randn(100, len(self.index), 1000)) + + def time_panel_pct_change_minor(self): + self.panel.pct_change(1, axis='minor') + + +class panel_shift(object): + goal_time = 0.2 + + def setup(self): + self.index = date_range(start='2000', freq='D', periods=1000) + self.panel = Panel(np.random.randn(100, len(self.index), 1000)) + + def time_panel_shift(self): + self.panel.shift(1) + + +class panel_shift_minor(object): + goal_time = 0.2 + + def setup(self): + self.index = date_range(start='2000', freq='D', periods=1000) + self.panel = Panel(np.random.randn(100, len(self.index), 1000)) + + def time_panel_shift_minor(self): + self.panel.shift(1, axis='minor') \ No newline at end of file diff --git a/asv_bench/benchmarks/parser_vb.py b/asv_bench/benchmarks/parser_vb.py new file mode 100644 index 0000000000000..46167dc2bb33c --- /dev/null +++ b/asv_bench/benchmarks/parser_vb.py @@ -0,0 +1,109 @@ +from cStringIO import StringIO +from pandas_vb_common import * +import os +from pandas import read_csv, read_table + + +class read_csv_comment2(object): + goal_time = 0.2 + + def setup(self): + self.data = ['A,B,C'] + self.data = (self.data + (['1,2,3 # comment'] * 100000)) + self.data = '\n'.join(self.data) + + def time_read_csv_comment2(self): + read_csv(StringIO(self.data), comment='#') + + +class read_csv_default_converter(object): + goal_time = 0.2 + + def setup(self): + self.data = '0.1213700904466425978256438611,0.0525708283766902484401839501,0.4174092731488769913994474336\n 0.4096341697147408700274695547,0.1587830198973579909349496119,0.1292545832485494372576795285\n 0.8323255650024565799327547210,0.9694902427379478160318626578,0.6295047811546814475747169126\n 0.4679375305798131323697930383,0.2963942381834381301075609371,0.5268936082160610157032465394\n 0.6685382761849776311890991564,0.6721207066140679753374342908,0.6519975277021627935170045020\n ' + self.data = (self.data * 200) + + def time_read_csv_default_converter(self): + read_csv(StringIO(self.data), sep=',', header=None, float_precision=None) + + +class read_csv_precise_converter(object): + goal_time = 0.2 + + def setup(self): + self.data = '0.1213700904466425978256438611,0.0525708283766902484401839501,0.4174092731488769913994474336\n 0.4096341697147408700274695547,0.1587830198973579909349496119,0.1292545832485494372576795285\n 0.8323255650024565799327547210,0.9694902427379478160318626578,0.6295047811546814475747169126\n 0.4679375305798131323697930383,0.2963942381834381301075609371,0.5268936082160610157032465394\n 0.6685382761849776311890991564,0.6721207066140679753374342908,0.6519975277021627935170045020\n ' + self.data = (self.data * 200) + + def time_read_csv_precise_converter(self): + read_csv(StringIO(self.data), sep=',', header=None, float_precision='high') + + +class read_csv_roundtrip_converter(object): + goal_time = 0.2 + + def setup(self): + self.data = '0.1213700904466425978256438611,0.0525708283766902484401839501,0.4174092731488769913994474336\n 0.4096341697147408700274695547,0.1587830198973579909349496119,0.1292545832485494372576795285\n 0.8323255650024565799327547210,0.9694902427379478160318626578,0.6295047811546814475747169126\n 0.4679375305798131323697930383,0.2963942381834381301075609371,0.5268936082160610157032465394\n 0.6685382761849776311890991564,0.6721207066140679753374342908,0.6519975277021627935170045020\n ' + self.data = (self.data * 200) + + def time_read_csv_roundtrip_converter(self): + read_csv(StringIO(self.data), sep=',', header=None, float_precision='round_trip') + + +class read_csv_thou_vb(object): + goal_time = 0.2 + + def setup(self): + self.N = 10000 + self.K = 8 + self.format = (lambda x: '{:,}'.format(x)) + self.df = DataFrame((np.random.randn(self.N, self.K) * np.random.randint(100, 10000, (self.N, self.K)))) + self.df = self.df.applymap(self.format) + self.df.to_csv('test.csv', sep='|') + + def time_read_csv_thou_vb(self): + read_csv('test.csv', sep='|', thousands=',') + + def teardown(self): + os.remove('test.csv') + + +class read_csv_vb(object): + goal_time = 0.2 + + def setup(self): + self.N = 10000 + self.K = 8 + self.df = DataFrame((np.random.randn(self.N, self.K) * np.random.randint(100, 10000, (self.N, self.K)))) + self.df.to_csv('test.csv', sep='|') + + def time_read_csv_vb(self): + read_csv('test.csv', sep='|') + + def teardown(self): + os.remove('test.csv') + + +class read_table_multiple_date(object): + goal_time = 0.2 + + def setup(self): + self.N = 10000 + self.K = 8 + self.data = 'KORD,19990127, 19:00:00, 18:56:00, 0.8100, 2.8100, 7.2000, 0.0000, 280.0000\n KORD,19990127, 20:00:00, 19:56:00, 0.0100, 2.2100, 7.2000, 0.0000, 260.0000\n KORD,19990127, 21:00:00, 20:56:00, -0.5900, 2.2100, 5.7000, 0.0000, 280.0000\n KORD,19990127, 21:00:00, 21:18:00, -0.9900, 2.0100, 3.6000, 0.0000, 270.0000\n KORD,19990127, 22:00:00, 21:56:00, -0.5900, 1.7100, 5.1000, 0.0000, 290.0000\n ' + self.data = (self.data * 200) + + def time_read_table_multiple_date(self): + read_table(StringIO(self.data), sep=',', header=None, parse_dates=[[1, 2], [1, 3]]) + + +class read_table_multiple_date_baseline(object): + goal_time = 0.2 + + def setup(self): + self.N = 10000 + self.K = 8 + self.data = 'KORD,19990127 19:00:00, 18:56:00, 0.8100, 2.8100, 7.2000, 0.0000, 280.0000\n KORD,19990127 20:00:00, 19:56:00, 0.0100, 2.2100, 7.2000, 0.0000, 260.0000\n KORD,19990127 21:00:00, 20:56:00, -0.5900, 2.2100, 5.7000, 0.0000, 280.0000\n KORD,19990127 21:00:00, 21:18:00, -0.9900, 2.0100, 3.6000, 0.0000, 270.0000\n KORD,19990127 22:00:00, 21:56:00, -0.5900, 1.7100, 5.1000, 0.0000, 290.0000\n ' + self.data = (self.data * 200) + + def time_read_table_multiple_date_baseline(self): + read_table(StringIO(self.data), sep=',', header=None, parse_dates=[1]) \ No newline at end of file diff --git a/asv_bench/benchmarks/plotting.py b/asv_bench/benchmarks/plotting.py new file mode 100644 index 0000000000000..d1df1b429c656 --- /dev/null +++ b/asv_bench/benchmarks/plotting.py @@ -0,0 +1,19 @@ +from pandas_vb_common import * +try: + from pandas import date_range +except ImportError: + + def date_range(start=None, end=None, periods=None, freq=None): + return DatetimeIndex(start, end, periods=periods, offset=freq) + + +class plot_timeseries_period(object): + goal_time = 0.2 + + def setup(self): + self.N = 2000 + self.M = 5 + self.df = DataFrame(np.random.randn(self.N, self.M), index=date_range('1/1/1975', periods=self.N)) + + def time_plot_timeseries_period(self): + self.df.plot() \ No newline at end of file diff --git a/asv_bench/benchmarks/reindex.py b/asv_bench/benchmarks/reindex.py new file mode 100644 index 0000000000000..d6fbd0d31c389 --- /dev/null +++ b/asv_bench/benchmarks/reindex.py @@ -0,0 +1,384 @@ +from pandas_vb_common import * +from random import shuffle + + +class dataframe_reindex(object): + goal_time = 0.2 + + def setup(self): + self.rng = DatetimeIndex(start='1/1/1970', periods=10000, freq=datetools.Minute()) + self.df = DataFrame(np.random.rand(10000, 10), index=self.rng, columns=range(10)) + self.df['foo'] = 'bar' + self.rng2 = Index(self.rng[::2]) + + def time_dataframe_reindex(self): + self.df.reindex(self.rng2) + + +class frame_drop_dup_inplace(object): + goal_time = 0.2 + + def setup(self): + self.N = 10000 + self.K = 10 + self.key1 = tm.makeStringIndex(self.N).values.repeat(self.K) + self.key2 = tm.makeStringIndex(self.N).values.repeat(self.K) + self.df = DataFrame({'key1': self.key1, 'key2': self.key2, 'value': np.random.randn((self.N * self.K)), }) + self.col_array_list = list(self.df.values.T) + + def time_frame_drop_dup_inplace(self): + self.df.drop_duplicates(['key1', 'key2'], inplace=True) + + +class frame_drop_dup_na_inplace(object): + goal_time = 0.2 + + def setup(self): + self.N = 10000 + self.K = 10 + self.key1 = tm.makeStringIndex(self.N).values.repeat(self.K) + self.key2 = tm.makeStringIndex(self.N).values.repeat(self.K) + self.df = DataFrame({'key1': self.key1, 'key2': self.key2, 'value': np.random.randn((self.N * self.K)), }) + self.col_array_list = list(self.df.values.T) + self.df.ix[:10000, :] = np.nan + + def time_frame_drop_dup_na_inplace(self): + self.df.drop_duplicates(['key1', 'key2'], inplace=True) + + +class frame_drop_duplicates(object): + goal_time = 0.2 + + def setup(self): + self.N = 10000 + self.K = 10 + self.key1 = tm.makeStringIndex(self.N).values.repeat(self.K) + self.key2 = tm.makeStringIndex(self.N).values.repeat(self.K) + self.df = DataFrame({'key1': self.key1, 'key2': self.key2, 'value': np.random.randn((self.N * self.K)), }) + self.col_array_list = list(self.df.values.T) + + def time_frame_drop_duplicates(self): + self.df.drop_duplicates(['key1', 'key2']) + + +class frame_drop_duplicates_na(object): + goal_time = 0.2 + + def setup(self): + self.N = 10000 + self.K = 10 + self.key1 = tm.makeStringIndex(self.N).values.repeat(self.K) + self.key2 = tm.makeStringIndex(self.N).values.repeat(self.K) + self.df = DataFrame({'key1': self.key1, 'key2': self.key2, 'value': np.random.randn((self.N * self.K)), }) + self.col_array_list = list(self.df.values.T) + self.df.ix[:10000, :] = np.nan + + def time_frame_drop_duplicates_na(self): + self.df.drop_duplicates(['key1', 'key2']) + + +class frame_fillna_many_columns_pad(object): + goal_time = 0.2 + + def setup(self): + self.values = np.random.randn(1000, 1000) + self.values[::2] = np.nan + self.df = DataFrame(self.values) + + def time_frame_fillna_many_columns_pad(self): + self.df.fillna(method='pad') + + +class frame_reindex_columns(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(index=range(10000), data=np.random.rand(10000, 30), columns=range(30)) + + def time_frame_reindex_columns(self): + self.df.reindex(columns=self.df.columns[1:5]) + + +class frame_sort_index_by_columns(object): + goal_time = 0.2 + + def setup(self): + self.N = 10000 + self.K = 10 + self.key1 = tm.makeStringIndex(self.N).values.repeat(self.K) + self.key2 = tm.makeStringIndex(self.N).values.repeat(self.K) + self.df = DataFrame({'key1': self.key1, 'key2': self.key2, 'value': np.random.randn((self.N * self.K)), }) + self.col_array_list = list(self.df.values.T) + + def time_frame_sort_index_by_columns(self): + self.df.sort_index(by=['key1', 'key2']) + + +class lib_fast_zip(object): + goal_time = 0.2 + + def setup(self): + self.N = 10000 + self.K = 10 + self.key1 = tm.makeStringIndex(self.N).values.repeat(self.K) + self.key2 = tm.makeStringIndex(self.N).values.repeat(self.K) + self.df = DataFrame({'key1': self.key1, 'key2': self.key2, 'value': np.random.randn((self.N * self.K)), }) + self.col_array_list = list(self.df.values.T) + + def time_lib_fast_zip(self): + lib.fast_zip(self.col_array_list) + + +class lib_fast_zip_fillna(object): + goal_time = 0.2 + + def setup(self): + self.N = 10000 + self.K = 10 + self.key1 = tm.makeStringIndex(self.N).values.repeat(self.K) + self.key2 = tm.makeStringIndex(self.N).values.repeat(self.K) + self.df = DataFrame({'key1': self.key1, 'key2': self.key2, 'value': np.random.randn((self.N * self.K)), }) + self.col_array_list = list(self.df.values.T) + self.df.ix[:10000, :] = np.nan + + def time_lib_fast_zip_fillna(self): + lib.fast_zip_fillna(self.col_array_list) + + +class reindex_daterange_backfill(object): + goal_time = 0.2 + + def setup(self): + self.rng = date_range('1/1/2000', periods=100000, freq=datetools.Minute()) + self.ts = Series(np.random.randn(len(self.rng)), index=self.rng) + self.ts2 = self.ts[::2] + self.ts3 = self.ts2.reindex(self.ts.index) + self.ts4 = self.ts3.astype('float32') + + def pad(source_series, target_index): + try: + source_series.reindex(target_index, method='pad') + except: + source_series.reindex(target_index, fillMethod='pad') + + def backfill(source_series, target_index): + try: + source_series.reindex(target_index, method='backfill') + except: + source_series.reindex(target_index, fillMethod='backfill') + + def time_reindex_daterange_backfill(self): + backfill(self.ts2, self.ts.index) + + +class reindex_daterange_pad(object): + goal_time = 0.2 + + def setup(self): + self.rng = date_range('1/1/2000', periods=100000, freq=datetools.Minute()) + self.ts = Series(np.random.randn(len(self.rng)), index=self.rng) + self.ts2 = self.ts[::2] + self.ts3 = self.ts2.reindex(self.ts.index) + self.ts4 = self.ts3.astype('float32') + + def pad(source_series, target_index): + try: + source_series.reindex(target_index, method='pad') + except: + source_series.reindex(target_index, fillMethod='pad') + + def backfill(source_series, target_index): + try: + source_series.reindex(target_index, method='backfill') + except: + source_series.reindex(target_index, fillMethod='backfill') + + def time_reindex_daterange_pad(self): + pad(self.ts2, self.ts.index) + + +class reindex_fillna_backfill(object): + goal_time = 0.2 + + def setup(self): + self.rng = date_range('1/1/2000', periods=100000, freq=datetools.Minute()) + self.ts = Series(np.random.randn(len(self.rng)), index=self.rng) + self.ts2 = self.ts[::2] + self.ts3 = self.ts2.reindex(self.ts.index) + self.ts4 = self.ts3.astype('float32') + + def pad(source_series, target_index): + try: + source_series.reindex(target_index, method='pad') + except: + source_series.reindex(target_index, fillMethod='pad') + + def backfill(source_series, target_index): + try: + source_series.reindex(target_index, method='backfill') + except: + source_series.reindex(target_index, fillMethod='backfill') + + def time_reindex_fillna_backfill(self): + self.ts3.fillna(method='backfill') + + +class reindex_fillna_backfill_float32(object): + goal_time = 0.2 + + def setup(self): + self.rng = date_range('1/1/2000', periods=100000, freq=datetools.Minute()) + self.ts = Series(np.random.randn(len(self.rng)), index=self.rng) + self.ts2 = self.ts[::2] + self.ts3 = self.ts2.reindex(self.ts.index) + self.ts4 = self.ts3.astype('float32') + + def pad(source_series, target_index): + try: + source_series.reindex(target_index, method='pad') + except: + source_series.reindex(target_index, fillMethod='pad') + + def backfill(source_series, target_index): + try: + source_series.reindex(target_index, method='backfill') + except: + source_series.reindex(target_index, fillMethod='backfill') + + def time_reindex_fillna_backfill_float32(self): + self.ts4.fillna(method='backfill') + + +class reindex_fillna_pad(object): + goal_time = 0.2 + + def setup(self): + self.rng = date_range('1/1/2000', periods=100000, freq=datetools.Minute()) + self.ts = Series(np.random.randn(len(self.rng)), index=self.rng) + self.ts2 = self.ts[::2] + self.ts3 = self.ts2.reindex(self.ts.index) + self.ts4 = self.ts3.astype('float32') + + def pad(source_series, target_index): + try: + source_series.reindex(target_index, method='pad') + except: + source_series.reindex(target_index, fillMethod='pad') + + def backfill(source_series, target_index): + try: + source_series.reindex(target_index, method='backfill') + except: + source_series.reindex(target_index, fillMethod='backfill') + + def time_reindex_fillna_pad(self): + self.ts3.fillna(method='pad') + + +class reindex_fillna_pad_float32(object): + goal_time = 0.2 + + def setup(self): + self.rng = date_range('1/1/2000', periods=100000, freq=datetools.Minute()) + self.ts = Series(np.random.randn(len(self.rng)), index=self.rng) + self.ts2 = self.ts[::2] + self.ts3 = self.ts2.reindex(self.ts.index) + self.ts4 = self.ts3.astype('float32') + + def pad(source_series, target_index): + try: + source_series.reindex(target_index, method='pad') + except: + source_series.reindex(target_index, fillMethod='pad') + + def backfill(source_series, target_index): + try: + source_series.reindex(target_index, method='backfill') + except: + source_series.reindex(target_index, fillMethod='backfill') + + def time_reindex_fillna_pad_float32(self): + self.ts4.fillna(method='pad') + + +class reindex_frame_level_align(object): + goal_time = 0.2 + + def setup(self): + self.index = MultiIndex(levels=[np.arange(10), np.arange(100), np.arange(100)], labels=[np.arange(10).repeat(10000), np.tile(np.arange(100).repeat(100), 10), np.tile(np.tile(np.arange(100), 100), 10)]) + random.shuffle(self.index.values) + self.df = DataFrame(np.random.randn(len(self.index), 4), index=self.index) + self.df_level = DataFrame(np.random.randn(100, 4), index=self.index.levels[1]) + + def time_reindex_frame_level_align(self): + self.df.align(self.df_level, level=1, copy=False) + + +class reindex_frame_level_reindex(object): + goal_time = 0.2 + + def setup(self): + self.index = MultiIndex(levels=[np.arange(10), np.arange(100), np.arange(100)], labels=[np.arange(10).repeat(10000), np.tile(np.arange(100).repeat(100), 10), np.tile(np.tile(np.arange(100), 100), 10)]) + random.shuffle(self.index.values) + self.df = DataFrame(np.random.randn(len(self.index), 4), index=self.index) + self.df_level = DataFrame(np.random.randn(100, 4), index=self.index.levels[1]) + + def time_reindex_frame_level_reindex(self): + self.df_level.reindex(self.df.index, level=1) + + +class reindex_multiindex(object): + goal_time = 0.2 + + def setup(self): + self.N = 1000 + self.K = 20 + self.level1 = tm.makeStringIndex(self.N).values.repeat(self.K) + self.level2 = np.tile(tm.makeStringIndex(self.K).values, self.N) + self.index = MultiIndex.from_arrays([self.level1, self.level2]) + self.s1 = Series(np.random.randn((self.N * self.K)), index=self.index) + self.s2 = self.s1[::2] + + def time_reindex_multiindex(self): + self.s1.reindex(self.s2.index) + + +class series_align_irregular_string(object): + goal_time = 0.2 + + def setup(self): + self.n = 50000 + self.indices = tm.makeStringIndex(self.n) + + def sample(values, k): + self.sampler = np.arange(len(values)) + shuffle(self.sampler) + return values.take(self.sampler[:k]) + self.subsample_size = 40000 + self.x = Series(np.random.randn(50000), self.indices) + self.y = Series(np.random.randn(self.subsample_size), index=sample(self.indices, self.subsample_size)) + + def time_series_align_irregular_string(self): + (self.x + self.y) + + +class series_drop_duplicates_int(object): + goal_time = 0.2 + + def setup(self): + self.s = Series(np.random.randint(0, 1000, size=10000)) + self.s2 = Series(np.tile(tm.makeStringIndex(1000).values, 10)) + + def time_series_drop_duplicates_int(self): + self.s.drop_duplicates() + + +class series_drop_duplicates_string(object): + goal_time = 0.2 + + def setup(self): + self.s = Series(np.random.randint(0, 1000, size=10000)) + self.s2 = Series(np.tile(tm.makeStringIndex(1000).values, 10)) + + def time_series_drop_duplicates_string(self): + self.s2.drop_duplicates() \ No newline at end of file diff --git a/asv_bench/benchmarks/replace.py b/asv_bench/benchmarks/replace.py new file mode 100644 index 0000000000000..9b78c287c5ad4 --- /dev/null +++ b/asv_bench/benchmarks/replace.py @@ -0,0 +1,48 @@ +from pandas_vb_common import * +from pandas.compat import range +from datetime import timedelta + + +class replace_fillna(object): + goal_time = 0.2 + + def setup(self): + self.N = 1000000 + try: + self.rng = date_range('1/1/2000', periods=self.N, freq='min') + except NameError: + self.rng = DatetimeIndex('1/1/2000', periods=self.N, offset=datetools.Minute()) + self.date_range = DateRange + self.ts = Series(np.random.randn(self.N), index=self.rng) + + def time_replace_fillna(self): + self.ts.fillna(0.0, inplace=True) + + +class replace_large_dict(object): + goal_time = 0.2 + + def setup(self): + self.n = (10 ** 6) + self.start_value = (10 ** 5) + self.to_rep = dict(((i, (self.start_value + i)) for i in range(self.n))) + self.s = Series(np.random.randint(self.n, size=(10 ** 3))) + + def time_replace_large_dict(self): + self.s.replace(self.to_rep, inplace=True) + + +class replace_replacena(object): + goal_time = 0.2 + + def setup(self): + self.N = 1000000 + try: + self.rng = date_range('1/1/2000', periods=self.N, freq='min') + except NameError: + self.rng = DatetimeIndex('1/1/2000', periods=self.N, offset=datetools.Minute()) + self.date_range = DateRange + self.ts = Series(np.random.randn(self.N), index=self.rng) + + def time_replace_replacena(self): + self.ts.replace(np.nan, 0.0, inplace=True) \ No newline at end of file diff --git a/asv_bench/benchmarks/reshape.py b/asv_bench/benchmarks/reshape.py new file mode 100644 index 0000000000000..b4081957af97b --- /dev/null +++ b/asv_bench/benchmarks/reshape.py @@ -0,0 +1,76 @@ +from pandas_vb_common import * +from pandas.core.reshape import melt + + +class melt_dataframe(object): + goal_time = 0.2 + + def setup(self): + self.index = MultiIndex.from_arrays([np.arange(100).repeat(100), np.roll(np.tile(np.arange(100), 100), 25)]) + self.df = DataFrame(np.random.randn(10000, 4), index=self.index) + self.df = DataFrame(np.random.randn(10000, 3), columns=['A', 'B', 'C']) + self.df['id1'] = np.random.randint(0, 10, 10000) + self.df['id2'] = np.random.randint(100, 1000, 10000) + + def time_melt_dataframe(self): + melt(self.df, id_vars=['id1', 'id2']) + + +class reshape_pivot_time_series(object): + goal_time = 0.2 + + def setup(self): + self.index = MultiIndex.from_arrays([np.arange(100).repeat(100), np.roll(np.tile(np.arange(100), 100), 25)]) + self.df = DataFrame(np.random.randn(10000, 4), index=self.index) + + def unpivot(frame): + (N, K) = frame.shape + self.data = {'value': frame.values.ravel('F'), 'variable': np.asarray(frame.columns).repeat(N), 'date': np.tile(np.asarray(frame.index), K), } + return DataFrame(self.data, columns=['date', 'variable', 'value']) + self.index = date_range('1/1/2000', periods=10000, freq='h') + self.df = DataFrame(randn(10000, 50), index=self.index, columns=range(50)) + self.pdf = unpivot(self.df) + self.f = (lambda : self.pdf.pivot('date', 'variable', 'value')) + + def time_reshape_pivot_time_series(self): + self.f() + + +class reshape_stack_simple(object): + goal_time = 0.2 + + def setup(self): + self.index = MultiIndex.from_arrays([np.arange(100).repeat(100), np.roll(np.tile(np.arange(100), 100), 25)]) + self.df = DataFrame(np.random.randn(10000, 4), index=self.index) + self.udf = self.df.unstack(1) + + def time_reshape_stack_simple(self): + self.udf.stack() + + +class reshape_unstack_simple(object): + goal_time = 0.2 + + def setup(self): + self.index = MultiIndex.from_arrays([np.arange(100).repeat(100), np.roll(np.tile(np.arange(100), 100), 25)]) + self.df = DataFrame(np.random.randn(10000, 4), index=self.index) + + def time_reshape_unstack_simple(self): + self.df.unstack(1) + + +class unstack_sparse_keyspace(object): + goal_time = 0.2 + + def setup(self): + self.index = MultiIndex.from_arrays([np.arange(100).repeat(100), np.roll(np.tile(np.arange(100), 100), 25)]) + self.df = DataFrame(np.random.randn(10000, 4), index=self.index) + self.NUM_ROWS = 1000 + for iter in range(10): + self.df = DataFrame({'A': np.random.randint(50, size=self.NUM_ROWS), 'B': np.random.randint(50, size=self.NUM_ROWS), 'C': np.random.randint((-10), 10, size=self.NUM_ROWS), 'D': np.random.randint((-10), 10, size=self.NUM_ROWS), 'E': np.random.randint(10, size=self.NUM_ROWS), 'F': np.random.randn(self.NUM_ROWS), }) + self.idf = self.df.set_index(['A', 'B', 'C', 'D', 'E']) + if (len(self.idf.index.unique()) == self.NUM_ROWS): + break + + def time_unstack_sparse_keyspace(self): + self.idf.unstack() \ No newline at end of file diff --git a/asv_bench/benchmarks/series_methods.py b/asv_bench/benchmarks/series_methods.py new file mode 100644 index 0000000000000..9cd61c741dae1 --- /dev/null +++ b/asv_bench/benchmarks/series_methods.py @@ -0,0 +1,74 @@ +from pandas_vb_common import * + + +class series_isin_int64(object): + goal_time = 0.2 + + def setup(self): + self.s1 = Series(np.random.randn(10000)) + self.s2 = Series(np.random.randint(1, 10, 10000)) + self.s3 = Series(np.random.randint(1, 10, 100000)).astype('int64') + self.values = [1, 2] + self.s4 = self.s3.astype('object') + + def time_series_isin_int64(self): + self.s3.isin(self.values) + + +class series_isin_object(object): + goal_time = 0.2 + + def setup(self): + self.s1 = Series(np.random.randn(10000)) + self.s2 = Series(np.random.randint(1, 10, 10000)) + self.s3 = Series(np.random.randint(1, 10, 100000)).astype('int64') + self.values = [1, 2] + self.s4 = self.s3.astype('object') + + def time_series_isin_object(self): + self.s4.isin(self.values) + + +class series_nlargest1(object): + goal_time = 0.2 + + def setup(self): + self.s1 = Series(np.random.randn(10000)) + self.s2 = Series(np.random.randint(1, 10, 10000)) + self.s3 = Series(np.random.randint(1, 10, 100000)).astype('int64') + self.values = [1, 2] + self.s4 = self.s3.astype('object') + + def time_series_nlargest1(self): + self.s1.nlargest(3, take_last=True) + self.s1.nlargest(3, take_last=False) + + +class series_nlargest2(object): + goal_time = 0.2 + + def setup(self): + self.s1 = Series(np.random.randn(10000)) + self.s2 = Series(np.random.randint(1, 10, 10000)) + self.s3 = Series(np.random.randint(1, 10, 100000)).astype('int64') + self.values = [1, 2] + self.s4 = self.s3.astype('object') + + def time_series_nlargest2(self): + self.s2.nlargest(3, take_last=True) + self.s2.nlargest(3, take_last=False) + + +class series_nsmallest2(object): + goal_time = 0.2 + + def setup(self): + self.s1 = Series(np.random.randn(10000)) + self.s2 = Series(np.random.randint(1, 10, 10000)) + self.s3 = Series(np.random.randint(1, 10, 100000)).astype('int64') + self.values = [1, 2] + self.s4 = self.s3.astype('object') + + def time_series_nsmallest2(self): + self.s2.nsmallest(3, take_last=True) + self.s2.nsmallest(3, take_last=False) \ No newline at end of file diff --git a/asv_bench/benchmarks/sparse.py b/asv_bench/benchmarks/sparse.py new file mode 100644 index 0000000000000..dbf35f5e40f55 --- /dev/null +++ b/asv_bench/benchmarks/sparse.py @@ -0,0 +1,55 @@ +from pandas_vb_common import * +import scipy.sparse +import pandas.sparse.series +from pandas.core.sparse import SparseSeries, SparseDataFrame +from pandas.core.sparse import SparseDataFrame + + +class sparse_series_to_frame(object): + goal_time = 0.2 + + def setup(self): + self.K = 50 + self.N = 50000 + self.rng = np.asarray(date_range('1/1/2000', periods=self.N, freq='T')) + self.series = {} + for i in range(1, (self.K + 1)): + self.data = np.random.randn(self.N)[:(- i)] + self.this_rng = self.rng[:(- i)] + self.data[100:] = np.nan + self.series[i] = SparseSeries(self.data, index=self.this_rng) + + def time_sparse_series_to_frame(self): + SparseDataFrame(self.series) + + +class sparse_frame_constructor(object): + goal_time = 0.2 + + def time_sparse_frame_constructor(self): + SparseDataFrame(columns=np.arange(100), index=np.arange(1000)) + + +class sparse_series_from_coo(object): + goal_time = 0.2 + + def setup(self): + self.A = scipy.sparse.coo_matrix(([3.0, 1.0, 2.0], ([1, 0, 0], [0, 2, 3])), shape=(100, 100)) + + def time_sparse_series_from_coo(self): + self.ss = pandas.sparse.series.SparseSeries.from_coo(self.A) + + +class sparse_series_to_coo(object): + goal_time = 0.2 + + def setup(self): + self.s = pd.Series(([np.nan] * 10000)) + self.s[0] = 3.0 + self.s[100] = (-1.0) + self.s[999] = 12.1 + self.s.index = pd.MultiIndex.from_product((range(10), range(10), range(10), range(10))) + self.ss = self.s.to_sparse() + + def time_sparse_series_to_coo(self): + self.ss.to_coo(row_levels=[0, 1], column_levels=[2, 3], sort_labels=True) \ No newline at end of file diff --git a/asv_bench/benchmarks/stat_ops.py b/asv_bench/benchmarks/stat_ops.py new file mode 100644 index 0000000000000..98e2bbfce1a44 --- /dev/null +++ b/asv_bench/benchmarks/stat_ops.py @@ -0,0 +1,236 @@ +from pandas_vb_common import * + + +class stat_ops_frame_mean_float_axis_0(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(100000, 4)) + self.dfi = DataFrame(np.random.randint(1000, size=self.df.shape)) + + def time_stat_ops_frame_mean_float_axis_0(self): + self.df.mean() + + +class stat_ops_frame_mean_float_axis_1(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(100000, 4)) + self.dfi = DataFrame(np.random.randint(1000, size=self.df.shape)) + + def time_stat_ops_frame_mean_float_axis_1(self): + self.df.mean(1) + + +class stat_ops_frame_mean_int_axis_0(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(100000, 4)) + self.dfi = DataFrame(np.random.randint(1000, size=self.df.shape)) + + def time_stat_ops_frame_mean_int_axis_0(self): + self.dfi.mean() + + +class stat_ops_frame_mean_int_axis_1(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(100000, 4)) + self.dfi = DataFrame(np.random.randint(1000, size=self.df.shape)) + + def time_stat_ops_frame_mean_int_axis_1(self): + self.dfi.mean(1) + + +class stat_ops_frame_sum_float_axis_0(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(100000, 4)) + self.dfi = DataFrame(np.random.randint(1000, size=self.df.shape)) + + def time_stat_ops_frame_sum_float_axis_0(self): + self.df.sum() + + +class stat_ops_frame_sum_float_axis_1(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(100000, 4)) + self.dfi = DataFrame(np.random.randint(1000, size=self.df.shape)) + + def time_stat_ops_frame_sum_float_axis_1(self): + self.df.sum(1) + + +class stat_ops_frame_sum_int_axis_0(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(100000, 4)) + self.dfi = DataFrame(np.random.randint(1000, size=self.df.shape)) + + def time_stat_ops_frame_sum_int_axis_0(self): + self.dfi.sum() + + +class stat_ops_frame_sum_int_axis_1(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(100000, 4)) + self.dfi = DataFrame(np.random.randint(1000, size=self.df.shape)) + + def time_stat_ops_frame_sum_int_axis_1(self): + self.dfi.sum(1) + + +class stat_ops_level_frame_sum(object): + goal_time = 0.2 + + def setup(self): + self.index = MultiIndex(levels=[np.arange(10), np.arange(100), np.arange(100)], labels=[np.arange(10).repeat(10000), np.tile(np.arange(100).repeat(100), 10), np.tile(np.tile(np.arange(100), 100), 10)]) + random.shuffle(self.index.values) + self.df = DataFrame(np.random.randn(len(self.index), 4), index=self.index) + self.df_level = DataFrame(np.random.randn(100, 4), index=self.index.levels[1]) + + def time_stat_ops_level_frame_sum(self): + self.df.sum(level=1) + + +class stat_ops_level_frame_sum_multiple(object): + goal_time = 0.2 + + def setup(self): + self.index = MultiIndex(levels=[np.arange(10), np.arange(100), np.arange(100)], labels=[np.arange(10).repeat(10000), np.tile(np.arange(100).repeat(100), 10), np.tile(np.tile(np.arange(100), 100), 10)]) + random.shuffle(self.index.values) + self.df = DataFrame(np.random.randn(len(self.index), 4), index=self.index) + self.df_level = DataFrame(np.random.randn(100, 4), index=self.index.levels[1]) + + def time_stat_ops_level_frame_sum_multiple(self): + self.df.sum(level=[0, 1]) + + +class stat_ops_level_series_sum(object): + goal_time = 0.2 + + def setup(self): + self.index = MultiIndex(levels=[np.arange(10), np.arange(100), np.arange(100)], labels=[np.arange(10).repeat(10000), np.tile(np.arange(100).repeat(100), 10), np.tile(np.tile(np.arange(100), 100), 10)]) + random.shuffle(self.index.values) + self.df = DataFrame(np.random.randn(len(self.index), 4), index=self.index) + self.df_level = DataFrame(np.random.randn(100, 4), index=self.index.levels[1]) + + def time_stat_ops_level_series_sum(self): + self.df[1].sum(level=1) + + +class stat_ops_level_series_sum_multiple(object): + goal_time = 0.2 + + def setup(self): + self.index = MultiIndex(levels=[np.arange(10), np.arange(100), np.arange(100)], labels=[np.arange(10).repeat(10000), np.tile(np.arange(100).repeat(100), 10), np.tile(np.tile(np.arange(100), 100), 10)]) + random.shuffle(self.index.values) + self.df = DataFrame(np.random.randn(len(self.index), 4), index=self.index) + self.df_level = DataFrame(np.random.randn(100, 4), index=self.index.levels[1]) + + def time_stat_ops_level_series_sum_multiple(self): + self.df[1].sum(level=[0, 1]) + + +class stat_ops_series_std(object): + goal_time = 0.2 + + def setup(self): + self.s = Series(np.random.randn(100000), index=np.arange(100000)) + self.s[::2] = np.nan + + def time_stat_ops_series_std(self): + self.s.std() + + +class stats_corr_spearman(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(1000, 30)) + + def time_stats_corr_spearman(self): + self.df.corr(method='spearman') + + +class stats_rank2d_axis0_average(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(5000, 50)) + + def time_stats_rank2d_axis0_average(self): + self.df.rank() + + +class stats_rank2d_axis1_average(object): + goal_time = 0.2 + + def setup(self): + self.df = DataFrame(np.random.randn(5000, 50)) + + def time_stats_rank2d_axis1_average(self): + self.df.rank(1) + + +class stats_rank_average(object): + goal_time = 0.2 + + def setup(self): + self.values = np.concatenate([np.arange(100000), np.random.randn(100000), np.arange(100000)]) + self.s = Series(self.values) + + def time_stats_rank_average(self): + self.s.rank() + + +class stats_rank_average_int(object): + goal_time = 0.2 + + def setup(self): + self.values = np.random.randint(0, 100000, size=200000) + self.s = Series(self.values) + + def time_stats_rank_average_int(self): + self.s.rank() + + +class stats_rank_pct_average(object): + goal_time = 0.2 + + def setup(self): + self.values = np.concatenate([np.arange(100000), np.random.randn(100000), np.arange(100000)]) + self.s = Series(self.values) + + def time_stats_rank_pct_average(self): + self.s.rank(pct=True) + + +class stats_rank_pct_average_old(object): + goal_time = 0.2 + + def setup(self): + self.values = np.concatenate([np.arange(100000), np.random.randn(100000), np.arange(100000)]) + self.s = Series(self.values) + + def time_stats_rank_pct_average_old(self): + (self.s.rank() / len(self.s)) + + +class stats_rolling_mean(object): + goal_time = 0.2 + + def setup(self): + self.arr = np.random.randn(100000) + + def time_stats_rolling_mean(self): + rolling_mean(self.arr, 100) \ No newline at end of file diff --git a/asv_bench/benchmarks/strings.py b/asv_bench/benchmarks/strings.py new file mode 100644 index 0000000000000..5adfbf4c2557d --- /dev/null +++ b/asv_bench/benchmarks/strings.py @@ -0,0 +1,393 @@ +from pandas_vb_common import * +import string +import itertools as IT +import pandas.util.testing as testing + + +class strings_cat(object): + goal_time = 0.2 + + def setup(self): + + def make_series(letters, strlen, size): + return Series(np.fromiter(IT.cycle(letters), count=(size * strlen), dtype='|S1').view('|S{}'.format(strlen))) + self.many = make_series(('matchthis' + string.uppercase), strlen=19, size=10000) + self.few = make_series(('matchthis' + (string.uppercase * 42)), strlen=19, size=10000) + + def time_strings_cat(self): + self.many.str.cat(sep=',') + + +class strings_center(object): + goal_time = 0.2 + + def setup(self): + + def make_series(letters, strlen, size): + return Series(np.fromiter(IT.cycle(letters), count=(size * strlen), dtype='|S1').view('|S{}'.format(strlen))) + self.many = make_series(('matchthis' + string.uppercase), strlen=19, size=10000) + self.few = make_series(('matchthis' + (string.uppercase * 42)), strlen=19, size=10000) + + def time_strings_center(self): + self.many.str.center(100) + + +class strings_contains_few(object): + goal_time = 0.2 + + def setup(self): + + def make_series(letters, strlen, size): + return Series(np.fromiter(IT.cycle(letters), count=(size * strlen), dtype='|S1').view('|S{}'.format(strlen))) + self.many = make_series(('matchthis' + string.uppercase), strlen=19, size=10000) + self.few = make_series(('matchthis' + (string.uppercase * 42)), strlen=19, size=10000) + + def time_strings_contains_few(self): + self.few.str.contains('matchthis') + + +class strings_contains_few_noregex(object): + goal_time = 0.2 + + def setup(self): + + def make_series(letters, strlen, size): + return Series(np.fromiter(IT.cycle(letters), count=(size * strlen), dtype='|S1').view('|S{}'.format(strlen))) + self.many = make_series(('matchthis' + string.uppercase), strlen=19, size=10000) + self.few = make_series(('matchthis' + (string.uppercase * 42)), strlen=19, size=10000) + + def time_strings_contains_few_noregex(self): + self.few.str.contains('matchthis', regex=False) + + +class strings_contains_many(object): + goal_time = 0.2 + + def setup(self): + + def make_series(letters, strlen, size): + return Series(np.fromiter(IT.cycle(letters), count=(size * strlen), dtype='|S1').view('|S{}'.format(strlen))) + self.many = make_series(('matchthis' + string.uppercase), strlen=19, size=10000) + self.few = make_series(('matchthis' + (string.uppercase * 42)), strlen=19, size=10000) + + def time_strings_contains_many(self): + self.many.str.contains('matchthis') + + +class strings_contains_many_noregex(object): + goal_time = 0.2 + + def setup(self): + + def make_series(letters, strlen, size): + return Series(np.fromiter(IT.cycle(letters), count=(size * strlen), dtype='|S1').view('|S{}'.format(strlen))) + self.many = make_series(('matchthis' + string.uppercase), strlen=19, size=10000) + self.few = make_series(('matchthis' + (string.uppercase * 42)), strlen=19, size=10000) + + def time_strings_contains_many_noregex(self): + self.many.str.contains('matchthis', regex=False) + + +class strings_count(object): + goal_time = 0.2 + + def setup(self): + + def make_series(letters, strlen, size): + return Series(np.fromiter(IT.cycle(letters), count=(size * strlen), dtype='|S1').view('|S{}'.format(strlen))) + self.many = make_series(('matchthis' + string.uppercase), strlen=19, size=10000) + self.few = make_series(('matchthis' + (string.uppercase * 42)), strlen=19, size=10000) + + def time_strings_count(self): + self.many.str.count('matchthis') + + +class strings_encode_decode(object): + goal_time = 0.2 + + def setup(self): + self.ser = Series(testing.makeUnicodeIndex()) + + def time_strings_encode_decode(self): + self.ser.str.encode('utf-8').str.decode('utf-8') + + +class strings_endswith(object): + goal_time = 0.2 + + def setup(self): + + def make_series(letters, strlen, size): + return Series(np.fromiter(IT.cycle(letters), count=(size * strlen), dtype='|S1').view('|S{}'.format(strlen))) + self.many = make_series(('matchthis' + string.uppercase), strlen=19, size=10000) + self.few = make_series(('matchthis' + (string.uppercase * 42)), strlen=19, size=10000) + + def time_strings_endswith(self): + self.many.str.endswith('matchthis') + + +class strings_extract(object): + goal_time = 0.2 + + def setup(self): + + def make_series(letters, strlen, size): + return Series(np.fromiter(IT.cycle(letters), count=(size * strlen), dtype='|S1').view('|S{}'.format(strlen))) + self.many = make_series(('matchthis' + string.uppercase), strlen=19, size=10000) + self.few = make_series(('matchthis' + (string.uppercase * 42)), strlen=19, size=10000) + + def time_strings_extract(self): + self.many.str.extract('(\\w*)matchthis(\\w*)') + + +class strings_findall(object): + goal_time = 0.2 + + def setup(self): + + def make_series(letters, strlen, size): + return Series(np.fromiter(IT.cycle(letters), count=(size * strlen), dtype='|S1').view('|S{}'.format(strlen))) + self.many = make_series(('matchthis' + string.uppercase), strlen=19, size=10000) + self.few = make_series(('matchthis' + (string.uppercase * 42)), strlen=19, size=10000) + + def time_strings_findall(self): + self.many.str.findall('[A-Z]+') + + +class strings_get(object): + goal_time = 0.2 + + def setup(self): + + def make_series(letters, strlen, size): + return Series(np.fromiter(IT.cycle(letters), count=(size * strlen), dtype='|S1').view('|S{}'.format(strlen))) + self.many = make_series(('matchthis' + string.uppercase), strlen=19, size=10000) + self.few = make_series(('matchthis' + (string.uppercase * 42)), strlen=19, size=10000) + + def time_strings_get(self): + self.many.str.get(0) + + +class strings_get_dummies(object): + goal_time = 0.2 + + def setup(self): + + def make_series(letters, strlen, size): + return Series(np.fromiter(IT.cycle(letters), count=(size * strlen), dtype='|S1').view('|S{}'.format(strlen))) + self.many = make_series(('matchthis' + string.uppercase), strlen=19, size=10000) + self.few = make_series(('matchthis' + (string.uppercase * 42)), strlen=19, size=10000) + self.s = make_series(string.uppercase, strlen=10, size=10000).str.join('|') + + def time_strings_get_dummies(self): + self.s.str.get_dummies('|') + + +class strings_join_split(object): + goal_time = 0.2 + + def setup(self): + + def make_series(letters, strlen, size): + return Series(np.fromiter(IT.cycle(letters), count=(size * strlen), dtype='|S1').view('|S{}'.format(strlen))) + self.many = make_series(('matchthis' + string.uppercase), strlen=19, size=10000) + self.few = make_series(('matchthis' + (string.uppercase * 42)), strlen=19, size=10000) + + def time_strings_join_split(self): + self.many.str.join('--').str.split('--') + + +class strings_join_split_expand(object): + goal_time = 0.2 + + def setup(self): + + def make_series(letters, strlen, size): + return Series(np.fromiter(IT.cycle(letters), count=(size * strlen), dtype='|S1').view('|S{}'.format(strlen))) + self.many = make_series(('matchthis' + string.uppercase), strlen=19, size=10000) + self.few = make_series(('matchthis' + (string.uppercase * 42)), strlen=19, size=10000) + + def time_strings_join_split_expand(self): + self.many.str.join('--').str.split('--', expand=True) + + +class strings_len(object): + goal_time = 0.2 + + def setup(self): + + def make_series(letters, strlen, size): + return Series(np.fromiter(IT.cycle(letters), count=(size * strlen), dtype='|S1').view('|S{}'.format(strlen))) + self.many = make_series(('matchthis' + string.uppercase), strlen=19, size=10000) + self.few = make_series(('matchthis' + (string.uppercase * 42)), strlen=19, size=10000) + + def time_strings_len(self): + self.many.str.len() + + +class strings_lower(object): + goal_time = 0.2 + + def setup(self): + + def make_series(letters, strlen, size): + return Series(np.fromiter(IT.cycle(letters), count=(size * strlen), dtype='|S1').view('|S{}'.format(strlen))) + self.many = make_series(('matchthis' + string.uppercase), strlen=19, size=10000) + self.few = make_series(('matchthis' + (string.uppercase * 42)), strlen=19, size=10000) + + def time_strings_lower(self): + self.many.str.lower() + + +class strings_lstrip(object): + goal_time = 0.2 + + def setup(self): + + def make_series(letters, strlen, size): + return Series(np.fromiter(IT.cycle(letters), count=(size * strlen), dtype='|S1').view('|S{}'.format(strlen))) + self.many = make_series(('matchthis' + string.uppercase), strlen=19, size=10000) + self.few = make_series(('matchthis' + (string.uppercase * 42)), strlen=19, size=10000) + + def time_strings_lstrip(self): + self.many.str.lstrip('matchthis') + + +class strings_match(object): + goal_time = 0.2 + + def setup(self): + + def make_series(letters, strlen, size): + return Series(np.fromiter(IT.cycle(letters), count=(size * strlen), dtype='|S1').view('|S{}'.format(strlen))) + self.many = make_series(('matchthis' + string.uppercase), strlen=19, size=10000) + self.few = make_series(('matchthis' + (string.uppercase * 42)), strlen=19, size=10000) + + def time_strings_match(self): + self.many.str.match('mat..this') + + +class strings_pad(object): + goal_time = 0.2 + + def setup(self): + + def make_series(letters, strlen, size): + return Series(np.fromiter(IT.cycle(letters), count=(size * strlen), dtype='|S1').view('|S{}'.format(strlen))) + self.many = make_series(('matchthis' + string.uppercase), strlen=19, size=10000) + self.few = make_series(('matchthis' + (string.uppercase * 42)), strlen=19, size=10000) + + def time_strings_pad(self): + self.many.str.pad(100, side='both') + + +class strings_repeat(object): + goal_time = 0.2 + + def setup(self): + + def make_series(letters, strlen, size): + return Series(np.fromiter(IT.cycle(letters), count=(size * strlen), dtype='|S1').view('|S{}'.format(strlen))) + self.many = make_series(('matchthis' + string.uppercase), strlen=19, size=10000) + self.few = make_series(('matchthis' + (string.uppercase * 42)), strlen=19, size=10000) + + def time_strings_repeat(self): + self.many.str.repeat(list(IT.islice(IT.cycle(range(1, 4)), len(self.many)))) + + +class strings_replace(object): + goal_time = 0.2 + + def setup(self): + + def make_series(letters, strlen, size): + return Series(np.fromiter(IT.cycle(letters), count=(size * strlen), dtype='|S1').view('|S{}'.format(strlen))) + self.many = make_series(('matchthis' + string.uppercase), strlen=19, size=10000) + self.few = make_series(('matchthis' + (string.uppercase * 42)), strlen=19, size=10000) + + def time_strings_replace(self): + self.many.str.replace('(matchthis)', '\x01\x01') + + +class strings_rstrip(object): + goal_time = 0.2 + + def setup(self): + + def make_series(letters, strlen, size): + return Series(np.fromiter(IT.cycle(letters), count=(size * strlen), dtype='|S1').view('|S{}'.format(strlen))) + self.many = make_series(('matchthis' + string.uppercase), strlen=19, size=10000) + self.few = make_series(('matchthis' + (string.uppercase * 42)), strlen=19, size=10000) + + def time_strings_rstrip(self): + self.many.str.rstrip('matchthis') + + +class strings_slice(object): + goal_time = 0.2 + + def setup(self): + + def make_series(letters, strlen, size): + return Series(np.fromiter(IT.cycle(letters), count=(size * strlen), dtype='|S1').view('|S{}'.format(strlen))) + self.many = make_series(('matchthis' + string.uppercase), strlen=19, size=10000) + self.few = make_series(('matchthis' + (string.uppercase * 42)), strlen=19, size=10000) + + def time_strings_slice(self): + self.many.str.slice(5, 15, 2) + + +class strings_startswith(object): + goal_time = 0.2 + + def setup(self): + + def make_series(letters, strlen, size): + return Series(np.fromiter(IT.cycle(letters), count=(size * strlen), dtype='|S1').view('|S{}'.format(strlen))) + self.many = make_series(('matchthis' + string.uppercase), strlen=19, size=10000) + self.few = make_series(('matchthis' + (string.uppercase * 42)), strlen=19, size=10000) + + def time_strings_startswith(self): + self.many.str.startswith('matchthis') + + +class strings_strip(object): + goal_time = 0.2 + + def setup(self): + + def make_series(letters, strlen, size): + return Series(np.fromiter(IT.cycle(letters), count=(size * strlen), dtype='|S1').view('|S{}'.format(strlen))) + self.many = make_series(('matchthis' + string.uppercase), strlen=19, size=10000) + self.few = make_series(('matchthis' + (string.uppercase * 42)), strlen=19, size=10000) + + def time_strings_strip(self): + self.many.str.strip('matchthis') + + +class strings_title(object): + goal_time = 0.2 + + def setup(self): + + def make_series(letters, strlen, size): + return Series(np.fromiter(IT.cycle(letters), count=(size * strlen), dtype='|S1').view('|S{}'.format(strlen))) + self.many = make_series(('matchthis' + string.uppercase), strlen=19, size=10000) + self.few = make_series(('matchthis' + (string.uppercase * 42)), strlen=19, size=10000) + + def time_strings_title(self): + self.many.str.title() + + +class strings_upper(object): + goal_time = 0.2 + + def setup(self): + + def make_series(letters, strlen, size): + return Series(np.fromiter(IT.cycle(letters), count=(size * strlen), dtype='|S1').view('|S{}'.format(strlen))) + self.many = make_series(('matchthis' + string.uppercase), strlen=19, size=10000) + self.few = make_series(('matchthis' + (string.uppercase * 42)), strlen=19, size=10000) + + def time_strings_upper(self): + self.many.str.upper() \ No newline at end of file diff --git a/asv_bench/benchmarks/timedelta.py b/asv_bench/benchmarks/timedelta.py new file mode 100644 index 0000000000000..36a0f98e3f5ef --- /dev/null +++ b/asv_bench/benchmarks/timedelta.py @@ -0,0 +1,34 @@ +from pandas_vb_common import * +from pandas import to_timedelta + + +class timedelta_convert_int(object): + goal_time = 0.2 + + def setup(self): + self.arr = np.random.randint(0, 1000, size=10000) + + def time_timedelta_convert_int(self): + to_timedelta(self.arr, unit='s') + + +class timedelta_convert_string(object): + goal_time = 0.2 + + def setup(self): + self.arr = np.random.randint(0, 1000, size=10000) + self.arr = ['{0} days'.format(i) for i in self.arr] + + def time_timedelta_convert_string(self): + to_timedelta(self.arr) + + +class timedelta_convert_string_seconds(object): + goal_time = 0.2 + + def setup(self): + self.arr = np.random.randint(0, 60, size=10000) + self.arr = ['00:00:{0:02d}'.format(i) for i in self.arr] + + def time_timedelta_convert_string_seconds(self): + to_timedelta(self.arr) \ No newline at end of file diff --git a/asv_bench/benchmarks/timeseries.py b/asv_bench/benchmarks/timeseries.py new file mode 100644 index 0000000000000..266c198de1455 --- /dev/null +++ b/asv_bench/benchmarks/timeseries.py @@ -0,0 +1,1046 @@ +from pandas.tseries.converter import DatetimeConverter +import pandas as pd +from datetime import timedelta +import datetime as dt +from pandas_vb_common import * +from pandas.tseries.frequencies import infer_freq +import pandas.tseries.holiday +import numpy as np + + +class dataframe_resample_max_numpy(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.rng = date_range(start='20130101', periods=100000, freq='50L') + self.df = DataFrame(np.random.randn(100000, 2), index=self.rng) + + def time_dataframe_resample_max_numpy(self): + self.df.resample('1s', how=np.max) + + +class dataframe_resample_max_string(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.rng = date_range(start='20130101', periods=100000, freq='50L') + self.df = DataFrame(np.random.randn(100000, 2), index=self.rng) + + def time_dataframe_resample_max_string(self): + self.df.resample('1s', how='max') + + +class dataframe_resample_mean_numpy(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.rng = date_range(start='20130101', periods=100000, freq='50L') + self.df = DataFrame(np.random.randn(100000, 2), index=self.rng) + + def time_dataframe_resample_mean_numpy(self): + self.df.resample('1s', how=np.mean) + + +class dataframe_resample_mean_string(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.rng = date_range(start='20130101', periods=100000, freq='50L') + self.df = DataFrame(np.random.randn(100000, 2), index=self.rng) + + def time_dataframe_resample_mean_string(self): + self.df.resample('1s', how='mean') + + +class dataframe_resample_min_numpy(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.rng = date_range(start='20130101', periods=100000, freq='50L') + self.df = DataFrame(np.random.randn(100000, 2), index=self.rng) + + def time_dataframe_resample_min_numpy(self): + self.df.resample('1s', how=np.min) + + +class dataframe_resample_min_string(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.rng = date_range(start='20130101', periods=100000, freq='50L') + self.df = DataFrame(np.random.randn(100000, 2), index=self.rng) + + def time_dataframe_resample_min_string(self): + self.df.resample('1s', how='min') + + +class datetimeindex_add_offset(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.rng = date_range(start='1/1/2000', periods=10000, freq='T') + + def time_datetimeindex_add_offset(self): + (self.rng + timedelta(minutes=2)) + + +class datetimeindex_converter(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + + def time_datetimeindex_converter(self): + DatetimeConverter.convert(self.rng, None, None) + + +class datetimeindex_infer_dst(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.dst_rng = date_range(start='10/29/2000 1:00:00', end='10/29/2000 1:59:59', freq='S') + self.index = date_range(start='10/29/2000', end='10/29/2000 00:59:59', freq='S') + self.index = self.index.append(self.dst_rng) + self.index = self.index.append(self.dst_rng) + self.index = self.index.append(date_range(start='10/29/2000 2:00:00', end='10/29/2000 3:00:00', freq='S')) + + def time_datetimeindex_infer_dst(self): + self.index.tz_localize('US/Eastern', infer_dst=True) + + +class datetimeindex_normalize(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.rng = date_range(start='1/1/2000 9:30', periods=10000, freq='S', tz='US/Eastern') + + def time_datetimeindex_normalize(self): + self.rng.normalize() + + +class datetimeindex_unique(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.rng = date_range(start='1/1/2000', periods=1000, freq='T') + self.index = self.rng.repeat(10) + + def time_datetimeindex_unique(self): + self.index.unique() + + +class dti_reset_index(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.rng = date_range(start='1/1/2000', periods=1000, freq='H') + self.df = DataFrame(np.random.randn(len(self.rng), 2), self.rng) + + def time_dti_reset_index(self): + self.df.reset_index() + + +class dti_reset_index_tz(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.rng = date_range(start='1/1/2000', periods=1000, freq='H', tz='US/Eastern') + self.df = DataFrame(np.random.randn(len(self.rng), 2), index=self.rng) + + def time_dti_reset_index_tz(self): + self.df.reset_index() + + +class period_setitem(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.rng = period_range(start='1/1/1990', freq='S', periods=20000) + self.df = DataFrame(index=range(len(self.rng))) + + def time_period_setitem(self): + self.df['col'] = self.rng + + +class timeseries_1min_5min_mean(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + + def time_timeseries_1min_5min_mean(self): + self.ts[:10000].resample('5min', how='mean') + + +class timeseries_1min_5min_ohlc(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + + def time_timeseries_1min_5min_ohlc(self): + self.ts[:10000].resample('5min', how='ohlc') + + +class timeseries_add_irregular(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.lindex = np.random.permutation(self.N)[:(self.N // 2)] + self.rindex = np.random.permutation(self.N)[:(self.N // 2)] + self.left = Series(self.ts.values.take(self.lindex), index=self.ts.index.take(self.lindex)) + self.right = Series(self.ts.values.take(self.rindex), index=self.ts.index.take(self.rindex)) + + def time_timeseries_add_irregular(self): + (self.left + self.right) + + +class timeseries_asof(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.N = 10000 + self.rng = date_range(start='1/1/1990', periods=self.N, freq='53s') + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.dates = date_range(start='1/1/1990', periods=(self.N * 10), freq='5s') + + def time_timeseries_asof(self): + self.ts.asof(self.dates) + + +class timeseries_asof_nan(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.N = 10000 + self.rng = date_range(start='1/1/1990', periods=self.N, freq='53s') + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.dates = date_range(start='1/1/1990', periods=(self.N * 10), freq='5s') + self.ts[250:5000] = np.nan + + def time_timeseries_asof_nan(self): + self.ts.asof(self.dates) + + +class timeseries_asof_single(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.N = 10000 + self.rng = date_range(start='1/1/1990', periods=self.N, freq='53s') + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.dates = date_range(start='1/1/1990', periods=(self.N * 10), freq='5s') + + def time_timeseries_asof_single(self): + self.ts.asof(self.dates[0]) + + +class timeseries_custom_bday_apply(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.date = dt.datetime(2011, 1, 1) + self.dt64 = np.datetime64('2011-01-01 09:00Z') + self.hcal = pd.tseries.holiday.USFederalHolidayCalendar() + self.day = pd.offsets.Day() + self.year = pd.offsets.YearBegin() + self.cday = pd.offsets.CustomBusinessDay() + self.cmb = pd.offsets.CustomBusinessMonthBegin(calendar=self.hcal) + self.cme = pd.offsets.CustomBusinessMonthEnd(calendar=self.hcal) + self.cdayh = pd.offsets.CustomBusinessDay(calendar=self.hcal) + + def time_timeseries_custom_bday_apply(self): + self.cday.apply(self.date) + + +class timeseries_custom_bday_apply_dt64(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.date = dt.datetime(2011, 1, 1) + self.dt64 = np.datetime64('2011-01-01 09:00Z') + self.hcal = pd.tseries.holiday.USFederalHolidayCalendar() + self.day = pd.offsets.Day() + self.year = pd.offsets.YearBegin() + self.cday = pd.offsets.CustomBusinessDay() + self.cmb = pd.offsets.CustomBusinessMonthBegin(calendar=self.hcal) + self.cme = pd.offsets.CustomBusinessMonthEnd(calendar=self.hcal) + self.cdayh = pd.offsets.CustomBusinessDay(calendar=self.hcal) + + def time_timeseries_custom_bday_apply_dt64(self): + self.cday.apply(self.dt64) + + +class timeseries_custom_bday_cal_decr(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.date = dt.datetime(2011, 1, 1) + self.dt64 = np.datetime64('2011-01-01 09:00Z') + self.hcal = pd.tseries.holiday.USFederalHolidayCalendar() + self.day = pd.offsets.Day() + self.year = pd.offsets.YearBegin() + self.cday = pd.offsets.CustomBusinessDay() + self.cmb = pd.offsets.CustomBusinessMonthBegin(calendar=self.hcal) + self.cme = pd.offsets.CustomBusinessMonthEnd(calendar=self.hcal) + self.cdayh = pd.offsets.CustomBusinessDay(calendar=self.hcal) + + def time_timeseries_custom_bday_cal_decr(self): + (self.date - (1 * self.cdayh)) + + +class timeseries_custom_bday_cal_incr(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.date = dt.datetime(2011, 1, 1) + self.dt64 = np.datetime64('2011-01-01 09:00Z') + self.hcal = pd.tseries.holiday.USFederalHolidayCalendar() + self.day = pd.offsets.Day() + self.year = pd.offsets.YearBegin() + self.cday = pd.offsets.CustomBusinessDay() + self.cmb = pd.offsets.CustomBusinessMonthBegin(calendar=self.hcal) + self.cme = pd.offsets.CustomBusinessMonthEnd(calendar=self.hcal) + self.cdayh = pd.offsets.CustomBusinessDay(calendar=self.hcal) + + def time_timeseries_custom_bday_cal_incr(self): + (self.date + (1 * self.cdayh)) + + +class timeseries_custom_bday_cal_incr_n(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.date = dt.datetime(2011, 1, 1) + self.dt64 = np.datetime64('2011-01-01 09:00Z') + self.hcal = pd.tseries.holiday.USFederalHolidayCalendar() + self.day = pd.offsets.Day() + self.year = pd.offsets.YearBegin() + self.cday = pd.offsets.CustomBusinessDay() + self.cmb = pd.offsets.CustomBusinessMonthBegin(calendar=self.hcal) + self.cme = pd.offsets.CustomBusinessMonthEnd(calendar=self.hcal) + self.cdayh = pd.offsets.CustomBusinessDay(calendar=self.hcal) + + def time_timeseries_custom_bday_cal_incr_n(self): + (self.date + (10 * self.cdayh)) + + +class timeseries_custom_bday_cal_incr_neg_n(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.date = dt.datetime(2011, 1, 1) + self.dt64 = np.datetime64('2011-01-01 09:00Z') + self.hcal = pd.tseries.holiday.USFederalHolidayCalendar() + self.day = pd.offsets.Day() + self.year = pd.offsets.YearBegin() + self.cday = pd.offsets.CustomBusinessDay() + self.cmb = pd.offsets.CustomBusinessMonthBegin(calendar=self.hcal) + self.cme = pd.offsets.CustomBusinessMonthEnd(calendar=self.hcal) + self.cdayh = pd.offsets.CustomBusinessDay(calendar=self.hcal) + + def time_timeseries_custom_bday_cal_incr_neg_n(self): + (self.date - (10 * self.cdayh)) + + +class timeseries_custom_bday_decr(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.date = dt.datetime(2011, 1, 1) + self.dt64 = np.datetime64('2011-01-01 09:00Z') + self.hcal = pd.tseries.holiday.USFederalHolidayCalendar() + self.day = pd.offsets.Day() + self.year = pd.offsets.YearBegin() + self.cday = pd.offsets.CustomBusinessDay() + self.cmb = pd.offsets.CustomBusinessMonthBegin(calendar=self.hcal) + self.cme = pd.offsets.CustomBusinessMonthEnd(calendar=self.hcal) + self.cdayh = pd.offsets.CustomBusinessDay(calendar=self.hcal) + + def time_timeseries_custom_bday_decr(self): + (self.date - self.cday) + + +class timeseries_custom_bday_incr(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.date = dt.datetime(2011, 1, 1) + self.dt64 = np.datetime64('2011-01-01 09:00Z') + self.hcal = pd.tseries.holiday.USFederalHolidayCalendar() + self.day = pd.offsets.Day() + self.year = pd.offsets.YearBegin() + self.cday = pd.offsets.CustomBusinessDay() + self.cmb = pd.offsets.CustomBusinessMonthBegin(calendar=self.hcal) + self.cme = pd.offsets.CustomBusinessMonthEnd(calendar=self.hcal) + self.cdayh = pd.offsets.CustomBusinessDay(calendar=self.hcal) + + def time_timeseries_custom_bday_incr(self): + (self.date + self.cday) + + +class timeseries_custom_bmonthbegin_decr_n(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.date = dt.datetime(2011, 1, 1) + self.dt64 = np.datetime64('2011-01-01 09:00Z') + self.hcal = pd.tseries.holiday.USFederalHolidayCalendar() + self.day = pd.offsets.Day() + self.year = pd.offsets.YearBegin() + self.cday = pd.offsets.CustomBusinessDay() + self.cmb = pd.offsets.CustomBusinessMonthBegin(calendar=self.hcal) + self.cme = pd.offsets.CustomBusinessMonthEnd(calendar=self.hcal) + self.cdayh = pd.offsets.CustomBusinessDay(calendar=self.hcal) + + def time_timeseries_custom_bmonthbegin_decr_n(self): + (self.date - (10 * self.cmb)) + + +class timeseries_custom_bmonthbegin_incr_n(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.date = dt.datetime(2011, 1, 1) + self.dt64 = np.datetime64('2011-01-01 09:00Z') + self.hcal = pd.tseries.holiday.USFederalHolidayCalendar() + self.day = pd.offsets.Day() + self.year = pd.offsets.YearBegin() + self.cday = pd.offsets.CustomBusinessDay() + self.cmb = pd.offsets.CustomBusinessMonthBegin(calendar=self.hcal) + self.cme = pd.offsets.CustomBusinessMonthEnd(calendar=self.hcal) + self.cdayh = pd.offsets.CustomBusinessDay(calendar=self.hcal) + + def time_timeseries_custom_bmonthbegin_incr_n(self): + (self.date + (10 * self.cmb)) + + +class timeseries_custom_bmonthend_decr_n(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.date = dt.datetime(2011, 1, 1) + self.dt64 = np.datetime64('2011-01-01 09:00Z') + self.hcal = pd.tseries.holiday.USFederalHolidayCalendar() + self.day = pd.offsets.Day() + self.year = pd.offsets.YearBegin() + self.cday = pd.offsets.CustomBusinessDay() + self.cmb = pd.offsets.CustomBusinessMonthBegin(calendar=self.hcal) + self.cme = pd.offsets.CustomBusinessMonthEnd(calendar=self.hcal) + self.cdayh = pd.offsets.CustomBusinessDay(calendar=self.hcal) + + def time_timeseries_custom_bmonthend_decr_n(self): + (self.date - (10 * self.cme)) + + +class timeseries_custom_bmonthend_incr(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.date = dt.datetime(2011, 1, 1) + self.dt64 = np.datetime64('2011-01-01 09:00Z') + self.hcal = pd.tseries.holiday.USFederalHolidayCalendar() + self.day = pd.offsets.Day() + self.year = pd.offsets.YearBegin() + self.cday = pd.offsets.CustomBusinessDay() + self.cmb = pd.offsets.CustomBusinessMonthBegin(calendar=self.hcal) + self.cme = pd.offsets.CustomBusinessMonthEnd(calendar=self.hcal) + self.cdayh = pd.offsets.CustomBusinessDay(calendar=self.hcal) + + def time_timeseries_custom_bmonthend_incr(self): + (self.date + self.cme) + + +class timeseries_custom_bmonthend_incr_n(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.date = dt.datetime(2011, 1, 1) + self.dt64 = np.datetime64('2011-01-01 09:00Z') + self.hcal = pd.tseries.holiday.USFederalHolidayCalendar() + self.day = pd.offsets.Day() + self.year = pd.offsets.YearBegin() + self.cday = pd.offsets.CustomBusinessDay() + self.cmb = pd.offsets.CustomBusinessMonthBegin(calendar=self.hcal) + self.cme = pd.offsets.CustomBusinessMonthEnd(calendar=self.hcal) + self.cdayh = pd.offsets.CustomBusinessDay(calendar=self.hcal) + + def time_timeseries_custom_bmonthend_incr_n(self): + (self.date + (10 * self.cme)) + + +class timeseries_day_apply(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.date = dt.datetime(2011, 1, 1) + self.dt64 = np.datetime64('2011-01-01 09:00Z') + self.hcal = pd.tseries.holiday.USFederalHolidayCalendar() + self.day = pd.offsets.Day() + self.year = pd.offsets.YearBegin() + self.cday = pd.offsets.CustomBusinessDay() + self.cmb = pd.offsets.CustomBusinessMonthBegin(calendar=self.hcal) + self.cme = pd.offsets.CustomBusinessMonthEnd(calendar=self.hcal) + self.cdayh = pd.offsets.CustomBusinessDay(calendar=self.hcal) + + def time_timeseries_day_apply(self): + self.day.apply(self.date) + + +class timeseries_day_incr(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.date = dt.datetime(2011, 1, 1) + self.dt64 = np.datetime64('2011-01-01 09:00Z') + self.hcal = pd.tseries.holiday.USFederalHolidayCalendar() + self.day = pd.offsets.Day() + self.year = pd.offsets.YearBegin() + self.cday = pd.offsets.CustomBusinessDay() + self.cmb = pd.offsets.CustomBusinessMonthBegin(calendar=self.hcal) + self.cme = pd.offsets.CustomBusinessMonthEnd(calendar=self.hcal) + self.cdayh = pd.offsets.CustomBusinessDay(calendar=self.hcal) + + def time_timeseries_day_incr(self): + (self.date + self.day) + + +class timeseries_infer_freq(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.rng = date_range(start='1/1/1700', freq='D', periods=100000) + self.a = self.rng[:50000].append(self.rng[50002:]) + + def time_timeseries_infer_freq(self): + infer_freq(self.a) + + +class timeseries_is_month_start(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.N = 10000 + self.rng = date_range(start='1/1/1', periods=self.N, freq='B') + + def time_timeseries_is_month_start(self): + self.rng.is_month_start + + +class timeseries_iter_datetimeindex(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.N = 1000000 + self.M = 10000 + self.idx1 = date_range(start='20140101', freq='T', periods=self.N) + self.idx2 = period_range(start='20140101', freq='T', periods=self.N) + + def iter_n(iterable, n=None): + self.i = 0 + for _ in iterable: + self.i += 1 + if ((n is not None) and (self.i > n)): + break + + def time_timeseries_iter_datetimeindex(self): + iter_n(self.idx1) + + +class timeseries_iter_datetimeindex_preexit(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.N = 1000000 + self.M = 10000 + self.idx1 = date_range(start='20140101', freq='T', periods=self.N) + self.idx2 = period_range(start='20140101', freq='T', periods=self.N) + + def iter_n(iterable, n=None): + self.i = 0 + for _ in iterable: + self.i += 1 + if ((n is not None) and (self.i > n)): + break + + def time_timeseries_iter_datetimeindex_preexit(self): + iter_n(self.idx1, self.M) + + +class timeseries_iter_periodindex(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.N = 1000000 + self.M = 10000 + self.idx1 = date_range(start='20140101', freq='T', periods=self.N) + self.idx2 = period_range(start='20140101', freq='T', periods=self.N) + + def iter_n(iterable, n=None): + self.i = 0 + for _ in iterable: + self.i += 1 + if ((n is not None) and (self.i > n)): + break + + def time_timeseries_iter_periodindex(self): + iter_n(self.idx2) + + +class timeseries_iter_periodindex_preexit(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.N = 1000000 + self.M = 10000 + self.idx1 = date_range(start='20140101', freq='T', periods=self.N) + self.idx2 = period_range(start='20140101', freq='T', periods=self.N) + + def iter_n(iterable, n=None): + self.i = 0 + for _ in iterable: + self.i += 1 + if ((n is not None) and (self.i > n)): + break + + def time_timeseries_iter_periodindex_preexit(self): + iter_n(self.idx2, self.M) + + +class timeseries_large_lookup_value(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.rng = date_range(start='1/1/2000', periods=1500000, freq='S') + self.ts = Series(1, index=self.rng) + + def time_timeseries_large_lookup_value(self): + self.ts[self.ts.index[(len(self.ts) // 2)]] + self.ts.index._cleanup() + + +class timeseries_period_downsample_mean(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.rng = period_range(start='1/1/2000', end='1/1/2001', freq='T') + self.ts = Series(np.random.randn(len(self.rng)), index=self.rng) + + def time_timeseries_period_downsample_mean(self): + self.ts.resample('D', how='mean') + + +class timeseries_resample_datetime64(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.rng = date_range(start='2000-01-01 00:00:00', end='2000-01-01 10:00:00', freq='555000U') + self.int_ts = Series(5, self.rng, dtype='int64') + self.ts = self.int_ts.astype('datetime64[ns]') + + def time_timeseries_resample_datetime64(self): + self.ts.resample('1S', how='last') + + +class timeseries_slice_minutely(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + + def time_timeseries_slice_minutely(self): + self.ts[:10000] + + +class timeseries_sort_index(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='s') + self.rng = self.rng.take(np.random.permutation(self.N)) + self.ts = Series(np.random.randn(self.N), index=self.rng) + + def time_timeseries_sort_index(self): + self.ts.sort_index() + + +class timeseries_timestamp_downsample_mean(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.rng = date_range(start='1/1/2000', end='1/1/2001', freq='T') + self.ts = Series(np.random.randn(len(self.rng)), index=self.rng) + + def time_timeseries_timestamp_downsample_mean(self): + self.ts.resample('D', how='mean') + + +class timeseries_timestamp_tzinfo_cons(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.rng = date_range(start='1/1/2000', end='3/1/2000', tz='US/Eastern') + + def time_timeseries_timestamp_tzinfo_cons(self): + self.rng[0] + + +class timeseries_to_datetime_YYYYMMDD(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.rng = date_range(start='1/1/2000', periods=10000, freq='D') + self.strings = Series((((self.rng.year * 10000) + (self.rng.month * 100)) + self.rng.day), dtype=np.int64).apply(str) + + def time_timeseries_to_datetime_YYYYMMDD(self): + to_datetime(self.strings, format='%Y%m%d') + + +class timeseries_to_datetime_iso8601(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.rng = date_range(start='1/1/2000', periods=20000, freq='H') + self.strings = [x.strftime('%Y-%m-%d %H:%M:%S') for x in self.rng] + + def time_timeseries_to_datetime_iso8601(self): + to_datetime(self.strings) + + +class timeseries_to_datetime_iso8601_format(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.rng = date_range(start='1/1/2000', periods=20000, freq='H') + self.strings = [x.strftime('%Y-%m-%d %H:%M:%S') for x in self.rng] + + def time_timeseries_to_datetime_iso8601_format(self): + to_datetime(self.strings, format='%Y-%m-%d %H:%M:%S') + + +class timeseries_with_format_no_exact(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.s = Series((['19MAY11', '19MAY11:00:00:00'] * 100000)) + + def time_timeseries_with_format_no_exact(self): + to_datetime(self.s, format='%d%b%y', exact=False) + + +class timeseries_with_format_replace(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.s = Series((['19MAY11', '19MAY11:00:00:00'] * 100000)) + + def time_timeseries_with_format_replace(self): + to_datetime(self.s.str.replace(':\\S+$', ''), format='%d%b%y') + + +class timeseries_year_apply(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.date = dt.datetime(2011, 1, 1) + self.dt64 = np.datetime64('2011-01-01 09:00Z') + self.hcal = pd.tseries.holiday.USFederalHolidayCalendar() + self.day = pd.offsets.Day() + self.year = pd.offsets.YearBegin() + self.cday = pd.offsets.CustomBusinessDay() + self.cmb = pd.offsets.CustomBusinessMonthBegin(calendar=self.hcal) + self.cme = pd.offsets.CustomBusinessMonthEnd(calendar=self.hcal) + self.cdayh = pd.offsets.CustomBusinessDay(calendar=self.hcal) + + def time_timeseries_year_apply(self): + self.year.apply(self.date) + + +class timeseries_year_incr(object): + goal_time = 0.2 + + def setup(self): + self.N = 100000 + self.rng = date_range(start='1/1/2000', periods=self.N, freq='T') + if hasattr(Series, 'convert'): + Series.resample = Series.convert + self.ts = Series(np.random.randn(self.N), index=self.rng) + self.date = dt.datetime(2011, 1, 1) + self.dt64 = np.datetime64('2011-01-01 09:00Z') + self.hcal = pd.tseries.holiday.USFederalHolidayCalendar() + self.day = pd.offsets.Day() + self.year = pd.offsets.YearBegin() + self.cday = pd.offsets.CustomBusinessDay() + self.cmb = pd.offsets.CustomBusinessMonthBegin(calendar=self.hcal) + self.cme = pd.offsets.CustomBusinessMonthEnd(calendar=self.hcal) + self.cdayh = pd.offsets.CustomBusinessDay(calendar=self.hcal) + + def time_timeseries_year_incr(self): + (self.date + self.year) \ No newline at end of file diff --git a/asv_bench/vbench_to_asv.py b/asv_bench/vbench_to_asv.py new file mode 100644 index 0000000000000..b3980ffed1a57 --- /dev/null +++ b/asv_bench/vbench_to_asv.py @@ -0,0 +1,151 @@ +import ast +import vbench +import os +import sys +import astor +import glob + + +def vbench_to_asv_source(bench, kinds=None): + tab = ' ' * 4 + if kinds is None: + kinds = ['time'] + + output = 'class {}(object):\n'.format(bench.name) + output += tab + 'goal_time = 0.2\n\n' + + if bench.setup: + indented_setup = [tab * 2 + '{}\n'.format(x) for x in bench.setup.splitlines()] + output += tab + 'def setup(self):\n' + ''.join(indented_setup) + '\n' + + for kind in kinds: + output += tab + 'def {}_{}(self):\n'.format(kind, bench.name) + for line in bench.code.splitlines(): + output += tab * 2 + line + '\n' + output += '\n\n' + + if bench.cleanup: + output += tab + 'def teardown(self):\n' + tab * 2 + bench.cleanup + + output += '\n\n' + return output + + +class AssignToSelf(ast.NodeTransformer): + def __init__(self): + super(AssignToSelf, self).__init__() + self.transforms = {} + self.imports = [] + + self.in_class_define = False + self.in_setup = False + + def visit_ClassDef(self, node): + self.transforms = {} + self.in_class_define = True + self.generic_visit(node) + return node + + def visit_TryExcept(self, node): + if any([isinstance(x, (ast.Import, ast.ImportFrom)) for x in node.body]): + self.imports.append(node) + else: + self.generic_visit(node) + return node + + def visit_Assign(self, node): + for target in node.targets: + if isinstance(target, ast.Name) and not isinstance(target.ctx, ast.Param) and not self.in_class_define: + self.transforms[target.id] = 'self.' + target.id + self.generic_visit(node) + + return node + + def visit_Name(self, node): + new_node = node + if node.id in self.transforms: + if not isinstance(node.ctx, ast.Param): + new_node = ast.Attribute(value=ast.Name(id='self', ctx=node.ctx), attr=node.id, ctx=node.ctx) + + self.generic_visit(node) + + return ast.copy_location(new_node, node) + + def visit_Import(self, node): + self.imports.append(node) + + def visit_ImportFrom(self, node): + self.imports.append(node) + + def visit_FunctionDef(self, node): + """Delete functions that are empty due to imports being moved""" + self.in_class_define = False + + if self.in_setup: + node.col_offset -= 4 + ast.increment_lineno(node, -1) + + if node.name == 'setup': + self.in_setup = True + + self.generic_visit(node) + + if node.name == 'setup': + self.in_setup = False + + if node.body: + return node + + +def translate_module(target_module): + g_vars = {} + l_vars = {} + exec('import ' + target_module) in g_vars + + print target_module + module = eval(target_module, g_vars) + + benchmarks = [] + for obj_str in dir(module): + obj = getattr(module, obj_str) + if isinstance(obj, vbench.benchmark.Benchmark): + benchmarks.append(obj) + + if not benchmarks: + return + + rewritten_output = '' + for bench in benchmarks: + rewritten_output += vbench_to_asv_source(bench) + + with open('rewrite.py', 'w') as f: + f.write(rewritten_output) + + ast_module = ast.parse(rewritten_output) + + transformer = AssignToSelf() + transformed_module = transformer.visit(ast_module) + + unique_imports = {astor.to_source(node): node for node in transformer.imports} + + transformed_module.body = unique_imports.values() + transformed_module.body + + transformed_source = astor.to_source(transformed_module) + + with open('benchmarks/{}.py'.format(target_module), 'w') as f: + f.write(transformed_source) + + +if __name__ == '__main__': + cwd = os.getcwd() + new_dir = os.path.join(os.path.dirname(__file__), '../vb_suite') + sys.path.insert(0, new_dir) + + for module in glob.glob(os.path.join(new_dir, '*.py')): + mod = os.path.basename(module) + if mod in ['make.py', 'measure_memory_consumption.py', 'perf_HEAD.py', 'run_suite.py', 'test_perf.py', 'generate_rst_files.py', 'test.py', 'suite.py']: + continue + print + print mod + + translate_module(mod.replace('.py', '')) diff --git a/bench/bench_sparse.py b/bench/bench_sparse.py index 7dc2db05cfe20..0aa705118d970 100644 --- a/bench/bench_sparse.py +++ b/bench/bench_sparse.py @@ -1,4 +1,3 @@ -import sys import numpy as np from pandas import * @@ -30,7 +29,7 @@ s1_dense = s1.to_dense() s2_dense = s2.to_dense() -if 'linux' in sys.platform: +if compat.is_platform_linux(): pth = '/home/wesm/code/pandas/example' else: pth = '/Users/wesm/code/pandas/example' diff --git a/ci/requirements-2.7.txt b/ci/requirements-2.7.txt index 0d515f300f5a7..951c8798bef15 100644 --- a/ci/requirements-2.7.txt +++ b/ci/requirements-2.7.txt @@ -17,7 +17,7 @@ boto=2.36.0 bottleneck=0.8.0 psycopg2=2.5.2 patsy -pymysql=0.6.1 +pymysql=0.6.3 html5lib=1.0b2 beautiful-soup=4.2.1 httplib2=0.8 diff --git a/ci/requirements-3.2.txt b/ci/requirements-3.2.txt deleted file mode 100644 index 8c2f675b65603..0000000000000 --- a/ci/requirements-3.2.txt +++ /dev/null @@ -1,4 +0,0 @@ -python-dateutil==2.1 -pytz==2013b -numpy==1.7.1 -cython==0.19.1 diff --git a/ci/requirements-3.4.txt b/ci/requirements-3.4.txt index 24af93fb16194..fd0a5bc53dd7e 100644 --- a/ci/requirements-3.4.txt +++ b/ci/requirements-3.4.txt @@ -3,6 +3,7 @@ pytz openpyxl xlsxwriter xlrd +xlwt html5lib patsy beautiful-soup diff --git a/ci/requirements-3.4_SLOW.txt b/ci/requirements-3.4_SLOW.txt index 6372d9b4f6068..ecc31dad78d07 100644 --- a/ci/requirements-3.4_SLOW.txt +++ b/ci/requirements-3.4_SLOW.txt @@ -3,6 +3,7 @@ pytz openpyxl xlsxwriter xlrd +xlwt html5lib patsy beautiful-soup diff --git a/ci/script.sh b/ci/script.sh index d5082234024d5..1126e8249646c 100755 --- a/ci/script.sh +++ b/ci/script.sh @@ -15,8 +15,8 @@ fi if [ "$BUILD_TEST" ]; then echo "We are not running nosetests as this is simply a build test." else - echo nosetests --exe -A "$NOSE_ARGS" pandas --with-xunit --xunit-file=/tmp/nosetests.xml - nosetests --exe -A "$NOSE_ARGS" pandas --with-xunit --xunit-file=/tmp/nosetests.xml + echo nosetests --exe -A "$NOSE_ARGS" pandas --doctest-tests --with-xunit --xunit-file=/tmp/nosetests.xml + nosetests --exe -A "$NOSE_ARGS" pandas --doctest-tests --with-xunit --xunit-file=/tmp/nosetests.xml fi RET="$?" diff --git a/conda.recipe/bld.bat b/conda.recipe/bld.bat index cc977c65dcbe1..284926fae8c04 100644 --- a/conda.recipe/bld.bat +++ b/conda.recipe/bld.bat @@ -1,2 +1,2 @@ @echo off -%PYTHON% setup.py install --quiet +%PYTHON% setup.py install diff --git a/conda.recipe/build.sh b/conda.recipe/build.sh index bce23bf0c6549..f341bce6fcf96 100644 --- a/conda.recipe/build.sh +++ b/conda.recipe/build.sh @@ -1,2 +1,2 @@ -#!/bin/bash -$PYTHON setup.py install --quiet +#!/bin/sh +$PYTHON setup.py install diff --git a/conda.recipe/meta.yaml b/conda.recipe/meta.yaml index 6817fbc9b43e0..6f0fd4fda47a3 100644 --- a/conda.recipe/meta.yaml +++ b/conda.recipe/meta.yaml @@ -1,6 +1,6 @@ package: - name: pandas - version: {{ environ.get('GIT_DESCRIBE_TAG', '') }} + name: pandas + version: {{ environ.get('GIT_DESCRIBE_TAG', '').replace('.dev', 'dev') }} build: number: {{ environ.get('GIT_DESCRIBE_NUMBER', 0) }} @@ -28,10 +28,9 @@ requirements: test: requires: - nose - - coverage commands: - - python -c "import pandas" + - nosetests --exe -A "not slow and not network and not disabled" pandas about: home: http://pandas.pydata.org diff --git a/doc/source/api.rst b/doc/source/api.rst index 76e03ce70342f..6b188deb9eb42 100644 --- a/doc/source/api.rst +++ b/doc/source/api.rst @@ -82,6 +82,15 @@ HDFStore: PyTables (HDF5) HDFStore.get HDFStore.select +SAS +~~~ + +.. autosummary:: + :toctree: generated/ + + read_sas + XportReader + SQL ~~~ @@ -509,6 +518,7 @@ These can be accessed like ``Series.dt.``. Series.dt.tz_localize Series.dt.tz_convert Series.dt.normalize + Series.dt.strftime **Timedelta Properties** @@ -798,9 +808,7 @@ Binary operator functions DataFrame.ne DataFrame.eq DataFrame.combine - DataFrame.combineAdd DataFrame.combine_first - DataFrame.combineMult Function application, GroupBy ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -903,6 +911,8 @@ Reshaping, sorting, transposing DataFrame.sort DataFrame.sort_index DataFrame.sortlevel + DataFrame.nlargest + DataFrame.nsmallest DataFrame.swaplevel DataFrame.stack DataFrame.unstack @@ -1443,6 +1453,7 @@ Conversion DatetimeIndex.to_datetime DatetimeIndex.to_period + DatetimeIndex.to_perioddelta DatetimeIndex.to_pydatetime DatetimeIndex.to_series @@ -1558,7 +1569,6 @@ application to columns of a specific data type. DataFrameGroupBy.hist DataFrameGroupBy.idxmax DataFrameGroupBy.idxmin - DataFrameGroupBy.irow DataFrameGroupBy.mad DataFrameGroupBy.pct_change DataFrameGroupBy.plot diff --git a/doc/source/basics.rst b/doc/source/basics.rst index 349e7e25fdafb..71d16a40f0215 100644 --- a/doc/source/basics.rst +++ b/doc/source/basics.rst @@ -240,14 +240,14 @@ way to summarize a boolean result. .. ipython:: python - (df>0).all() - (df>0).any() + (df > 0).all() + (df > 0).any() You can reduce to a final boolean value. .. ipython:: python - (df>0).any().any() + (df > 0).any().any() You can test if a pandas object is empty, via the :attr:`~DataFrame.empty` property. @@ -330,6 +330,48 @@ equality to be True: df1.equals(df2) df1.equals(df2.sort()) +Comparing array-like objects +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can conveniently do element-wise comparisons when comparing a pandas +data structure with a scalar value: + +.. ipython:: python + + pd.Series(['foo', 'bar', 'baz']) == 'foo' + pd.Index(['foo', 'bar', 'baz']) == 'foo' + +Pandas also handles element-wise comparisons between different array-like +objects of the same length: + +.. ipython:: python + + pd.Series(['foo', 'bar', 'baz']) == pd.Index(['foo', 'bar', 'qux']) + pd.Series(['foo', 'bar', 'baz']) == np.array(['foo', 'bar', 'qux']) + +Trying to compare ``Index`` or ``Series`` objects of different lengths will +raise a ValueError: + +.. code-block:: python + + In [55]: pd.Series(['foo', 'bar', 'baz']) == pd.Series(['foo', 'bar']) + ValueError: Series lengths must match to compare + + In [56]: pd.Series(['foo', 'bar', 'baz']) == pd.Series(['foo']) + ValueError: Series lengths must match to compare + +Note that this is different from the numpy behavior where a comparison can +be broadcast: + +.. ipython:: python + + np.array([1, 2, 3]) == np.array([2]) + +or it can return False if broadcasting can not be done: + +.. ipython:: python + + np.array([1, 2, 3]) == np.array([1, 2]) Combining overlapping data sets ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1058,6 +1100,30 @@ Note that the same result could have been achieved using increasing or descreasing. :meth:`~Series.fillna` and :meth:`~Series.interpolate` will not make any checks on the order of the index. +.. _basics.limits_on_reindex_fill: + +Limits on filling while reindexing +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``limit`` and ``tolerance`` arguments provide additional control over +filling while reindexing. Limit specifies the maximum count of consecutive +matches: + +.. ipython:: python + + ts2.reindex(ts.index, method='ffill', limit=1) + +In contrast, tolerance specifies the maximum distance between the index and +indexer values: + +.. ipython:: python + + ts2.reindex(ts.index, method='ffill', tolerance='1 day') + +Notice that when used on a ``DatetimeIndex``, ``TimedeltaIndex`` or +``PeriodIndex``, ``tolerance`` will coerced into a ``Timedelta`` if possible. +This allows you to specify tolerance with appropriate strings. + .. _basics.drop: Dropping labels from an axis @@ -1109,24 +1175,81 @@ parameter that is by default ``False`` and copies the underlying data. Pass The Panel class has a related :meth:`~Panel.rename_axis` class which can rename any of its three axes. +.. _basics.iteration: + Iteration --------- -Because Series is array-like, basic iteration produces the values. Other data -structures follow the dict-like convention of iterating over the "keys" of the -objects. In short: +The behavior of basic iteration over pandas objects depends on the type. +When iterating over a Series, it is regarded as array-like, and basic iteration +produces the values. Other data structures, like DataFrame and Panel, +follow the dict-like convention of iterating over the "keys" of the +objects. - * **Series**: values - * **DataFrame**: column labels - * **Panel**: item labels +In short, basic iteration (``for i in object``) produces: -Thus, for example: +* **Series**: values +* **DataFrame**: column labels +* **Panel**: item labels + +Thus, for example, iterating over a DataFrame gives you the column names: .. ipython:: - In [0]: for col in df: - ...: print(col) - ...: + In [0]: df = pd.DataFrame({'col1' : np.random.randn(3), 'col2' : np.random.randn(3)}, + ...: index=['a', 'b', 'c']) + + In [0]: for col in df: + ...: print(col) + ...: + +Pandas objects also have the dict-like :meth:`~DataFrame.iteritems` method to +iterate over the (key, value) pairs. + +To iterate over the rows of a DataFrame, you can use the following methods: + +* :meth:`~DataFrame.iterrows`: Iterate over the rows of a DataFrame as (index, Series) pairs. + This converts the rows to Series objects, which can change the dtypes and has some + performance implications. +* :meth:`~DataFrame.itertuples`: Iterate over the rows of a DataFrame as tuples of the values. + This is a lot faster as :meth:`~DataFrame.iterrows`, and is in most cases preferable to + use to iterate over the values of a DataFrame. + +.. warning:: + + Iterating through pandas objects is generally **slow**. In many cases, + iterating manually over the rows is not needed and can be avoided with + one of the following approaches: + + * Look for a *vectorized* solution: many operations can be performed using + built-in methods or numpy functions, (boolean) indexing, ... + + * When you have a function that cannot work on the full DataFrame/Series + at once, it is better to use :meth:`~DataFrame.apply` instead of iterating + over the values. See the docs on :ref:`function application `. + + * If you need to do iterative manipulations on the values but performance is + important, consider writing the inner loop using e.g. cython or numba. + See the :ref:`enhancing performance ` section for some + examples of this approach. + +.. warning:: + + You should **never modify** something you are iterating over. + This is not guaranteed to work in all cases. Depending on the + data types, the iterator returns a copy and not a view, and writing + to it will have no effect! + + For example, in the following case setting the value has no effect: + + .. ipython:: python + + df = pd.DataFrame({'a': [1, 2, 3], 'b': ['a', 'b', 'c']}) + + for index, row in df.iterrows(): + row['a'] = 10 + + df iteritems ~~~~~~~~~ @@ -1134,9 +1257,9 @@ iteritems Consistent with the dict-like interface, :meth:`~DataFrame.iteritems` iterates through key-value pairs: - * **Series**: (index, scalar value) pairs - * **DataFrame**: (column, Series) pairs - * **Panel**: (item, DataFrame) pairs +* **Series**: (index, scalar value) pairs +* **DataFrame**: (column, Series) pairs +* **Panel**: (item, DataFrame) pairs For example: @@ -1147,22 +1270,46 @@ For example: ...: print(frame) ...: - .. _basics.iterrows: iterrows ~~~~~~~~ -New in v0.7 is the ability to iterate efficiently through rows of a -DataFrame with :meth:`~DataFrame.iterrows`. It returns an iterator yielding each +:meth:`~DataFrame.iterrows` allows you to iterate through the rows of a +DataFrame as Series objects. It returns an iterator yielding each index value along with a Series containing the data in each row: .. ipython:: - In [0]: for row_index, row in df2.iterrows(): + In [0]: for row_index, row in df.iterrows(): ...: print('%s\n%s' % (row_index, row)) ...: +.. note:: + + Because :meth:`~DataFrame.iterrows` returns a Series for each row, + it does **not** preserve dtypes across the rows (dtypes are + preserved across columns for DataFrames). For example, + + .. ipython:: python + + df_orig = pd.DataFrame([[1, 1.5]], columns=['int', 'float']) + df_orig.dtypes + row = next(df_orig.iterrows())[1] + row + + All values in ``row``, returned as a Series, are now upcasted + to floats, also the original integer value in column `x`: + + .. ipython:: python + + row['int'].dtype + df_orig['int'].dtype + + To preserve dtypes while iterating over the rows, it is better + to use :meth:`~DataFrame.itertuples` which returns tuples of the values + and which is generally much faster as ``iterrows``. + For instance, a contrived way to transpose the DataFrame would be: .. ipython:: python @@ -1174,45 +1321,38 @@ For instance, a contrived way to transpose the DataFrame would be: df2_t = pd.DataFrame(dict((idx,values) for idx, values in df2.iterrows())) print(df2_t) -.. note:: - - ``iterrows`` does **not** preserve dtypes across the rows (dtypes are - preserved across columns for DataFrames). For example, - - .. ipython:: python - - df_iter = pd.DataFrame([[1, 1.0]], columns=['x', 'y']) - row = next(df_iter.iterrows())[1] - print(row['x'].dtype) - print(df_iter['x'].dtype) - itertuples ~~~~~~~~~~ -The :meth:`~DataFrame.itertuples` method will return an iterator yielding a tuple for each row in the -DataFrame. The first element of the tuple will be the row's corresponding index -value, while the remaining values are the row values proper. +The :meth:`~DataFrame.itertuples` method will return an iterator +yielding a tuple for each row in the DataFrame. The first element +of the tuple will be the row's corresponding index value, +while the remaining values are the row values. For instance, .. ipython:: python - for r in df2.itertuples(): - print(r) + for row in df.itertuples(): + print(row) + +This method does not convert the row to a Series object but just returns the +values inside a tuple. Therefore, :meth:`~DataFrame.itertuples` preserves the +data type of the values and is generally faster as :meth:`~DataFrame.iterrows`. .. _basics.dt_accessors: .dt accessor -~~~~~~~~~~~~ +------------ ``Series`` has an accessor to succinctly return datetime like properties for the -*values* of the Series, if its a datetime/period like Series. +*values* of the Series, if it is a datetime/period like Series. This will return a Series, indexed like the existing Series. .. ipython:: python # datetime - s = pd.Series(pd.date_range('20130101 09:10:12',periods=4)) + s = pd.Series(pd.date_range('20130101 09:10:12', periods=4)) s s.dt.hour s.dt.second @@ -1238,12 +1378,29 @@ You can also chain these types of operations: s.dt.tz_localize('UTC').dt.tz_convert('US/Eastern') +You can also format datetime values as strings with :meth:`Series.dt.strftime` which +supports the same format as the standard :meth:`~datetime.datetime.strftime`. + +.. ipython:: python + + # DatetimeIndex + s = pd.Series(pd.date_range('20130101', periods=4)) + s + s.dt.strftime('%Y/%m/%d') + +.. ipython:: python + + # PeriodIndex + s = pd.Series(pd.period_range('20130101', periods=4)) + s + s.dt.strftime('%Y/%m/%d') + The ``.dt`` accessor works for period and timedelta dtypes. .. ipython:: python # period - s = pd.Series(pd.period_range('20130101', periods=4,freq='D')) + s = pd.Series(pd.period_range('20130101', periods=4, freq='D')) s s.dt.year s.dt.day @@ -1251,7 +1408,7 @@ The ``.dt`` accessor works for period and timedelta dtypes. .. ipython:: python # timedelta - s = pd.Series(pd.timedelta_range('1 day 00:00:05',periods=4,freq='s')) + s = pd.Series(pd.timedelta_range('1 day 00:00:05', periods=4, freq='s')) s s.dt.days s.dt.seconds @@ -1364,6 +1521,20 @@ faster than sorting the entire Series and calling ``head(n)`` on the result. s.nsmallest(3) s.nlargest(3) +.. versionadded:: 0.17.0 + +``DataFrame`` also has the ``nlargest`` and ``nsmallest`` methods. + +.. ipython:: python + + df = pd.DataFrame({'a': [-2, -1, 1, 10, 8, 11, -1], + 'b': list('abdceff'), + 'c': [1.0, 2.0, 4.0, 3.2, np.nan, 3.0, 4.0]}) + df.nlargest(3, 'a') + df.nlargest(5, ['a', 'c']) + df.nsmallest(3, 'a') + df.nsmallest(5, ['a', 'c']) + .. _basics.multi-index_sorting: @@ -1522,26 +1693,36 @@ then the more *general* one will be used as the result of the operation. object conversion ~~~~~~~~~~~~~~~~~ -:meth:`~DataFrame.convert_objects` is a method to try to force conversion of types from the ``object`` dtype to other types. -To force conversion of specific types that are *number like*, e.g. could be a string that represents a number, -pass ``convert_numeric=True``. This will force strings and numbers alike to be numbers if possible, otherwise -they will be set to ``np.nan``. +.. note:: + + The syntax of :meth:`~DataFrame.convert_objects` changed in 0.17.0. See + :ref:`API changes ` + for more details. + +:meth:`~DataFrame.convert_objects` is a method that converts columns from +the ``object`` dtype to datetimes, timedeltas or floats. For example, to +attempt conversion of object data that are *number like*, e.g. could be a +string that represents a number, pass ``numeric=True``. By default, this will +attempt a soft conversion and so will only succeed if the entire column is +convertible. To force the conversion, add the keyword argument ``coerce=True``. +This will force strings and number-like objects to be numbers if +possible, and other values will be set to ``np.nan``. .. ipython:: python df3['D'] = '1.' df3['E'] = '1' - df3.convert_objects(convert_numeric=True).dtypes + df3.convert_objects(numeric=True).dtypes # same, but specific dtype conversion df3['D'] = df3['D'].astype('float16') df3['E'] = df3['E'].astype('int32') df3.dtypes -To force conversion to ``datetime64[ns]``, pass ``convert_dates='coerce'``. +To force conversion to ``datetime64[ns]``, pass ``datetime=True`` and ``coerce=True``. This will convert any datetime-like object to dates, forcing other values to ``NaT``. This might be useful if you are reading in data which is mostly dates, -but occasionally has non-dates intermixed and you want to represent as missing. +but occasionally contains non-dates that you wish to represent as missing. .. ipython:: python @@ -1550,10 +1731,15 @@ but occasionally has non-dates intermixed and you want to represent as missing. 'foo', 1.0, 1, pd.Timestamp('20010104'), '20010105'], dtype='O') s - s.convert_objects(convert_dates='coerce') + s.convert_objects(datetime=True, coerce=True) -In addition, :meth:`~DataFrame.convert_objects` will attempt the *soft* conversion of any *object* dtypes, meaning that if all +Without passing ``coerce=True``, :meth:`~DataFrame.convert_objects` will attempt +*soft* conversion of any *object* dtypes, meaning that if all the objects in a Series are of the same type, the Series will have that dtype. +Note that setting ``coerce=True`` does not *convert* arbitrary types to either +``datetime64[ns]`` or ``timedelta64[ns]``. For example, a series containing string +dates will not be converted to a series of datetimes. To convert between types, +see :ref:`converting to timestamps `. gotchas ~~~~~~~ diff --git a/doc/source/conf.py b/doc/source/conf.py index 08fc8483762ab..57c1667dca0c3 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -52,7 +52,7 @@ with open("index.rst") as f: - lines = f.readlines() + index_rst_lines = f.readlines() # only include the slow autosummary feature if we're building the API section # of the docs @@ -60,20 +60,21 @@ # JP: added from sphinxdocs autosummary_generate = False -if any([re.match("\s*api\s*",l) for l in lines]): +if any([re.match("\s*api\s*",l) for l in index_rst_lines]): autosummary_generate = True -ds = [] +files_to_delete = [] for f in os.listdir(os.path.dirname(__file__)): - if (not f.endswith(('.rst'))) or (f.startswith('.')) or os.path.basename(f) == 'index.rst': + if not f.endswith('.rst') or f.startswith('.') or os.path.basename(f) == 'index.rst': continue - _f = f.split('.rst')[0] - if not any([re.match("\s*%s\s*$" % _f,l) for l in lines]): - ds.append(f) + _file_basename = f.split('.rst')[0] + _regex_to_match = "\s*{}\s*$".format(_file_basename) + if not any([re.match(_regex_to_match, line) for line in index_rst_lines]): + files_to_delete.append(f) -if ds: - print("I'm about to DELETE the following:\n%s\n" % list(sorted(ds))) +if files_to_delete: + print("I'm about to DELETE the following:\n%s\n" % list(sorted(files_to_delete))) sys.stdout.write("WARNING: I'd like to delete those to speed up processing (yes/no)? ") if PY3: answer = input() @@ -81,7 +82,7 @@ answer = raw_input() if answer.lower().strip() in ('y','yes'): - for f in ds: + for f in files_to_delete: f = os.path.join(os.path.join(os.path.dirname(__file__),f)) f= os.path.abspath(f) try: diff --git a/doc/source/contributing.rst b/doc/source/contributing.rst index 1f58992dba017..4ec2258df56f2 100644 --- a/doc/source/contributing.rst +++ b/doc/source/contributing.rst @@ -247,6 +247,8 @@ just checked out. There are two primary methods of doing this. from your development directory. Thus, you can always be using the development version on your system without being inside the clone directory. +.. _contributing.documentation: + Contributing to the documentation ================================= @@ -316,6 +318,13 @@ Some other important things to know about the docs: output saved) during the doc build. This way, they will always be up to date, but it makes the doc building a bit more complex. +The utility script ``scripts/api_rst_coverage.py`` can be used to compare +the list of methods documented in ``doc/source/api.rst`` (which is used to generate +the `API Reference `_ page) +and the actual public methods. +It will identify methods documented in in ``doc/source/api.rst`` that are not actually +class methods, and existing methods that are not documented in ``doc/source/api.rst``. + How to build the pandas documentation ------------------------------------- @@ -536,10 +545,23 @@ Documenting your code Changes should be reflected in the release notes located in `doc/source/whatsnew/vx.y.z.txt`. This file contains an ongoing change log for each release. Add an entry to this file to document your fix, enhancement or (unavoidable) breaking change. Make sure to include the -GitHub issue number when adding your entry. +GitHub issue number when adding your entry (using `` :issue:`1234` `` where `1234` is the +issue/pull request number). + +If your code is an enhancement, it is most likely necessary to add usage +examples to the existing documentation. This can be done following the section +regarding documentation :ref:`above `. +Further, to let users know when this feature was added, the ``versionadded`` +directive is used. The sphinx syntax for that is: + +.. code-block:: rst + + .. versionadded:: 0.17.0 -If your code is an enhancement, it is most likely necessary to add usage examples to the -existing documentation. This can be done following the section regarding documentation. +This will put the text *New in version 0.17.0* wherever you put the sphinx +directive. This should also be put in the docstring when adding a new function +or method (`example `__) +or a new keyword argument (`example `__). Contributing your changes to *pandas* ===================================== diff --git a/doc/source/cookbook.rst b/doc/source/cookbook.rst index f69f926296020..9e7b9ad0b7582 100644 --- a/doc/source/cookbook.rst +++ b/doc/source/cookbook.rst @@ -745,6 +745,9 @@ Timeseries `Vectorized Lookup `__ +`Aggregation and plotting time series +`__ + Turn a matrix with hours in columns and days in rows into a continuous row sequence in the form of a time series. `How to rearrange a python pandas DataFrame? `__ @@ -831,6 +834,9 @@ ignore_index is needed in pandas < v0.13, and depending on df construction `Join with a criteria based on the values `__ +`Using searchsorted to merge based on values inside a range +`__ + .. _cookbook.plotting: Plotting @@ -985,8 +991,14 @@ The :ref:`Excel ` docs `Reading from a filelike handle `__ +`Modifying formatting in XlsxWriter output +`__ + .. _cookbook.html: +HTML +**** + `Reading HTML tables from a server that cannot handle the default request header `__ diff --git a/doc/source/dsintro.rst b/doc/source/dsintro.rst index 9221f2685d79b..5a62e7dccea34 100644 --- a/doc/source/dsintro.rst +++ b/doc/source/dsintro.rst @@ -1,18 +1,23 @@ .. currentmodule:: pandas -.. _dsintro: - .. ipython:: python :suppress: import numpy as np - from pandas import * - randn = np.random.randn np.set_printoptions(precision=4, suppress=True) - set_option('display.precision', 4, 'display.max_columns', 8) - options.display.max_rows=15 import pandas as pd + pd.set_option('display.precision', 4, 'display.max_columns', 8) + pd.options.display.max_rows = 15 + + import matplotlib + try: + matplotlib.style.use('ggplot') + except AttributeError: + pd.options.display.mpl_style = 'default' + import matplotlib.pyplot as plt + plt.close('all') +.. _dsintro: ************************ Intro to Data Structures @@ -26,9 +31,7 @@ objects. To get started, import numpy and load pandas into your namespace: .. ipython:: python import numpy as np - # will use a lot in examples - randn = np.random.randn - from pandas import * + import pandas as pd Here is a basic tenet to keep in mind: **data alignment is intrinsic**. The link between labels and data will not be broken unless done so explicitly by you. @@ -36,13 +39,6 @@ between labels and data will not be broken unless done so explicitly by you. We'll give a brief intro to the data structures, then consider all of the broad categories of functionality and methods in separate sections. -When using pandas, we recommend the following import convention: - -.. code-block:: python - - import pandas as pd - - .. _basics.series: Series @@ -60,7 +56,7 @@ labels are collectively referred to as the **index**. The basic method to create :: - >>> s = Series(data, index=index) + >>> s = pd.Series(data, index=index) Here, ``data`` can be many different things: @@ -78,11 +74,11 @@ index is passed, one will be created having values ``[0, ..., len(data) - 1]``. .. ipython:: python - s = Series(randn(5), index=['a', 'b', 'c', 'd', 'e']) + s = pd.Series(np.random.randn(5), index=['a', 'b', 'c', 'd', 'e']) s s.index - Series(randn(5)) + pd.Series(np.random.randn(5)) .. note:: @@ -101,8 +97,8 @@ constructed from the sorted keys of the dict, if possible. .. ipython:: python d = {'a' : 0., 'b' : 1., 'c' : 2.} - Series(d) - Series(d, index=['b', 'c', 'd', 'a']) + pd.Series(d) + pd.Series(d, index=['b', 'c', 'd', 'a']) .. note:: @@ -113,7 +109,7 @@ provided. The value will be repeated to match the length of **index** .. ipython:: python - Series(5., index=['a', 'b', 'c', 'd', 'e']) + pd.Series(5., index=['a', 'b', 'c', 'd', 'e']) Series is ndarray-like ~~~~~~~~~~~~~~~~~~~~~~ @@ -211,7 +207,7 @@ Series can also have a ``name`` attribute: .. ipython:: python - s = Series(np.random.randn(5), name='something') + s = pd.Series(np.random.randn(5), name='something') s s.name @@ -254,13 +250,13 @@ keys. .. ipython:: python - d = {'one' : Series([1., 2., 3.], index=['a', 'b', 'c']), - 'two' : Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd'])} - df = DataFrame(d) + d = {'one' : pd.Series([1., 2., 3.], index=['a', 'b', 'c']), + 'two' : pd.Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd'])} + df = pd.DataFrame(d) df - DataFrame(d, index=['d', 'b', 'a']) - DataFrame(d, index=['d', 'b', 'a'], columns=['two', 'three']) + pd.DataFrame(d, index=['d', 'b', 'a']) + pd.DataFrame(d, index=['d', 'b', 'a'], columns=['two', 'three']) The row and column labels can be accessed respectively by accessing the **index** and **columns** attributes: @@ -286,8 +282,8 @@ result will be ``range(n)``, where ``n`` is the array length. d = {'one' : [1., 2., 3., 4.], 'two' : [4., 3., 2., 1.]} - DataFrame(d) - DataFrame(d, index=['a', 'b', 'c', 'd']) + pd.DataFrame(d) + pd.DataFrame(d, index=['a', 'b', 'c', 'd']) From structured or record array ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -296,12 +292,12 @@ This case is handled identically to a dict of arrays. .. ipython:: python - data = np.zeros((2,),dtype=[('A', 'i4'),('B', 'f4'),('C', 'a10')]) - data[:] = [(1,2.,'Hello'),(2,3.,"World")] + data = np.zeros((2,), dtype=[('A', 'i4'),('B', 'f4'),('C', 'a10')]) + data[:] = [(1,2.,'Hello'), (2,3.,"World")] - DataFrame(data) - DataFrame(data, index=['first', 'second']) - DataFrame(data, columns=['C', 'A', 'B']) + pd.DataFrame(data) + pd.DataFrame(data, index=['first', 'second']) + pd.DataFrame(data, columns=['C', 'A', 'B']) .. note:: @@ -316,9 +312,9 @@ From a list of dicts .. ipython:: python data2 = [{'a': 1, 'b': 2}, {'a': 5, 'b': 10, 'c': 20}] - DataFrame(data2) - DataFrame(data2, index=['first', 'second']) - DataFrame(data2, columns=['a', 'b']) + pd.DataFrame(data2) + pd.DataFrame(data2, index=['first', 'second']) + pd.DataFrame(data2, columns=['a', 'b']) .. _basics.dataframe.from_dict_of_tuples: @@ -329,11 +325,11 @@ You can automatically create a multi-indexed frame by passing a tuples dictionar .. ipython:: python - DataFrame({('a', 'b'): {('A', 'B'): 1, ('A', 'C'): 2}, - ('a', 'a'): {('A', 'C'): 3, ('A', 'B'): 4}, - ('a', 'c'): {('A', 'B'): 5, ('A', 'C'): 6}, - ('b', 'a'): {('A', 'C'): 7, ('A', 'B'): 8}, - ('b', 'b'): {('A', 'D'): 9, ('A', 'B'): 10}}) + pd.DataFrame({('a', 'b'): {('A', 'B'): 1, ('A', 'C'): 2}, + ('a', 'a'): {('A', 'C'): 3, ('A', 'B'): 4}, + ('a', 'c'): {('A', 'B'): 5, ('A', 'C'): 6}, + ('b', 'a'): {('A', 'C'): 7, ('A', 'B'): 8}, + ('b', 'b'): {('A', 'D'): 9, ('A', 'B'): 10}}) .. _basics.dataframe.from_series: @@ -376,7 +372,7 @@ For example: .. ipython:: python data - DataFrame.from_records(data, index='C') + pd.DataFrame.from_records(data, index='C') .. _basics.dataframe.from_items: @@ -391,15 +387,15 @@ of columns: .. ipython:: python - DataFrame.from_items([('A', [1, 2, 3]), ('B', [4, 5, 6])]) + pd.DataFrame.from_items([('A', [1, 2, 3]), ('B', [4, 5, 6])]) If you pass ``orient='index'``, the keys will be the row labels. But in this case you must also pass the desired column names: .. ipython:: python - DataFrame.from_items([('A', [1, 2, 3]), ('B', [4, 5, 6])], - orient='index', columns=['one', 'two', 'three']) + pd.DataFrame.from_items([('A', [1, 2, 3]), ('B', [4, 5, 6])], + orient='index', columns=['one', 'two', 'three']) Column selection, addition, deletion ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -465,7 +461,7 @@ derived from existing columns. .. ipython:: python - iris = read_csv('data/iris.data') + iris = pd.read_csv('data/iris.data') iris.head() (iris.assign(sepal_ratio = iris['SepalWidth'] / iris['SepalLength']) @@ -564,8 +560,8 @@ union of the column and row labels. .. ipython:: python - df = DataFrame(randn(10, 4), columns=['A', 'B', 'C', 'D']) - df2 = DataFrame(randn(7, 3), columns=['A', 'B', 'C']) + df = pd.DataFrame(np.random.randn(10, 4), columns=['A', 'B', 'C', 'D']) + df2 = pd.DataFrame(np.random.randn(7, 3), columns=['A', 'B', 'C']) df + df2 When doing an operation between DataFrame and Series, the default behavior is @@ -583,8 +579,8 @@ also contains dates, the broadcasting will be column-wise: .. ipython:: python :okwarning: - index = date_range('1/1/2000', periods=8) - df = DataFrame(randn(8, 3), index=index, columns=list('ABC')) + index = pd.date_range('1/1/2000', periods=8) + df = pd.DataFrame(np.random.randn(8, 3), index=index, columns=list('ABC')) df type(df['A']) df - df['A'] @@ -619,8 +615,8 @@ Boolean operators work as well: .. ipython:: python - df1 = DataFrame({'a' : [1, 0, 1], 'b' : [0, 1, 1] }, dtype=bool) - df2 = DataFrame({'a' : [0, 1, 1], 'b' : [1, 1, 0] }, dtype=bool) + df1 = pd.DataFrame({'a' : [1, 0, 1], 'b' : [0, 1, 1] }, dtype=bool) + df2 = pd.DataFrame({'a' : [0, 1, 1], 'b' : [1, 1, 0] }, dtype=bool) df1 & df2 df1 | df2 df1 ^ df2 @@ -660,7 +656,7 @@ Similarly, the dot method on Series implements dot product: .. ipython:: python - s1 = Series(np.arange(5,10)) + s1 = pd.Series(np.arange(5,10)) s1.dot(s1) DataFrame is not intended to be a drop-in replacement for ndarray as its @@ -682,7 +678,7 @@ R package): .. ipython:: python - baseball = read_csv('data/baseball.csv') + baseball = pd.read_csv('data/baseball.csv') print(baseball) baseball.info() @@ -704,21 +700,21 @@ default: .. ipython:: python - DataFrame(randn(3, 12)) + pd.DataFrame(np.random.randn(3, 12)) You can change how much to print on a single row by setting the ``display.width`` option: .. ipython:: python - set_option('display.width', 40) # default is 80 + pd.set_option('display.width', 40) # default is 80 - DataFrame(randn(3, 12)) + pd.DataFrame(np.random.randn(3, 12)) .. ipython:: python :suppress: - reset_option('display.width') + pd.reset_option('display.width') You can also disable this feature via the ``expand_frame_repr`` option. This will print the table in one block. @@ -731,8 +727,8 @@ accessed like attributes: .. ipython:: python - df = DataFrame({'foo1' : np.random.randn(5), - 'foo2' : np.random.randn(5)}) + df = pd.DataFrame({'foo1' : np.random.randn(5), + 'foo2' : np.random.randn(5)}) df df.foo1 @@ -770,9 +766,9 @@ From 3D ndarray with optional axis labels .. ipython:: python - wp = Panel(randn(2, 5, 4), items=['Item1', 'Item2'], - major_axis=date_range('1/1/2000', periods=5), - minor_axis=['A', 'B', 'C', 'D']) + wp = pd.Panel(np.random.randn(2, 5, 4), items=['Item1', 'Item2'], + major_axis=pd.date_range('1/1/2000', periods=5), + minor_axis=['A', 'B', 'C', 'D']) wp @@ -781,9 +777,9 @@ From dict of DataFrame objects .. ipython:: python - data = {'Item1' : DataFrame(randn(4, 3)), - 'Item2' : DataFrame(randn(4, 2))} - Panel(data) + data = {'Item1' : pd.DataFrame(np.random.randn(4, 3)), + 'Item2' : pd.DataFrame(np.random.randn(4, 2))} + pd.Panel(data) Note that the values in the dict need only be **convertible to DataFrame**. Thus, they can be any of the other valid inputs to DataFrame as @@ -803,7 +799,7 @@ For example, compare to the construction above: .. ipython:: python - Panel.from_dict(data, orient='minor') + pd.Panel.from_dict(data, orient='minor') Orient is especially useful for mixed-type DataFrames. If you pass a dict of DataFrame objects with mixed-type columns, all of the data will get upcasted to @@ -811,11 +807,11 @@ DataFrame objects with mixed-type columns, all of the data will get upcasted to .. ipython:: python - df = DataFrame({'a': ['foo', 'bar', 'baz'], - 'b': np.random.randn(3)}) + df = pd.DataFrame({'a': ['foo', 'bar', 'baz'], + 'b': np.random.randn(3)}) df data = {'item1': df, 'item2': df} - panel = Panel.from_dict(data, orient='minor') + panel = pd.Panel.from_dict(data, orient='minor') panel['a'] panel['b'] panel['b'].dtypes @@ -838,8 +834,8 @@ a DataFrame with a two-level index to a Panel. .. ipython:: python - midx = MultiIndex(levels=[['one', 'two'], ['x','y']], labels=[[1,1,0,0],[1,0,1,0]]) - df = DataFrame({'A' : [1, 2, 3, 4], 'B': [5, 6, 7, 8]}, index=midx) + midx = pd.MultiIndex(levels=[['one', 'two'], ['x','y']], labels=[[1,1,0,0],[1,0,1,0]]) + df = pd.DataFrame({'A' : [1, 2, 3, 4], 'B': [5, 6, 7, 8]}, index=midx) df.to_panel() .. _dsintro.panel_item_selection: @@ -897,7 +893,7 @@ Another way to change the dimensionality of an object is to ``squeeze`` a 1-len .. ipython:: python wp.reindex(items=['Item1']).squeeze() - wp.reindex(items=['Item1'],minor=['B']).squeeze() + wp.reindex(items=['Item1'], minor=['B']).squeeze() Conversion to DataFrame @@ -910,9 +906,9 @@ method: .. ipython:: python - panel = Panel(np.random.randn(3, 5, 4), items=['one', 'two', 'three'], - major_axis=date_range('1/1/2000', periods=5), - minor_axis=['a', 'b', 'c', 'd']) + panel = pd.Panel(np.random.randn(3, 5, 4), items=['one', 'two', 'three'], + major_axis=pd.date_range('1/1/2000', periods=5), + minor_axis=['a', 'b', 'c', 'd']) panel.to_frame() @@ -931,7 +927,6 @@ containers. DataFrames - **minor_axis**: axis 3, it is the **columns** of each of the DataFrames - ``Panel4D`` is a sub-class of ``Panel``, so most methods that work on Panels are applicable to Panel4D. The following methods are disabled: @@ -944,11 +939,11 @@ From 4D ndarray with optional axis labels .. ipython:: python - p4d = Panel4D(randn(2, 2, 5, 4), - labels=['Label1','Label2'], - items=['Item1', 'Item2'], - major_axis=date_range('1/1/2000', periods=5), - minor_axis=['A', 'B', 'C', 'D']) + p4d = pd.Panel4D(np.random.randn(2, 2, 5, 4), + labels=['Label1','Label2'], + items=['Item1', 'Item2'], + major_axis=pd.date_range('1/1/2000', periods=5), + minor_axis=['A', 'B', 'C', 'D']) p4d @@ -957,9 +952,9 @@ From dict of Panel objects .. ipython:: python - data = { 'Label1' : Panel({ 'Item1' : DataFrame(randn(4, 3)) }), - 'Label2' : Panel({ 'Item2' : DataFrame(randn(4, 2)) }) } - Panel4D(data) + data = { 'Label1' : pd.Panel({ 'Item1' : pd.DataFrame(np.random.randn(4, 3)) }), + 'Label2' : pd.Panel({ 'Item2' : pd.DataFrame(np.random.randn(4, 2)) }) } + pd.Panel4D(data) Note that the values in the dict need only be **convertible to Panels**. Thus, they can be any of the other valid inputs to Panel as per above. @@ -1022,7 +1017,7 @@ Here we slice to a Panel4D. orders = [ 'cool', 'labels','items','major_axis','minor_axis'], slices = { 'labels' : 'labels', 'items' : 'items', 'major_axis' : 'major_axis', 'minor_axis' : 'minor_axis' }, - slicer = Panel4D, + slicer = pd.Panel4D, aliases = { 'major' : 'major_axis', 'minor' : 'minor_axis' }, stat_axis = 2) diff --git a/doc/source/ecosystem.rst b/doc/source/ecosystem.rst index c70b6deade36e..762656ba05bd6 100644 --- a/doc/source/ecosystem.rst +++ b/doc/source/ecosystem.rst @@ -80,6 +80,10 @@ The `Vincent `__ project leverages `Vega < (that in turn, leverages `d3 `__) to create plots . It has great support for pandas data objects. +`Plotly `__ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +`Plotly’s `__ `Python API `__ enables interactive figures and web shareability. Maps, 2D, 3D, and live-streaming graphs are rendered with WebGL and `D3.js `__. The library supports plotting directly from a pandas DataFrame and cloud-based collaboration. Users of `matplotlib, ggplot for Python, and Seaborn `__ can convert figures into interactive web-based plots. Plots can be drawn in `IPython Notebooks `__ , edited with R or MATLAB, modified in a GUI, or embedded in apps and dashboards. Plotly is free for unlimited sharing, and has `cloud `__, `offline `__, or `on-premise `__ accounts for private use. .. _ecosystem.ide: @@ -132,19 +136,19 @@ Pandas DataFrames with timeseries indexes. `pydatastream `_ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -PyDatastream is a Python interface to the +PyDatastream is a Python interface to the `Thomson Dataworks Enterprise (DWE/Datastream) `__ -SOAP API to return indexed Pandas DataFrames or Panels with financial data. +SOAP API to return indexed Pandas DataFrames or Panels with financial data. This package requires valid credentials for this API (non free). `pandaSDMX `_ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -pandaSDMX is an extensible library to retrieve and acquire statistical data -and metadata disseminated in -`SDMX `_ 2.1. This standard is currently supported by +pandaSDMX is an extensible library to retrieve and acquire statistical data +and metadata disseminated in +`SDMX `_ 2.1. This standard is currently supported by the European statistics office (Eurostat) -and the European Central Bank (ECB). Datasets may be returned as pandas Series -or multi-indexed DataFrames. +and the European Central Bank (ECB). Datasets may be returned as pandas Series +or multi-indexed DataFrames. `fredapi `_ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -183,8 +187,16 @@ Out-of-core ------------- `Blaze `__ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Blaze provides a standard API for doing computations with various in-memory and on-disk backends: NumPy, Pandas, SQLAlchemy, MongoDB, PyTables, PySpark. + +`Odo `__ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Odo provides a uniform API for moving data between different formats. It uses +pandas own ``read_csv`` for CSV IO and leverages many existing packages such as +PyTables, h5py, and pymongo to move data between non pandas formats. Its graph +based approach is also extensible by end users for custom formats that may be +too specific for the core of odo. diff --git a/doc/source/enhancingperf.rst b/doc/source/enhancingperf.rst index 517c91c93d821..855a459f48cf4 100644 --- a/doc/source/enhancingperf.rst +++ b/doc/source/enhancingperf.rst @@ -5,17 +5,14 @@ .. ipython:: python :suppress: - import os - import csv - from pandas import DataFrame, Series - import pandas as pd - pd.options.display.max_rows=15 - import numpy as np np.random.seed(123456) - randn = np.random.randn - randint = np.random.randint np.set_printoptions(precision=4, suppress=True) + import pandas as pd + pd.options.display.max_rows=15 + + import os + import csv ********************* @@ -49,7 +46,10 @@ We have a DataFrame to which we want to apply a function row-wise. .. ipython:: python - df = DataFrame({'a': randn(1000), 'b': randn(1000),'N': randint(100, 1000, (1000)), 'x': 'x'}) + df = pd.DataFrame({'a': np.random.randn(1000), + 'b': np.random.randn(1000), + 'N': np.random.randint(100, 1000, (1000)), + 'x': 'x'}) df Here's the function in pure python: @@ -94,7 +94,8 @@ hence we'll concentrate our efforts cythonizing these two functions. Plain cython ~~~~~~~~~~~~ -First we're going to need to import the cython magic function to ipython: +First we're going to need to import the cython magic function to ipython (for +cython versions >=0.21 you can use ``%load_ext Cython``): .. ipython:: python @@ -306,7 +307,14 @@ Numba works by generating optimized machine code using the LLVM compiler infrast You will need to install ``numba``. This is easy with ``conda``, by using: ``conda install numba``, see :ref:`installing using miniconda`. -We simply take the plain python code from above and annotate with the ``@jit`` decorator. +.. note:: + + As of ``numba`` version 0.20, pandas objects cannot be passed directly to numba-compiled functions. Instead, one must pass the ``numpy`` array underlying the ``pandas`` object to the numba-compiled function as demonstrated below. + +Jit +~~~ + +Using ``numba`` to just-in-time compile your code. We simply take the plain python code from above and annotate with the ``@jit`` decorator. .. code-block:: python @@ -335,16 +343,57 @@ We simply take the plain python code from above and annotate with the ``@jit`` d def compute_numba(df): result = apply_integrate_f_numba(df['a'].values, df['b'].values, df['N'].values) - return Series(result, index=df.index, name='result') + return pd.Series(result, index=df.index, name='result') -Similar to above, we directly pass ``numpy`` arrays directly to the numba function. Further -we are wrapping the results to provide a nice interface by passing/returning pandas objects. +Note that we directly pass ``numpy`` arrays to the numba function. ``compute_numba`` is just a wrapper that provides a nicer interface by passing/returning pandas objects. .. code-block:: python In [4]: %timeit compute_numba(df) 1000 loops, best of 3: 798 us per loop +Vectorize +~~~~~~~~~ + +``numba`` can also be used to write vectorized functions that do not require the user to explicitly +loop over the observations of a vector; a vectorized function will be applied to each row automatically. +Consider the following toy example of doubling each observation: + +.. code-block:: python + + import numba + + def double_every_value_nonumba(x): + return x*2 + + @numba.vectorize + def double_every_value_withnumba(x): + return x*2 + + + # Custom function without numba + In [5]: %timeit df['col1_doubled'] = df.a.apply(double_every_value_nonumba) + 1000 loops, best of 3: 797 us per loop + + # Standard implementation (faster than a custom function) + In [6]: %timeit df['col1_doubled'] = df.a*2 + 1000 loops, best of 3: 233 us per loop + + # Custom function with numba + In [7]: %timeit df['col1_doubled'] = double_every_value_withnumba(df.a.values) + 1000 loops, best of 3: 145 us per loop + +Caveats +~~~~~~~ + +.. note:: + + ``numba`` will execute on any function, but can only accelerate certain classes of functions. + +``numba`` is best at accelerating functions that apply numerical functions to numpy arrays. When passed a function that only uses operations it knows how to accelerate, it will execute in ``nopython`` mode. + +If ``numba`` is passed a function that includes something it doesn't know how to work with -- a category that currently includes sets, lists, dictionaries, or string functions -- it will revert to ``object mode``. In ``object mode``, numba will execute but your code will not speed up significantly. If you would prefer that ``numba`` throw an error if it cannot compile a function in a way that speeds up your code, pass numba the argument ``nopython=True`` (e.g. ``@numba.jit(nopython=True)``). For more on troubleshooting ``numba`` modes, see the `numba troubleshooting page `__. + Read more in the `numba docs `__. .. _enhancingperf.eval: @@ -433,18 +482,13 @@ First let's create a few decent-sized arrays to play with: .. ipython:: python - import pandas as pd - from pandas import DataFrame, Series - from numpy.random import randn - import numpy as np nrows, ncols = 20000, 100 - df1, df2, df3, df4 = [DataFrame(randn(nrows, ncols)) for _ in range(4)] + df1, df2, df3, df4 = [pd.DataFrame(np.random.randn(nrows, ncols)) for _ in range(4)] Now let's compare adding them together using plain ol' Python versus :func:`~pandas.eval`: - .. ipython:: python %timeit df1 + df2 + df3 + df4 @@ -467,10 +511,9 @@ Now let's do the same thing but with comparisons: :func:`~pandas.eval` also works with unaligned pandas objects: - .. ipython:: python - s = Series(randn(50)) + s = pd.Series(np.random.randn(50)) %timeit df1 + df2 + df3 + df4 + s .. ipython:: python @@ -515,7 +558,7 @@ evaluate an expression in the "context" of a :class:`~pandas.DataFrame`. .. ipython:: python - df = DataFrame(randn(5, 2), columns=['a', 'b']) + df = pd.DataFrame(np.random.randn(5, 2), columns=['a', 'b']) df.eval('a + b') Any expression that is a valid :func:`pandas.eval` expression is also a valid @@ -530,7 +573,7 @@ it must be a valid Python identifier. .. ipython:: python - df = DataFrame(dict(a=range(5), b=range(5, 10))) + df = pd.DataFrame(dict(a=range(5), b=range(5, 10))) df.eval('c = a + b') df.eval('d = a + b + c') df.eval('a = 1') @@ -540,7 +583,7 @@ The equivalent in standard Python would be .. ipython:: python - df = DataFrame(dict(a=range(5), b=range(5, 10))) + df = pd.DataFrame(dict(a=range(5), b=range(5, 10))) df['c'] = df.a + df.b df['d'] = df.a + df.b + df.c df['a'] = 1 @@ -555,8 +598,8 @@ For example, .. code-block:: python - df = DataFrame(randn(5, 2), columns=['a', 'b']) - newcol = randn(len(df)) + df = pd.DataFrame(np.random.randn(5, 2), columns=['a', 'b']) + newcol = np.random.randn(len(df)) df.eval('b + newcol') UndefinedVariableError: name 'newcol' is not defined @@ -567,8 +610,8 @@ expression by placing the ``@`` character in front of the name. For example, .. ipython:: python - df = DataFrame(randn(5, 2), columns=list('ab')) - newcol = randn(len(df)) + df = pd.DataFrame(np.random.randn(5, 2), columns=list('ab')) + newcol = np.random.randn(len(df)) df.eval('b + @newcol') df.query('b < @newcol') @@ -582,7 +625,7 @@ name in an expression. .. ipython:: python - a = randn() + a = np.random.randn() df.query('@a < a') df.loc[a < df.a] # same as the previous expression @@ -710,8 +753,8 @@ you have an expression--for example .. ipython:: python - df = DataFrame({'strings': np.repeat(list('cba'), 3), - 'nums': np.repeat(range(3), 3)}) + df = pd.DataFrame({'strings': np.repeat(list('cba'), 3), + 'nums': np.repeat(range(3), 3)}) df df.query('strings == "a" and nums == 1') diff --git a/doc/source/faq.rst b/doc/source/faq.rst index 32290839ad71d..7714d937e15d6 100644 --- a/doc/source/faq.rst +++ b/doc/source/faq.rst @@ -8,26 +8,18 @@ Frequently Asked Questions (FAQ) .. ipython:: python :suppress: - from datetime import datetime import numpy as np np.random.seed(123456) - from pandas import * - options.display.max_rows=15 - randn = np.random.randn - randint = np.random.randint np.set_printoptions(precision=4, suppress=True) - from dateutil.relativedelta import relativedelta - from pandas.tseries.api import * - from pandas.tseries.offsets import * - import matplotlib.pyplot as plt - plt.close('all') + import pandas as pd + pd.options.display.max_rows = 15 import matplotlib try: matplotlib.style.use('ggplot') except AttributeError: - options.display.mpl_style = 'default' - from pandas.compat import lrange - + pd.options.display.mpl_style = 'default' + import matplotlib.pyplot as plt + plt.close('all') .. _df-memory-usage: @@ -45,11 +37,11 @@ when calling ``df.info()``: .. ipython:: python dtypes = ['int64', 'float64', 'datetime64[ns]', 'timedelta64[ns]', - 'complex128', 'object', 'bool'] + 'complex128', 'object', 'bool'] n = 5000 data = dict([ (t, np.random.randint(100, size=n).astype(t)) for t in dtypes]) - df = DataFrame(data) + df = pd.DataFrame(data) df['categorical'] = df['object'].astype('category') df.info() @@ -89,149 +81,6 @@ representation; i.e., 1KB = 1024 bytes). See also :ref:`Categorical Memory Usage `. - -.. _ref-scikits-migration: - -Migrating from scikits.timeseries to pandas >= 0.8.0 ----------------------------------------------------- - -Starting with pandas 0.8.0, users of scikits.timeseries should have all of the -features that they need to migrate their code to use pandas. Portions of the -scikits.timeseries codebase for implementing calendar logic and timespan -frequency conversions (but **not** resampling, that has all been implemented -from scratch from the ground up) have been ported to the pandas codebase. - -The scikits.timeseries notions of ``Date`` and ``DateArray`` are responsible -for implementing calendar logic: - -:: - - In [16]: dt = ts.Date('Q', '1984Q3') - - # sic - In [17]: dt - Out[17]: - - In [18]: dt.asfreq('D', 'start') - Out[18]: - - In [19]: dt.asfreq('D', 'end') - Out[19]: - - In [20]: dt + 3 - Out[20]: - -``Date`` and ``DateArray`` from scikits.timeseries have been reincarnated in -pandas ``Period`` and ``PeriodIndex``: - -.. ipython:: python - - pnow('D') # scikits.timeseries.now() - Period(year=2007, month=3, day=15, freq='D') - p = Period('1984Q3') - p - p.asfreq('D', 'start') - p.asfreq('D', 'end') - (p + 3).asfreq('T') + 6 * 60 + 30 - rng = period_range('1990', '2010', freq='A') - rng - rng.asfreq('B', 'end') - 3 - -.. csv-table:: - :header: "scikits.timeseries", "pandas", "Notes" - :widths: 20, 20, 60 - - Date, Period, "A span of time, from yearly through to secondly" - DateArray, PeriodIndex, "An array of timespans" - convert, resample, "Frequency conversion in scikits.timeseries" - convert_to_annual, pivot_annual, "currently supports up to daily frequency, see :issue:`736`" - - -PeriodIndex / DateArray properties and functions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The scikits.timeseries ``DateArray`` had a number of information -properties. Here are the pandas equivalents: - -.. csv-table:: - :header: "scikits.timeseries", "pandas", "Notes" - :widths: 20, 60, 20 - - get_steps, ``np.diff(idx.values)``, - has_missing_dates, ``not idx.is_full``, - is_full, ``idx.is_full``, - is_valid, ``idx.is_monotonic and idx.is_unique``, - is_chronological, ``is_monotonic``, - ``arr.sort_chronologically()``, ``idx.order()``, - -Frequency conversion -~~~~~~~~~~~~~~~~~~~~ - -Frequency conversion is implemented using the ``resample`` method on Series -and DataFrame objects with a DatetimeIndex or PeriodIndex. ``resample`` also -works on panels (3D). Here is some code that resamples daily data to montly: - -.. ipython:: python - - rng = period_range('Jan-2000', periods=50, freq='M') - data = Series(np.random.randn(50), index=rng) - data - data.resample('A', how=np.mean) - -Plotting -~~~~~~~~ - -Much of the plotting functionality of scikits.timeseries has been ported and -adopted to pandas's data structures. For example: - -.. ipython:: python - - rng = period_range('1987Q2', periods=10, freq='Q-DEC') - data = Series(np.random.randn(10), index=rng) - - @savefig skts_ts_plot.png - plt.figure(); data.plot() - -Converting to and from period format -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Use the ``to_timestamp`` and ``to_period`` instance methods. - -Treatment of missing data -~~~~~~~~~~~~~~~~~~~~~~~~~ - -Unlike scikits.timeseries, pandas data structures are not based on NumPy's -``MaskedArray`` object. Missing data is represented as ``NaN`` in numerical -arrays and either as ``None`` or ``NaN`` in non-numerical arrays. Implementing -a version of pandas's data structures that use MaskedArray is possible but -would require the involvement of a dedicated maintainer. Active pandas -developers are not interested in this. - -Resampling with timestamps and periods -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -``resample`` has a ``kind`` argument which allows you to resample time series -with a DatetimeIndex to PeriodIndex: - -.. ipython:: python - - rng = date_range('1/1/2000', periods=200, freq='D') - data = Series(np.random.randn(200), index=rng) - data[:10] - data.index - data.resample('M', kind='period') - -Similarly, resampling from periods to timestamps is possible with an optional -interval (``'start'`` or ``'end'``) convention: - -.. ipython:: python - - rng = period_range('Jan-2000', periods=50, freq='M') - data = Series(np.random.randn(50), index=rng) - resampled = data.resample('A', kind='timestamp', convention='end') - resampled.index - - Byte-Ordering Issues -------------------- Occasionally you may have to deal with data that were created on a machine with @@ -244,7 +93,7 @@ using something similar to the following: x = np.array(list(range(10)), '>i4') # big endian newx = x.byteswap().newbyteorder() # force native byteorder - s = Series(newx) + s = pd.Series(newx) See `the NumPy documentation on byte order `__ for more diff --git a/doc/source/gotchas.rst b/doc/source/gotchas.rst index addeddcb0bdde..cf4a86d530180 100644 --- a/doc/source/gotchas.rst +++ b/doc/source/gotchas.rst @@ -4,13 +4,11 @@ .. ipython:: python :suppress: - import os import numpy as np - from pandas import * - options.display.max_rows=15 - randn = np.random.randn np.set_printoptions(precision=4, suppress=True) - from pandas.compat import lrange + import pandas as pd + pd.options.display.max_rows=15 + ******************* Caveats and Gotchas @@ -27,7 +25,7 @@ what the result of .. code-block:: python - >>> if Series([False, True, False]): + >>> if pd.Series([False, True, False]): ... should be. Should it be ``True`` because it's not zero-length? ``False`` because there are ``False`` values? @@ -64,10 +62,10 @@ To evaluate single-element pandas objects in a boolean context, use the method ` .. ipython:: python - Series([True]).bool() - Series([False]).bool() - DataFrame([[True]]).bool() - DataFrame([[False]]).bool() + pd.Series([True]).bool() + pd.Series([False]).bool() + pd.DataFrame([[True]]).bool() + pd.DataFrame([[False]]).bool() Bitwise boolean ~~~~~~~~~~~~~~~ @@ -147,7 +145,7 @@ arrays. For example: .. ipython:: python - s = Series([1, 2, 3, 4, 5], index=list('abcde')) + s = pd.Series([1, 2, 3, 4, 5], index=list('abcde')) s s.dtype @@ -228,9 +226,9 @@ following code will generate exceptions: .. code-block:: python - s = Series(range(5)) + s = pd.Series(range(5)) s[-1] - df = DataFrame(np.random.randn(5, 4)) + df = pd.DataFrame(np.random.randn(5, 4)) df df.ix[-2:] @@ -255,7 +253,7 @@ consider the following Series: .. ipython:: python - s = Series(randn(6), index=list('abcdef')) + s = pd.Series(np.random.randn(6), index=list('abcdef')) s Suppose we wished to slice from ``c`` to ``e``, using integers this would be @@ -294,8 +292,8 @@ concise means of selecting data from a pandas object: .. ipython:: python - df = DataFrame(randn(6, 4), columns=['one', 'two', 'three', 'four'], - index=list('abcdef')) + df = pd.DataFrame(np.random.randn(6, 4), columns=['one', 'two', 'three', 'four'], + index=list('abcdef')) df df.ix[['b', 'c', 'e']] @@ -326,7 +324,7 @@ cases where an index contains, say, both integers and strings: .. ipython:: python - s = Series([1, 2, 3], index=['a', 0, 1]) + s = pd.Series([1, 2, 3], index=['a', 0, 1]) s s.ix[[0, 1]] s.reindex([0, 1]) @@ -345,10 +343,10 @@ The use of ``reindex_like`` can potentially change the dtype of a ``Series``. .. ipython:: python - series = Series([1, 2, 3]) - x = Series([True]) + series = pd.Series([1, 2, 3]) + x = pd.Series([True]) x.dtype - x = Series([True]).reindex_like(series) + x = pd.Series([True]).reindex_like(series) x.dtype This is because ``reindex_like`` silently inserts ``NaNs`` and the ``dtype`` @@ -371,10 +369,10 @@ can be represented using a 64-bit integer is limited to approximately 584 years: .. ipython:: python - begin = Timestamp.min + begin = pd.Timestamp.min begin - end = Timestamp.max + end = pd.Timestamp.max end See :ref:`here ` for ways to represent data outside these bound. @@ -404,10 +402,10 @@ of the new set of columns rather than the original ones: print(open('tmp.csv').read()) date_spec = {'nominal': [1, 2], 'actual': [1, 3]} - df = read_csv('tmp.csv', header=None, - parse_dates=date_spec, - keep_date_col=True, - index_col=0) + df = pd.read_csv('tmp.csv', header=None, + parse_dates=date_spec, + keep_date_col=True, + index_col=0) # index_col=0 refers to the combined column "nominal" and not the original # first column of 'KORD' strings @@ -417,6 +415,7 @@ of the new set of columns rather than the original ones: .. ipython:: python :suppress: + import os os.remove('tmp.csv') @@ -569,7 +568,7 @@ using something similar to the following: x = np.array(list(range(10)), '>i4') # big endian newx = x.byteswap().newbyteorder() # force native byteorder - s = Series(newx) + s = pd.Series(newx) See `the NumPy documentation on byte order `__ for more diff --git a/doc/source/groupby.rst b/doc/source/groupby.rst index c9e18b585c764..acddf1bb3fe30 100644 --- a/doc/source/groupby.rst +++ b/doc/source/groupby.rst @@ -6,18 +6,16 @@ import numpy as np np.random.seed(123456) - from pandas import * - options.display.max_rows=15 - randn = np.random.randn np.set_printoptions(precision=4, suppress=True) - import matplotlib.pyplot as plt - plt.close('all') + import pandas as pd + pd.options.display.max_rows = 15 import matplotlib try: matplotlib.style.use('ggplot') except AttributeError: - options.display.mpl_style = 'default' - from pandas.compat import zip + pd.options.display.mpl_style = 'default' + import matplotlib.pyplot as plt + plt.close('all') ***************************** Group By: split-apply-combine @@ -105,11 +103,12 @@ consider the following DataFrame: .. ipython:: python - df = DataFrame({'A' : ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B' : ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C' : randn(8), 'D' : randn(8)}) + df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B' : ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C' : np.random.randn(8), + 'D' : np.random.randn(8)}) df We could naturally group by either the ``A`` or ``B`` columns or both: @@ -142,7 +141,7 @@ output of aggregation functions will only contain unique index values: lst = [1, 2, 3, 1, 2, 3] - s = Series([1, 2, 3, 10, 20, 30], lst) + s = pd.Series([1, 2, 3, 10, 20, 30], lst) grouped = s.groupby(level=0) @@ -189,7 +188,7 @@ however pass ``sort=False`` for potential speedups: .. ipython:: python - df2 = DataFrame({'X' : ['B', 'B', 'A', 'A'], 'Y' : [1, 2, 3, 4]}) + df2 = pd.DataFrame({'X' : ['B', 'B', 'A', 'A'], 'Y' : [1, 2, 3, 4]}) df2.groupby(['X'], sort=True).sum() df2.groupby(['X'], sort=False).sum() @@ -203,10 +202,10 @@ however pass ``sort=False`` for potential speedups: n = 10 weight = np.random.normal(166, 20, size=n) height = np.random.normal(60, 10, size=n) - time = date_range('1/1/2000', periods=n) + time = pd.date_range('1/1/2000', periods=n) gender = tm.choice(['male', 'female'], size=n) - df = DataFrame({'height': height, 'weight': weight, - 'gender': gender}, index=time) + df = pd.DataFrame({'height': height, 'weight': weight, + 'gender': gender}, index=time) .. ipython:: python @@ -226,11 +225,12 @@ however pass ``sort=False`` for potential speedups: .. ipython:: python :suppress: - df = DataFrame({'A' : ['foo', 'bar', 'foo', 'bar', - 'foo', 'bar', 'foo', 'foo'], - 'B' : ['one', 'one', 'two', 'three', - 'two', 'two', 'one', 'three'], - 'C' : randn(8), 'D' : randn(8)}) + df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar', + 'foo', 'bar', 'foo', 'foo'], + 'B' : ['one', 'one', 'two', 'three', + 'two', 'two', 'one', 'three'], + 'C' : np.random.randn(8), + 'D' : np.random.randn(8)}) .. _groupby.multiindex: @@ -248,8 +248,8 @@ natural to group by one of the levels of the hierarchy. ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']] tuples = list(zip(*arrays)) tuples - index = MultiIndex.from_tuples(tuples, names=['first', 'second']) - s = Series(randn(8), index=index) + index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second']) + s = pd.Series(np.random.randn(8), index=index) .. ipython:: python @@ -281,13 +281,13 @@ Also as of v0.6, grouping with multiple levels is supported. ['doo', 'doo', 'bee', 'bee', 'bop', 'bop', 'bop', 'bop'], ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']] tuples = list(zip(*arrays)) - index = MultiIndex.from_tuples(tuples, names=['first', 'second', 'third']) - s = Series(randn(8), index=index) + index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second', 'third']) + s = pd.Series(np.random.randn(8), index=index) .. ipython:: python s - s.groupby(level=['first','second']).sum() + s.groupby(level=['first', 'second']).sum() More on the ``sum`` function and aggregation later. @@ -499,9 +499,9 @@ to standardize the data within each group: .. ipython:: python - index = date_range('10/1/1999', periods=1100) - ts = Series(np.random.normal(0.5, 2, 1100), index) - ts = rolling_mean(ts, 100, 100).dropna() + index = pd.date_range('10/1/1999', periods=1100) + ts = pd.Series(np.random.normal(0.5, 2, 1100), index) + ts = pd.rolling_mean(ts, 100, 100).dropna() ts.head() ts.tail() @@ -528,7 +528,7 @@ We can also visually compare the original and transformed data sets. .. ipython:: python - compare = DataFrame({'Original': ts, 'Transformed': transformed}) + compare = pd.DataFrame({'Original': ts, 'Transformed': transformed}) @savefig groupby_transform_plot.png compare.plot() @@ -539,11 +539,11 @@ Another common data transform is to replace missing data with the group mean. :suppress: cols = ['A', 'B', 'C'] - values = randn(1000, 3) + values = np.random.randn(1000, 3) values[np.random.randint(0, 1000, 100), 0] = np.nan values[np.random.randint(0, 1000, 50), 1] = np.nan values[np.random.randint(0, 1000, 200), 2] = np.nan - data_df = DataFrame(values, columns=cols) + data_df = pd.DataFrame(values, columns=cols) .. ipython:: python @@ -599,7 +599,7 @@ than 2. .. ipython:: python - sf = Series([1, 1, 2, 3, 3, 3]) + sf = pd.Series([1, 1, 2, 3, 3, 3]) sf.groupby(sf).filter(lambda x: x.sum() > 2) The argument of ``filter`` must be a function that, applied to the group as a @@ -610,7 +610,7 @@ with only a couple members. .. ipython:: python - dff = DataFrame({'A': np.arange(8), 'B': list('aabbbbcc')}) + dff = pd.DataFrame({'A': np.arange(8), 'B': list('aabbbbcc')}) dff.groupby('B').filter(lambda x: len(x) > 2) Alternatively, instead of dropping the offending groups, we can return a @@ -672,9 +672,9 @@ next). This enables some operations to be carried out rather succinctly: .. ipython:: python - tsdf = DataFrame(randn(1000, 3), - index=date_range('1/1/2000', periods=1000), - columns=['A', 'B', 'C']) + tsdf = pd.DataFrame(np.random.randn(1000, 3), + index=pd.date_range('1/1/2000', periods=1000), + columns=['A', 'B', 'C']) tsdf.ix[::2] = np.nan grouped = tsdf.groupby(lambda x: x.year) grouped.fillna(method='pad') @@ -689,8 +689,8 @@ The ``nlargest`` and ``nsmallest`` methods work on ``Series`` style groupbys: .. ipython:: python - s = Series([9, 8, 7, 5, 19, 1, 4.2, 3.3]) - g = Series(list('abababab')) + s = pd.Series([9, 8, 7, 5, 19, 1, 4.2, 3.3]) + g = pd.Series(list('abababab')) gb = s.groupby(g) gb.nlargest(3) gb.nsmallest(3) @@ -721,8 +721,8 @@ The dimension of the returned result can also change: In [8]: grouped = df.groupby('A')['C'] In [10]: def f(group): - ....: return DataFrame({'original' : group, - ....: 'demeaned' : group - group.mean()}) + ....: return pd.DataFrame({'original' : group, + ....: 'demeaned' : group - group.mean()}) ....: In [11]: grouped.apply(f) @@ -732,8 +732,8 @@ The dimension of the returned result can also change: .. ipython:: python def f(x): - return Series([ x, x**2 ], index = ['x', 'x^s']) - s = Series(np.random.rand(5)) + return pd.Series([ x, x**2 ], index = ['x', 'x^s']) + s = pd.Series(np.random.rand(5)) s s.apply(f) @@ -754,7 +754,7 @@ The dimension of the returned result can also change: .. ipython:: python - d = DataFrame({"a":["x", "y"], "b":[1,2]}) + d = pd.DataFrame({"a":["x", "y"], "b":[1,2]}) def identity(df): print df return df @@ -784,6 +784,8 @@ will be (silently) dropped. Thus, this does not pose any problems: df.groupby('A').std() +.. _groupby.missing: + NA and NaT group handling ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -800,9 +802,9 @@ can be used as group keys. If so, the order of the levels will be preserved: .. ipython:: python - data = Series(np.random.randn(100)) + data = pd.Series(np.random.randn(100)) - factor = qcut(data, [0, .25, .5, .75, 1.]) + factor = pd.qcut(data, [0, .25, .5, .75, 1.]) data.groupby(factor).mean() @@ -811,27 +813,28 @@ can be used as group keys. If so, the order of the levels will be preserved: Grouping with a Grouper specification ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Your may need to specify a bit more data to properly group. You can +You may need to specify a bit more data to properly group. You can use the ``pd.Grouper`` to provide this local control. .. ipython:: python - import datetime as DT - - df = DataFrame({ - 'Branch' : 'A A A A A A A B'.split(), - 'Buyer': 'Carl Mark Carl Carl Joe Joe Joe Carl'.split(), - 'Quantity': [1,3,5,1,8,1,9,3], - 'Date' : [ - DT.datetime(2013,1,1,13,0), - DT.datetime(2013,1,1,13,5), - DT.datetime(2013,10,1,20,0), - DT.datetime(2013,10,2,10,0), - DT.datetime(2013,10,1,20,0), - DT.datetime(2013,10,2,10,0), - DT.datetime(2013,12,2,12,0), - DT.datetime(2013,12,2,14,0), - ]}) + import datetime + + df = pd.DataFrame({ + 'Branch' : 'A A A A A A A B'.split(), + 'Buyer': 'Carl Mark Carl Carl Joe Joe Joe Carl'.split(), + 'Quantity': [1,3,5,1,8,1,9,3], + 'Date' : [ + datetime.datetime(2013,1,1,13,0), + datetime.datetime(2013,1,1,13,5), + datetime.datetime(2013,10,1,20,0), + datetime.datetime(2013,10,2,10,0), + datetime.datetime(2013,10,1,20,0), + datetime.datetime(2013,10,2,10,0), + datetime.datetime(2013,12,2,12,0), + datetime.datetime(2013,12,2,14,0), + ] + }) df @@ -860,7 +863,7 @@ Just like for a DataFrame or Series you can call head and tail on a groupby: .. ipython:: python - df = DataFrame([[1, 2], [1, 4], [5, 6]], columns=['A', 'B']) + df = pd.DataFrame([[1, 2], [1, 4], [5, 6]], columns=['A', 'B']) df g = df.groupby('A') @@ -892,7 +895,7 @@ To select from a DataFrame or Series the nth item, use the nth method. This is a .. ipython:: python - df = DataFrame([[1, np.nan], [1, 4], [5, 6]], columns=['A', 'B']) + df = pd.DataFrame([[1, np.nan], [1, 4], [5, 6]], columns=['A', 'B']) g = df.groupby('A') g.nth(0) @@ -917,7 +920,7 @@ As with other methods, passing ``as_index=False``, will achieve a filtration, wh .. ipython:: python - df = DataFrame([[1, np.nan], [1, 4], [5, 6]], columns=['A', 'B']) + df = pd.DataFrame([[1, np.nan], [1, 4], [5, 6]], columns=['A', 'B']) g = df.groupby('A',as_index=False) g.nth(0) @@ -927,8 +930,8 @@ You can also select multiple rows from each group by specifying multiple nth val .. ipython:: python - business_dates = date_range(start='4/1/2014', end='6/30/2014', freq='B') - df = DataFrame(1, index=business_dates, columns=['a', 'b']) + business_dates = pd.date_range(start='4/1/2014', end='6/30/2014', freq='B') + df = pd.DataFrame(1, index=business_dates, columns=['a', 'b']) # get the first, 4th, and last date index for each month df.groupby((df.index.year, df.index.month)).nth([0, 3, -1]) @@ -959,7 +962,7 @@ the values in column 1 where the group is "B" are 3 higher on average. .. ipython:: python np.random.seed(1234) - df = DataFrame(np.random.randn(50, 2)) + df = pd.DataFrame(np.random.randn(50, 2)) df['g'] = np.random.choice(['A', 'B'], size=50) df.loc[df['g'] == 'B', 1] += 3 @@ -1008,11 +1011,11 @@ column index name will be used as the name of the inserted column: .. ipython:: python df = pd.DataFrame({ - 'a': [0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2], - 'b': [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1], - 'c': [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0], - 'd': [0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1], - }) + 'a': [0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2], + 'b': [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1], + 'c': [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0], + 'd': [0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1], + }) def compute_metrics(x): result = {'b_sum': x['b'].sum(), 'c_mean': x['c'].mean()} diff --git a/doc/source/indexing.rst b/doc/source/indexing.rst index a1912032bc3bf..38629ee7baaea 100644 --- a/doc/source/indexing.rst +++ b/doc/source/indexing.rst @@ -6,15 +6,10 @@ :suppress: import numpy as np - import random np.random.seed(123456) - from pandas import * - options.display.max_rows=15 - import pandas as pd - randn = np.random.randn - randint = np.random.randint np.set_printoptions(precision=4, suppress=True) - from pandas.compat import range, zip + import pandas as pd + pd.options.display.max_rows=15 *************************** Indexing and Selecting Data @@ -126,18 +121,6 @@ the specification are assumed to be ``:``. (e.g. ``p.loc['a']`` is equiv to DataFrame; ``df.loc[row_indexer,column_indexer]`` Panel; ``p.loc[item_indexer,major_indexer,minor_indexer]`` -Deprecations ------------- - -Beginning with version 0.11.0, it's recommended that you transition away from -the following methods as they *may* be deprecated in future versions. - - - ``irow`` - - ``icol`` - - ``iget_value`` - -See the section :ref:`Selection by Position ` for substitutes. - .. _indexing.basics: Basics @@ -162,10 +145,10 @@ indexing functionality: .. ipython:: python - dates = date_range('1/1/2000', periods=8) - df = DataFrame(randn(8, 4), index=dates, columns=['A', 'B', 'C', 'D']) + dates = pd.date_range('1/1/2000', periods=8) + df = pd.DataFrame(np.random.randn(8, 4), index=dates, columns=['A', 'B', 'C', 'D']) df - panel = Panel({'one' : df, 'two' : df - df.mean()}) + panel = pd.Panel({'one' : df, 'two' : df - df.mean()}) panel .. note:: @@ -208,7 +191,7 @@ as an attribute: .. ipython:: python - sa = Series([1,2,3],index=list('abc')) + sa = pd.Series([1,2,3],index=list('abc')) dfa = df.copy() .. ipython:: python @@ -307,7 +290,7 @@ Selection By Label .. ipython:: python - dfl = DataFrame(np.random.randn(5,4), columns=list('ABCD'), index=date_range('20130101',periods=5)) + dfl = pd.DataFrame(np.random.randn(5,4), columns=list('ABCD'), index=pd.date_range('20130101',periods=5)) dfl .. code-block:: python @@ -333,7 +316,7 @@ The ``.loc`` attribute is the primary access method. The following are valid inp .. ipython:: python - s1 = Series(np.random.randn(6),index=list('abcdef')) + s1 = pd.Series(np.random.randn(6),index=list('abcdef')) s1 s1.loc['c':] s1.loc['b'] @@ -349,9 +332,9 @@ With a DataFrame .. ipython:: python - df1 = DataFrame(np.random.randn(6,4), - index=list('abcdef'), - columns=list('ABCD')) + df1 = pd.DataFrame(np.random.randn(6,4), + index=list('abcdef'), + columns=list('ABCD')) df1 df1.loc[['a','b','d'],:] @@ -403,7 +386,7 @@ The ``.iloc`` attribute is the primary access method. The following are valid in .. ipython:: python - s1 = Series(np.random.randn(5),index=list(range(0,10,2))) + s1 = pd.Series(np.random.randn(5), index=list(range(0,10,2))) s1 s1.iloc[:3] s1.iloc[3] @@ -419,9 +402,9 @@ With a DataFrame .. ipython:: python - df1 = DataFrame(np.random.randn(6,4), - index=list(range(0,12,2)), - columns=list(range(0,8,2))) + df1 = pd.DataFrame(np.random.randn(6,4), + index=list(range(0,12,2)), + columns=list(range(0,8,2))) df1 Select via integer slicing @@ -437,20 +420,14 @@ Select via integer list df1.iloc[[1,3,5],[1,3]] -For slicing rows explicitly (equiv to deprecated ``df.irow(slice(1,3))``). - .. ipython:: python df1.iloc[1:3,:] -For slicing columns explicitly (equiv to deprecated ``df.icol(slice(1,3))``). - .. ipython:: python df1.iloc[:,1:3] -For getting a scalar via integer position (equiv to deprecated ``df.get_value(1,1)``) - .. ipython:: python # this is also equivalent to ``df1.iat[1,1]`` @@ -472,7 +449,7 @@ Out of range slice indexes are handled gracefully just as in Python/Numpy. x x[4:10] x[8:10] - s = Series(x) + s = pd.Series(x) s s.iloc[4:10] s.iloc[8:10] @@ -488,7 +465,7 @@ returned) .. ipython:: python - dfl = DataFrame(np.random.randn(5,2),columns=list('AB')) + dfl = pd.DataFrame(np.random.randn(5,2), columns=list('AB')) dfl dfl.iloc[:,2:3] dfl.iloc[:,1:3] @@ -516,7 +493,7 @@ A random selection of rows or columns from a Series, DataFrame, or Panel with th .. ipython :: python - s = Series([0,1,2,3,4,5]) + s = pd.Series([0,1,2,3,4,5]) # When no arguments are passed, returns 1 row. s.sample() @@ -532,7 +509,7 @@ using the ``replace`` option: .. ipython :: python - s = Series([0,1,2,3,4,5]) + s = pd.Series([0,1,2,3,4,5]) # Without replacement (default): s.sample(n=6, replace=False) @@ -547,7 +524,7 @@ to have different probabilities, you can pass the ``sample`` function sampling w .. ipython :: python - s = Series([0,1,2,3,4,5]) + s = pd.Series([0,1,2,3,4,5]) example_weights = [0, 0, 0.2, 0.2, 0.2, 0.4] s.sample(n=3, weights=example_weights) @@ -561,21 +538,21 @@ as a string. .. ipython :: python - df2 = DataFrame({'col1':[9,8,7,6], 'weight_column':[0.5, 0.4, 0.1, 0]}) + df2 = pd.DataFrame({'col1':[9,8,7,6], 'weight_column':[0.5, 0.4, 0.1, 0]}) df2.sample(n = 3, weights = 'weight_column') ``sample`` also allows users to sample columns instead of rows using the ``axis`` argument. .. ipython :: python - df3 = DataFrame({'col1':[1,2,3], 'col2':[2,3,4]}) + df3 = pd.DataFrame({'col1':[1,2,3], 'col2':[2,3,4]}) df3.sample(n=1, axis=1) Finally, one can also set a seed for ``sample``'s random number generator using the ``random_state`` argument, which will accept either an integer (as a seed) or a numpy RandomState object. .. ipython :: python - df4 = DataFrame({'col1':[1,2,3], 'col2':[2,3,4]}) + df4 = pd.DataFrame({'col1':[1,2,3], 'col2':[2,3,4]}) # With a given seed, the sample will always draw the same rows. df4.sample(n=2, random_state=2) @@ -594,7 +571,7 @@ In the ``Series`` case this is effectively an appending operation .. ipython:: python - se = Series([1,2,3]) + se = pd.Series([1,2,3]) se se[5] = 5. se @@ -603,7 +580,7 @@ A ``DataFrame`` can be enlarged on either axis via ``.loc`` .. ipython:: python - dfi = DataFrame(np.arange(6).reshape(3,2), + dfi = pd.DataFrame(np.arange(6).reshape(3,2), columns=['A','B']) dfi dfi.loc[:,'C'] = dfi.loc[:,'A'] @@ -661,7 +638,7 @@ Using a boolean vector to index a Series works exactly as in a numpy ndarray: .. ipython:: python - s = Series(range(-3, 4)) + s = pd.Series(range(-3, 4)) s s[s > 0] s[(s < -1) | (s > 0.5)] @@ -680,9 +657,9 @@ more complex criteria: .. ipython:: python - df2 = DataFrame({'a' : ['one', 'one', 'two', 'three', 'two', 'one', 'six'], - 'b' : ['x', 'y', 'y', 'x', 'y', 'x', 'x'], - 'c' : randn(7)}) + df2 = pd.DataFrame({'a' : ['one', 'one', 'two', 'three', 'two', 'one', 'six'], + 'b' : ['x', 'y', 'y', 'x', 'y', 'x', 'x'], + 'c' : np.random.randn(7)}) # only want 'two' or 'three' criterion = df2['a'].map(lambda x: x.startswith('t')) @@ -713,7 +690,7 @@ select rows where one or more columns have values you want: .. ipython:: python - s = Series(np.arange(5),index=np.arange(5)[::-1],dtype='int64') + s = pd.Series(np.arange(5), index=np.arange(5)[::-1], dtype='int64') s s.isin([2, 4, 6]) s[s.isin([2, 4, 6])] @@ -733,8 +710,8 @@ in the membership check: .. ipython:: python - s_mi = Series(np.arange(6), - index=pd.MultiIndex.from_product([[0, 1], ['a', 'b', 'c']])) + s_mi = pd.Series(np.arange(6), + index=pd.MultiIndex.from_product([[0, 1], ['a', 'b', 'c']])) s_mi s_mi.iloc[s_mi.index.isin([(1, 'a'), (2, 'b'), (0, 'c')])] s_mi.iloc[s_mi.index.isin(['a', 'c', 'e'], level=1)] @@ -746,8 +723,8 @@ wherever the element is in the sequence of values. .. ipython:: python - df = DataFrame({'vals': [1, 2, 3, 4], 'ids': ['a', 'b', 'f', 'n'], - 'ids2': ['a', 'n', 'c', 'n']}) + df = pd.DataFrame({'vals': [1, 2, 3, 4], 'ids': ['a', 'b', 'f', 'n'], + 'ids2': ['a', 'n', 'c', 'n']}) values = ['a', 'b', 1, 3] @@ -801,8 +778,8 @@ Equivalent is ``df.where(df < 0)`` .. ipython:: python :suppress: - dates = date_range('1/1/2000', periods=8) - df = DataFrame(randn(8, 4), index=dates, columns=['A', 'B', 'C', 'D']) + dates = pd.date_range('1/1/2000', periods=8) + df = pd.DataFrame(np.random.randn(8, 4), index=dates, columns=['A', 'B', 'C', 'D']) .. ipython:: python @@ -889,16 +866,10 @@ method that allows selection using an expression. You can get the value of the frame where column ``b`` has values between the values of columns ``a`` and ``c``. For example: -.. ipython:: python - :suppress: - - from numpy.random import randint, rand - np.random.seed(1234) - .. ipython:: python n = 10 - df = DataFrame(rand(n, 3), columns=list('abc')) + df = pd.DataFrame(np.random.rand(n, 3), columns=list('abc')) df # pure python @@ -912,7 +883,7 @@ with the name ``a``. .. ipython:: python - df = DataFrame(randint(n / 2, size=(n, 2)), columns=list('bc')) + df = pd.DataFrame(np.random.randint(n / 2, size=(n, 2)), columns=list('bc')) df.index.name = 'a' df df.query('a < b and b < c') @@ -928,7 +899,7 @@ If instead you don't want to or cannot name your index, you can use the name .. ipython:: python - df = DataFrame(randint(n, size=(n, 2)), columns=list('bc')) + df = pd.DataFrame(np.random.randint(n, size=(n, 2)), columns=list('bc')) df df.query('index < b < c') @@ -946,7 +917,7 @@ If instead you don't want to or cannot name your index, you can use the name .. ipython:: python - df = DataFrame({'a': randint(5, size=5)}) + df = pd.DataFrame({'a': np.random.randint(5, size=5)}) df.index.name = 'a' df.query('a > 2') # uses the column 'a', not the index @@ -970,23 +941,20 @@ You can also use the levels of a ``DataFrame`` with a .. ipython:: python - import pandas.util.testing as tm - n = 10 - colors = tm.choice(['red', 'green'], size=n) - foods = tm.choice(['eggs', 'ham'], size=n) + colors = np.random.choice(['red', 'green'], size=n) + foods = np.random.choice(['eggs', 'ham'], size=n) colors foods - index = MultiIndex.from_arrays([colors, foods], names=['color', 'food']) - df = DataFrame(randn(n, 2), index=index) + index = pd.MultiIndex.from_arrays([colors, foods], names=['color', 'food']) + df = pd.DataFrame(np.random.randn(n, 2), index=index) df df.query('color == "red"') If the levels of the ``MultiIndex`` are unnamed, you can refer to them using special names: - .. ipython:: python df.index.names = [None, None] @@ -1008,9 +976,9 @@ having to specify which frame you're interested in querying .. ipython:: python - df = DataFrame(rand(n, 3), columns=list('abc')) + df = pd.DataFrame(np.random.rand(n, 3), columns=list('abc')) df - df2 = DataFrame(rand(n + 2, 3), columns=df.columns) + df2 = pd.DataFrame(np.random.rand(n + 2, 3), columns=df.columns) df2 expr = '0.0 <= a <= c <= 0.5' map(lambda frame: frame.query(expr), [df, df2]) @@ -1022,7 +990,7 @@ Full numpy-like syntax .. ipython:: python - df = DataFrame(randint(n, size=(n, 3)), columns=list('abc')) + df = pd.DataFrame(np.random.randint(n, size=(n, 3)), columns=list('abc')) df df.query('(a < b) & (b < c)') df[(df.a < df.b) & (df.b < df.c)] @@ -1065,8 +1033,9 @@ The ``in`` and ``not in`` operators .. ipython:: python # get all rows where columns "a" and "b" have overlapping values - df = DataFrame({'a': list('aabbccddeeff'), 'b': list('aaaabbbbcccc'), - 'c': randint(5, size=12), 'd': randint(9, size=12)}) + df = pd.DataFrame({'a': list('aabbccddeeff'), 'b': list('aaaabbbbcccc'), + 'c': np.random.randint(5, size=12), + 'd': np.random.randint(9, size=12)}) df df.query('a in b') @@ -1139,8 +1108,8 @@ You can negate boolean expressions with the word ``not`` or the ``~`` operator. .. ipython:: python - df = DataFrame(rand(n, 3), columns=list('abc')) - df['bools'] = rand(len(df)) > 0.5 + df = pd.DataFrame(np.random.rand(n, 3), columns=list('abc')) + df['bools'] = np.random.rand(len(df)) > 0.5 df.query('~bools') df.query('not bools') df.query('not bools') == df[~df.bools] @@ -1192,7 +1161,7 @@ floating point values generated using ``numpy.random.randn()``. .. ipython:: python :suppress: - df = DataFrame(randn(8, 4), index=dates, columns=['A', 'B', 'C', 'D']) + df = pd.DataFrame(np.random.randn(8, 4), index=dates, columns=['A', 'B', 'C', 'D']) df2 = df.copy() @@ -1209,28 +1178,45 @@ takes as an argument the columns to use to identify duplicated rows. - ``drop_duplicates`` removes duplicate rows. By default, the first observed row of a duplicate set is considered unique, but -each method has a ``take_last`` parameter that indicates the last observed row -should be taken instead. +each method has a ``keep`` parameter to specify targets to be kept. + +- ``keep='first'`` (default): mark / drop duplicates except for the first occurrence. +- ``keep='last'``: mark / drop duplicates except for the last occurrence. +- ``keep=False``: mark / drop all duplicates. .. ipython:: python - df2 = DataFrame({'a' : ['one', 'one', 'two', 'three', 'two', 'one', 'six'], - 'b' : ['x', 'y', 'y', 'x', 'y', 'x', 'x'], - 'c' : np.random.randn(7)}) - df2.duplicated(['a','b']) - df2.drop_duplicates(['a','b']) - df2.drop_duplicates(['a','b'], take_last=True) + df2 = pd.DataFrame({'a': ['one', 'one', 'two', 'two', 'two', 'three', 'four'], + 'b': ['x', 'y', 'x', 'y', 'x', 'x', 'x'], + 'c': np.random.randn(7)}) + df2 + df2.duplicated('a') + df2.duplicated('a', keep='last') + df2.duplicated('a', keep=False) + df2.drop_duplicates('a') + df2.drop_duplicates('a', keep='last') + df2.drop_duplicates('a', keep=False) -An alternative way to drop duplicates on the index is ``.groupby(level=0)`` combined with ``first()`` or ``last()``. +Also, you can pass a list of columns to identify duplications. .. ipython:: python - df3 = df2.set_index('b') - df3 - df3.groupby(level=0).first() + df2.duplicated(['a', 'b']) + df2.drop_duplicates(['a', 'b']) - # a bit more verbose - df3.reset_index().drop_duplicates(subset='b', take_last=False).set_index('b') +To drop duplicates by index value, use ``Index.duplicated`` then perform slicing. +Same options are available in ``keep`` parameter. + +.. ipython:: python + + df3 = pd.DataFrame({'a': np.arange(6), + 'b': np.random.randn(6)}, + index=['a', 'a', 'b', 'c', 'b', 'a']) + df3 + df3.index.duplicated() + df3[~df3.index.duplicated()] + df3[~df3.index.duplicated(keep='last')] + df3[~df3.index.duplicated(keep=False)] .. _indexing.dictionarylike: @@ -1242,7 +1228,7 @@ default value. .. ipython:: python - s = Series([1,2,3], index=['a','b','c']) + s = pd.Series([1,2,3], index=['a','b','c']) s.get('a') # equivalent to s['a'] s.get('x', default=-1) @@ -1267,7 +1253,7 @@ numpy array. For instance, .. ipython:: python - dflookup = DataFrame(np.random.rand(20,4), columns = ['A','B','C','D']) + dflookup = pd.DataFrame(np.random.rand(20,4), columns = ['A','B','C','D']) dflookup.lookup(list(range(0,10,2)), ['B','C','A','B','D']) .. _indexing.class: @@ -1287,7 +1273,7 @@ lookups, data alignment, and reindexing. The easiest way to create an .. ipython:: python - index = Index(['e', 'd', 'a', 'b']) + index = pd.Index(['e', 'd', 'a', 'b']) index 'd' in index @@ -1296,26 +1282,26 @@ You can also pass a ``name`` to be stored in the index: .. ipython:: python - index = Index(['e', 'd', 'a', 'b'], name='something') + index = pd.Index(['e', 'd', 'a', 'b'], name='something') index.name The name, if set, will be shown in the console display: .. ipython:: python - index = Index(list(range(5)), name='rows') - columns = Index(['A', 'B', 'C'], name='cols') - df = DataFrame(np.random.randn(5, 3), index=index, columns=columns) + index = pd.Index(list(range(5)), name='rows') + columns = pd.Index(['A', 'B', 'C'], name='cols') + df = pd.DataFrame(np.random.randn(5, 3), index=index, columns=columns) df df['A'] +.. _indexing.set_metadata: + Setting metadata ~~~~~~~~~~~~~~~~ .. versionadded:: 0.13.0 -.. _indexing.set_metadata: - Indexes are "mostly immutable", but it is possible to set and change their metadata, like the index ``name`` (or, for ``MultiIndex``, ``levels`` and ``labels``). @@ -1328,7 +1314,7 @@ See :ref:`Advanced Indexing ` for usage of MultiIndexes. .. ipython:: python - ind = Index([1, 2, 3]) + ind = pd.Index([1, 2, 3]) ind.rename("apple") ind ind.set_names(["apple"], inplace=True) @@ -1342,8 +1328,7 @@ See :ref:`Advanced Indexing ` for usage of MultiIndexes. .. ipython:: python - - index = MultiIndex.from_product([range(3), ['one', 'two']], names=['first', 'second']) + index = pd.MultiIndex.from_product([range(3), ['one', 'two']], names=['first', 'second']) index index.levels[1] index.set_levels(["a", "b"], level=1) @@ -1364,8 +1349,8 @@ operators. Difference is provided via the ``.difference()`` method. .. ipython:: python - a = Index(['c', 'b', 'a']) - b = Index(['c', 'e', 'd']) + a = pd.Index(['c', 'b', 'a']) + b = pd.Index(['c', 'e', 'd']) a | b a & b a.difference(b) @@ -1377,8 +1362,8 @@ with duplicates dropped. .. ipython:: python - idx1 = Index([1, 2, 3, 4]) - idx2 = Index([2, 3, 4, 5]) + idx1 = pd.Index([1, 2, 3, 4]) + idx2 = pd.Index([2, 3, 4, 5]) idx1.sym_diff(idx2) idx1 ^ idx2 @@ -1401,10 +1386,10 @@ indexed DataFrame: .. ipython:: python :suppress: - data = DataFrame({'a' : ['bar', 'bar', 'foo', 'foo'], - 'b' : ['one', 'two', 'one', 'two'], - 'c' : ['z', 'y', 'x', 'w'], - 'd' : [1., 2., 3, 4]}) + data = pd.DataFrame({'a' : ['bar', 'bar', 'foo', 'foo'], + 'b' : ['one', 'two', 'one', 'two'], + 'c' : ['z', 'y', 'x', 'w'], + 'd' : [1., 2., 3, 4]}) .. ipython:: python @@ -1482,12 +1467,12 @@ When setting values in a pandas object, care must be taken to avoid what is call .. ipython:: python - dfmi = DataFrame([list('abcd'), - list('efgh'), - list('ijkl'), - list('mnop')], - columns=MultiIndex.from_product([['one','two'], - ['first','second']])) + dfmi = pd.DataFrame([list('abcd'), + list('efgh'), + list('ijkl'), + list('mnop')], + columns=pd.MultiIndex.from_product([['one','two'], + ['first','second']])) dfmi Compare these two access methods: @@ -1543,9 +1528,9 @@ which can take the values ``['raise','warn',None]``, where showing a warning is .. ipython:: python :okwarning: - dfb = DataFrame({'a' : ['one', 'one', 'two', - 'three', 'two', 'one', 'six'], - 'c' : np.arange(7)}) + dfb = pd.DataFrame({'a' : ['one', 'one', 'two', + 'three', 'two', 'one', 'six'], + 'c' : np.arange(7)}) # This will show the SettingWithCopyWarning # but the frame values will be set @@ -1573,7 +1558,7 @@ This is the correct access method .. ipython:: python - dfc = DataFrame({'A':['aaa','bbb','ccc'],'B':[1,2,3]}) + dfc = pd.DataFrame({'A':['aaa','bbb','ccc'],'B':[1,2,3]}) dfc.loc[0,'A'] = 11 dfc diff --git a/doc/source/install.rst b/doc/source/install.rst index b3f86db5e3e59..42cfd95becabb 100644 --- a/doc/source/install.rst +++ b/doc/source/install.rst @@ -18,7 +18,7 @@ Instructions for installing from source, Python version support ---------------------- -Officially Python 2.6, 2.7, 3.2, 3.3, and 3.4. +Officially Python 2.6, 2.7, 3.3, and 3.4. Installing pandas ----------------- @@ -153,7 +153,8 @@ and can take a few minutes to complete. Installing using your Linux distribution's package manager. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - +The commands in this table will install pandas for Python 2 from your distribution. +To install pandas for Python 3 you may need to use the package ``python3-pandas``. .. csv-table:: :header: "Distribution", "Status", "Download / Repository Link", "Install method" @@ -212,6 +213,7 @@ installed), make sure you have `nose Dependencies ------------ +* `setuptools `__ * `NumPy `__: 1.7.0 or higher * `python-dateutil `__ 1.5 or higher * `pytz `__ @@ -249,10 +251,9 @@ Optional Dependencies * `statsmodels `__ * Needed for parts of :mod:`pandas.stats` * `openpyxl `__, `xlrd/xlwt `__ - * openpyxl version 1.6.1 or higher, but lower than 2.0.0 * Needed for Excel I/O * `XlsxWriter `__ - * Alternative Excel writer. + * Alternative Excel writer * `boto `__: necessary for Amazon S3 access. * `blosc `__: for msgpack compression using ``blosc`` @@ -267,11 +268,11 @@ Optional Dependencies installation. * Google's `python-gflags `__ and `google-api-python-client `__ - * Needed for :mod:`~pandas.io.gbq` + * Needed for :mod:`~pandas.io.gbq` * `setuptools `__ - * Needed for :mod:`~pandas.io.gbq` (specifically, it utilizes `pkg_resources`) + * Needed for :mod:`~pandas.io.gbq` (specifically, it utilizes `pkg_resources`) * `httplib2 `__ - * Needed for :mod:`~pandas.io.gbq` + * Needed for :mod:`~pandas.io.gbq` * One of the following combinations of libraries is needed to use the top-level :func:`~pandas.io.html.read_html` function: diff --git a/doc/source/internals.rst b/doc/source/internals.rst index 8b4f7360fc235..3d96b93de4cc9 100644 --- a/doc/source/internals.rst +++ b/doc/source/internals.rst @@ -6,15 +6,10 @@ :suppress: import numpy as np - import random np.random.seed(123456) - from pandas import * - options.display.max_rows=15 - import pandas as pd - randn = np.random.randn - randint = np.random.randint np.set_printoptions(precision=4, suppress=True) - from pandas.compat import range, zip + import pandas as pd + pd.options.display.max_rows = 15 ********* Internals @@ -40,7 +35,7 @@ containers for the axis labels: - ``TimedeltaIndex``: An Index object with ``Timedelta`` boxed elements (impl are the in64 values) - ``PeriodIndex``: An Index object with Period elements -These are range generates to make the creation of a regular index easy: +There are functions that make the creation of a regular index easy: - ``date_range``: fixed frequency date range generated from a time rule or DateOffset. An ndarray of Python datetime objects @@ -81,7 +76,7 @@ integer **labels**, and the level **names**: .. ipython:: python - index = MultiIndex.from_product([range(3), ['one', 'two']], names=['first', 'second']) + index = pd.MultiIndex.from_product([range(3), ['one', 'two']], names=['first', 'second']) index index.levels index.labels @@ -198,7 +193,7 @@ Below example shows how to define ``SubclassedSeries`` and ``SubclassedDataFrame Define Original Properties ~~~~~~~~~~~~~~~~~~~~~~~~~~ -To let original data structures have additional properties, you should let ``pandas`` knows what properties are added. ``pandas`` maps unknown properties to data names overriding ``__getattribute__``. Defining original properties can be done in one of 2 ways: +To let original data structures have additional properties, you should let ``pandas`` know what properties are added. ``pandas`` maps unknown properties to data names overriding ``__getattribute__``. Defining original properties can be done in one of 2 ways: 1. Define ``_internal_names`` and ``_internal_names_set`` for temporary properties which WILL NOT be passed to manipulation results. 2. Define ``_metadata`` for normal properties which will be passed to manipulation results. @@ -210,7 +205,7 @@ Below is an example to define 2 original properties, "internal_cache" as a tempo class SubclassedDataFrame2(DataFrame): # temporary properties - _internal_names = DataFrame._internal_names + ['internal_cache'] + _internal_names = pd.DataFrame._internal_names + ['internal_cache'] _internal_names_set = set(_internal_names) # normal properties @@ -244,5 +239,3 @@ Below is an example to define 2 original properties, "internal_cache" as a tempo # properties defined in _metadata are retained >>> df[['A', 'B']].added_property property - - diff --git a/doc/source/io.rst b/doc/source/io.rst index 73a2f2f1d3531..2f2c4c7566413 100644 --- a/doc/source/io.rst +++ b/doc/source/io.rst @@ -41,6 +41,7 @@ object. * :ref:`read_html` * :ref:`read_gbq` (experimental) * :ref:`read_stata` + * :ref:`read_sas` * :ref:`read_clipboard` * :ref:`read_pickle` @@ -115,7 +116,7 @@ They can take a number of arguments: as the index. - ``names``: List of column names to use as column names. To replace header existing in file, explicitly pass ``header=0``. - - ``na_values``: optional list of strings to recognize as NaN (missing + - ``na_values``: optional string or list of strings to recognize as NaN (missing values), either in addition to or in lieu of the default set. - ``true_values``: list of strings to recognize as ``True`` - ``false_values``: list of strings to recognize as ``False`` @@ -723,7 +724,8 @@ NA Values ~~~~~~~~~ To control which values are parsed as missing values (which are signified by ``NaN``), specifiy a -list of strings in ``na_values``. If you specify a number (a ``float``, like ``5.0`` or an ``integer`` like ``5``), +string in ``na_values``. If you specify a list of strings, then all values in +it are considered to be missing values. If you specify a number (a ``float``, like ``5.0`` or an ``integer`` like ``5``), the corresponding equivalent values will also imply a missing value (in this case effectively ``[5.0,5]`` are recognized as ``NaN``. @@ -2130,7 +2132,9 @@ one can pass an :class:`~pandas.io.excel.ExcelWriter`. df1.to_excel(writer, sheet_name='Sheet1') df2.to_excel(writer, sheet_name='Sheet2') -.. note:: Wringing a little more performance out of ``read_excel`` +.. note:: + + Wringing a little more performance out of ``read_excel`` Internally, Excel stores all numeric data as floats. Because this can produce unexpected behavior when reading in data, pandas defaults to trying to convert integers to floats if it doesn't lose information (``1.0 --> @@ -2182,6 +2186,45 @@ argument to ``to_excel`` and to ``ExcelWriter``. The built-in engines are: df.to_excel('path_to_file.xlsx', sheet_name='Sheet1') +.. _io.excel_writing_buffer: + +Writing Excel Files to Memory +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. versionadded:: 0.17 + +Pandas supports writing Excel files to buffer-like objects such as ``StringIO`` or +``BytesIO`` using :class:`~pandas.io.excel.ExcelWriter`. + +.. code-block:: python + + # Safe import for either Python 2.x or 3.x + try: + from io import BytesIO + except ImportError: + from cStringIO import StringIO as BytesIO + + bio = BytesIO() + + # By setting the 'engine' in the ExcelWriter constructor. + writer = ExcelWriter(bio, engine='xlsxwriter') + df.to_excel(writer, sheet_name='Sheet1') + + # Save the workbook + writer.save() + + # Seek to the beginning and read to copy the workbook to a variable in memory + bio.seek(0) + workbook = bio.read() + +.. note:: + + ``engine`` is optional but recommended. Setting the engine determines + the version of workbook produced. Setting ``engine='xlrd'`` will produce an + Excel 2003-format workbook (xls). Using either ``'openpyxl'`` or + ``'xlsxwriter'`` will produce an Excel 2007-format workbook (xlsx). If + omitted, an Excel 2007-formatted workbook is produced. + .. _io.clipboard: Clipboard @@ -2365,9 +2408,13 @@ for some advanced strategies As of version 0.15.0, pandas requires ``PyTables`` >= 3.0.0. Stores written with prior versions of pandas / ``PyTables`` >= 2.3 are fully compatible (this was the previous minimum ``PyTables`` required version). .. warning:: - + There is a ``PyTables`` indexing bug which may appear when querying stores using an index. If you see a subset of results being returned, upgrade to ``PyTables`` >= 3.2. Stores created previously will need to be rewritten using the updated version. +.. warning:: + + As of version 0.17.0, ``HDFStore`` will not drop rows that have all missing values by default. Previously, if all values (except the index) were missing, ``HDFStore`` would not write those rows to disk. + .. ipython:: python :suppress: :okexcept: @@ -2444,6 +2491,8 @@ Closing a Store, Context Manager import os os.remove('store.h5') + + Read/Write API ~~~~~~~~~~~~~~ @@ -2462,6 +2511,65 @@ similar to how ``read_csv`` and ``to_csv`` work. (new in 0.11.0) os.remove('store_tl.h5') + +As of version 0.17.0, HDFStore will no longer drop rows that are all missing by default. This behavior can be enabled by setting ``dropna=True``. + +.. ipython:: python + :suppress: + + import os + +.. ipython:: python + + df_with_missing = pd.DataFrame({'col1':[0, np.nan, 2], + 'col2':[1, np.nan, np.nan]}) + df_with_missing + + df_with_missing.to_hdf('file.h5', 'df_with_missing', + format = 'table', mode='w') + + pd.read_hdf('file.h5', 'df_with_missing') + + df_with_missing.to_hdf('file.h5', 'df_with_missing', + format = 'table', mode='w', dropna=True) + pd.read_hdf('file.h5', 'df_with_missing') + + +.. ipython:: python + :suppress: + + os.remove('file.h5') + +This is also true for the major axis of a ``Panel``: + +.. ipython:: python + + matrix = [[[np.nan, np.nan, np.nan],[1,np.nan,np.nan]], + [[np.nan, np.nan, np.nan], [np.nan,5,6]], + [[np.nan, np.nan, np.nan],[np.nan,3,np.nan]]] + + panel_with_major_axis_all_missing = Panel(matrix, + items=['Item1', 'Item2','Item3'], + major_axis=[1,2], + minor_axis=['A', 'B', 'C']) + + panel_with_major_axis_all_missing + + panel_with_major_axis_all_missing.to_hdf('file.h5', 'panel', + dropna = True, + format='table', + mode='w') + reloaded = read_hdf('file.h5', 'panel') + reloaded + + +.. ipython:: python + :suppress: + + os.remove('file.h5') + + + .. _io.hdf5-fixed: Fixed Format @@ -3117,8 +3225,7 @@ Notes & Caveats ``PyTables`` only supports concurrent reads (via threading or processes). If you need reading and writing *at the same time*, you need to serialize these operations in a single thread in a single - process. You will corrupt your data otherwise. See the issue - (:`2397`) for more information. + process. You will corrupt your data otherwise. See the (:issue:`2397`) for more information. - If you use locks to manage write access between multiple processes, you may want to use :py:func:`~os.fsync` before releasing write locks. For convenience you can use ``store.flush(fsync=True)`` to do this for you. @@ -3137,9 +3244,10 @@ Notes & Caveats .. warning:: ``PyTables`` will show a ``NaturalNameWarning`` if a column name - cannot be used as an attribute selector. Generally identifiers that - have spaces, start with numbers, or ``_``, or have ``-`` embedded are not considered - *natural*. These types of identifiers cannot be used in a ``where`` clause + cannot be used as an attribute selector. + *Natural* identifiers contain only letters, numbers, and underscores, + and may not begin with a number. + Other identifiers cannot be used in a ``where`` clause and are generally a bad idea. DataTypes @@ -3148,34 +3256,19 @@ DataTypes ``HDFStore`` will map an object dtype to the ``PyTables`` underlying dtype. This means the following types are known to work: - - floating : ``float64, float32, float16`` *(using* ``np.nan`` *to - represent invalid values)* - - integer : ``int64, int32, int8, uint64, uint32, uint8`` - - bool - - datetime64[ns] *(using* ``NaT`` *to represent invalid values)* - - object : ``strings`` *(using* ``np.nan`` *to represent invalid - values)* - -Currently, ``unicode`` and ``datetime`` columns (represented with a -dtype of ``object``), **WILL FAIL**. In addition, even though a column -may look like a ``datetime64[ns]``, if it contains ``np.nan``, this -**WILL FAIL**. You can try to convert datetimelike columns to proper -``datetime64[ns]`` columns, that possibly contain ``NaT`` to represent -invalid values. (Some of these issues have been addressed and these -conversion may not be necessary in future versions of pandas) - - .. ipython:: python - - import datetime - df = DataFrame(dict(datelike=Series([datetime.datetime(2001, 1, 1), - datetime.datetime(2001, 1, 2), np.nan]))) - df - df.dtypes - - # to convert - df['datelike'] = Series(df['datelike'].values, dtype='M8[ns]') - df - df.dtypes +====================================================== ========================= +Type Represents missing values +====================================================== ========================= +floating : ``float64, float32, float16`` ``np.nan`` +integer : ``int64, int32, int8, uint64,uint32, uint8`` +boolean +``datetime64[ns]`` ``NaT`` +``timedelta64[ns]`` ``NaT`` +categorical : see the section below +object : ``strings`` ``np.nan`` +====================================================== ========================= + +``unicode`` columns are not supported, and **WILL FAIL**. .. _io.hdf5-categorical: @@ -3513,9 +3606,16 @@ below and the SQLAlchemy `documentation / - # where is relative: - engine = create_engine('sqlite:///foo.db') + # sqlite:/// + # where is relative: + engine = create_engine('sqlite:///foo.db') - # or absolute, starting with a slash: - engine = create_engine('sqlite:////absolute/path/to/foo.db') + # or absolute, starting with a slash: + engine = create_engine('sqlite:////absolute/path/to/foo.db') For more information see the examples the SQLAlchemy `documentation `__ @@ -3824,8 +3924,8 @@ will produce the dictionary representation of the schema. .. code-block:: python - df = pandas.DataFrame({'A': [1.0]}) - gbq.generate_bq_schema(df, default_type='STRING') + df = pandas.DataFrame({'A': [1.0]}) + gbq.generate_bq_schema(df, default_type='STRING') .. warning:: @@ -3939,8 +4039,11 @@ missing values are represented as ``np.nan``. If ``True``, missing values are represented using ``StataMissingValue`` objects, and columns containing missing values will have ``object`` data type. -:func:`~pandas.read_stata` and :class:`~pandas.io.stata.StataReader` supports .dta -formats 104, 105, 108, 113-115 (Stata 10-12) and 117 (Stata 13+). +.. note:: + + :func:`~pandas.read_stata` and + :class:`~pandas.io.stata.StataReader` support .dta formats 113-115 + (Stata 10-12), 117 (Stata 13), and 118 (Stata 14). .. note:: @@ -4018,6 +4121,46 @@ easy conversion to and from pandas. .. _xray: http://xray.readthedocs.org/ +.. _io.sas: + +SAS Format +---------- + +.. versionadded:: 0.17.0 + +The top-level function :function:`read_sas` currently can read (but +not write) SAS xport (.XPT) format files. Pandas cannot currently +handle SAS7BDAT files. + +XPORT files only contain two value types: ASCII text and double +precision numeric values. There is no automatic type conversion to +integers, dates, or categoricals. By default the whole file is read +and returned as a ``DataFrame``. + +Specify a ``chunksize`` or use ``iterator=True`` to obtain an +``XportReader`` object for incrementally reading the file. The +``XportReader`` object also has attributes that contain additional +information about the file and its variables. + +Read a SAS XPORT file: + +.. code-block:: python + + df = pd.read_sas('sas_xport.xpt') + +Obtain an iterator and read an XPORT file 100,000 lines at a time: + +.. code-block:: python + + rdr = pd.read_sas('sas_xport.xpt', chunk=100000) + for chunk in rdr: + do_something(chunk) + +The specification_ for the xport file format is available from the SAS +web site. + +.. _specification: https://support.sas.com/techsup/technote/ts140.pdf + .. _io.perf: Performance Considerations @@ -4027,14 +4170,16 @@ This is an informal comparison of various IO methods, using pandas 0.13.1. .. code-block:: python - In [3]: df = DataFrame(randn(1000000,2),columns=list('AB')) + In [1]: df = DataFrame(randn(1000000,2),columns=list('AB')) + + In [2]: df.info() Int64Index: 1000000 entries, 0 to 999999 Data columns (total 2 columns): - A 1000000 non-null values - B 1000000 non-null values + A 1000000 non-null float64 + B 1000000 non-null float64 dtypes: float64(2) - + memory usage: 22.9 MB Writing diff --git a/doc/source/missing_data.rst b/doc/source/missing_data.rst index 04a6302f958a2..51293ca4240c6 100644 --- a/doc/source/missing_data.rst +++ b/doc/source/missing_data.rst @@ -68,26 +68,41 @@ detect this value with data of different types: floating point, integer, boolean, and general object. In many cases, however, the Python ``None`` will arise and we wish to also consider that "missing" or "null". -Prior to version v0.10.0 ``inf`` and ``-inf`` were also -considered to be "null" in computations. This is no longer the case by -default; use the ``mode.use_inf_as_null`` option to recover it. +.. note:: + + Prior to version v0.10.0 ``inf`` and ``-inf`` were also + considered to be "null" in computations. This is no longer the case by + default; use the ``mode.use_inf_as_null`` option to recover it. .. _missing.isnull: To make detecting missing values easier (and across different array dtypes), pandas provides the :func:`~pandas.core.common.isnull` and :func:`~pandas.core.common.notnull` functions, which are also methods on -``Series`` objects: +``Series`` and ``DataFrame`` objects: .. ipython:: python df2['one'] - isnull(df2['one']) + pd.isnull(df2['one']) df2['four'].notnull() + df2.isnull() + +.. warning:: + + One has to be mindful that in python (and numpy), the ``nan's`` don't compare equal, but ``None's`` **do**. + Note that Pandas/numpy uses the fact that ``np.nan != np.nan``, and treats ``None`` like ``np.nan``. + + .. ipython:: python -**Summary:** ``NaN`` and ``None`` (in object arrays) are considered -missing by the ``isnull`` and ``notnull`` functions. ``inf`` and -``-inf`` are no longer considered missing by default. + None == None + np.nan == np.nan + + So as compared to above, a scalar equality comparison versus a ``None/np.nan`` doesn't provide useful information. + + .. ipython:: python + + df2['one'] == np.nan Datetimes --------- @@ -99,7 +114,7 @@ pandas objects provide intercompatibility between ``NaT`` and ``NaN``. .. ipython:: python df2 = df.copy() - df2['timestamp'] = Timestamp('20120101') + df2['timestamp'] = pd.Timestamp('20120101') df2 df2.ix[['a','c','h'],['one','timestamp']] = np.nan df2 @@ -158,10 +173,10 @@ The descriptive statistics and computational methods discussed in the ` and :ref:`here `) are all written to account for missing data. For example: - * When summing data, NA (missing) values will be treated as zero - * If the data are all NA, the result will be NA - * Methods like **cumsum** and **cumprod** ignore NA values, but preserve them - in the resulting arrays +* When summing data, NA (missing) values will be treated as zero +* If the data are all NA, the result will be NA +* Methods like **cumsum** and **cumprod** ignore NA values, but preserve them + in the resulting arrays .. ipython:: python @@ -174,9 +189,14 @@ NA values in GroupBy ~~~~~~~~~~~~~~~~~~~~ NA groups in GroupBy are automatically excluded. This behavior is consistent -with R, for example. +with R, for example: + +.. ipython:: python + df + df.groupby('one').mean() +See the groupby section :ref:`here ` for more information. Cleaning / filling missing data -------------------------------- @@ -255,7 +275,7 @@ use case of this is to fill a DataFrame with the mean of that column. .. ipython:: python - dff = pd.DataFrame(np.random.randn(10,3),columns=list('ABC')) + dff = pd.DataFrame(np.random.randn(10,3), columns=list('ABC')) dff.iloc[3:5,0] = np.nan dff.iloc[4:6,1] = np.nan dff.iloc[5:8,2] = np.nan @@ -271,7 +291,7 @@ a Series in this case. .. ipython:: python - dff.where(notnull(dff),dff.mean(),axis='columns') + dff.where(pd.notnull(dff), dff.mean(), axis='columns') .. _missing_data.dropna: @@ -316,7 +336,7 @@ performs linear interpolation at missing datapoints. :suppress: np.random.seed(123456) - idx = date_range('1/1/2000', periods=100, freq='BM') + idx = pd.date_range('1/1/2000', periods=100, freq='BM') ts = pd.Series(np.random.randn(100), index=idx) ts[1:20] = np.nan ts[60:80] = np.nan @@ -363,7 +383,7 @@ You can also interpolate with a DataFrame: .. ipython:: python df = pd.DataFrame({'A': [1, 2.1, np.nan, 4.7, 5.6, 6.8], - 'B': [.25, np.nan, np.nan, 4, 12.2, 14.4]}) + 'B': [.25, np.nan, np.nan, 4, 12.2, 14.4]}) df df.interpolate() @@ -420,7 +440,7 @@ at the new values. ser = pd.Series(np.sort(np.random.uniform(size=100))) # interpolate at new_index - new_index = ser.index | Index([49.25, 49.5, 49.75, 50.25, 50.5, 50.75]) + new_index = ser.index | pd.Index([49.25, 49.5, 49.75, 50.25, 50.5, 50.75]) interp_s = ser.reindex(new_index).interpolate(method='pchip') interp_s[49:51] diff --git a/doc/source/options.rst b/doc/source/options.rst index 9ede87422b21c..26871a11473de 100644 --- a/doc/source/options.rst +++ b/doc/source/options.rst @@ -154,7 +154,7 @@ lines are replaced by an ellipsis. .. ipython:: python - df=pd.DataFrame(np.random.randn(7,2)) + df = pd.DataFrame(np.random.randn(7,2)) pd.set_option('max_rows', 7) df pd.set_option('max_rows', 5) @@ -166,7 +166,7 @@ dataframes to stretch across pages, wrapped over the full column vs row-wise. .. ipython:: python - df=pd.DataFrame(np.random.randn(5,10)) + df = pd.DataFrame(np.random.randn(5,10)) pd.set_option('expand_frame_repr', True) df pd.set_option('expand_frame_repr', False) @@ -178,7 +178,7 @@ dataframes to stretch across pages, wrapped over the full column vs row-wise. .. ipython:: python - df=pd.DataFrame(np.random.randn(10,10)) + df = pd.DataFrame(np.random.randn(10,10)) pd.set_option('max_rows', 5) pd.set_option('large_repr', 'truncate') df @@ -192,8 +192,8 @@ of this length or longer will be truncated with an ellipsis. .. ipython:: python - df=pd.DataFrame(np.array([['foo', 'bar', 'bim', 'uncomfortably long string'], - ['horse', 'cow', 'banana', 'apple']])) + df = pd.DataFrame(np.array([['foo', 'bar', 'bim', 'uncomfortably long string'], + ['horse', 'cow', 'banana', 'apple']])) pd.set_option('max_colwidth',40) df pd.set_option('max_colwidth', 6) @@ -205,7 +205,7 @@ will be given. .. ipython:: python - df=pd.DataFrame(np.random.randn(10,10)) + df = pd.DataFrame(np.random.randn(10,10)) pd.set_option('max_info_columns', 11) df.info() pd.set_option('max_info_columns', 5) @@ -219,7 +219,7 @@ can specify the option ``df.info(null_counts=True)`` to override on showing a pa .. ipython:: python - df=pd.DataFrame(np.random.choice([0,1,np.nan],size=(10,10))) + df =pd.DataFrame(np.random.choice([0,1,np.nan], size=(10,10))) df pd.set_option('max_info_rows', 11) df.info() @@ -227,12 +227,12 @@ can specify the option ``df.info(null_counts=True)`` to override on showing a pa df.info() pd.reset_option('max_info_rows') -``display.precision`` sets the output display precision. This is only a +``display.precision`` sets the output display precision in terms of decimal places. This is only a suggestion. .. ipython:: python - df=pd.DataFrame(np.random.randn(5,5)) + df = pd.DataFrame(np.random.randn(5,5)) pd.set_option('precision',7) df pd.set_option('precision',4) @@ -244,7 +244,7 @@ precision at which the number is stored. .. ipython:: python - df=pd.DataFrame(np.random.randn(6,6)) + df = pd.DataFrame(np.random.randn(6,6)) pd.set_option('chop_threshold', 0) df pd.set_option('chop_threshold', .5) @@ -256,7 +256,8 @@ Options are 'right', and 'left'. .. ipython:: python - df=pd.DataFrame(np.array([np.random.randn(6), np.random.randint(1,9,6)*.1, np.zeros(6)]).T, columns=['A', 'B', 'C'], dtype='float') + df = pd.DataFrame(np.array([np.random.randn(6), np.random.randint(1,9,6)*.1, np.zeros(6)]).T, + columns=['A', 'B', 'C'], dtype='float') pd.set_option('colheader_justify', 'right') df pd.set_option('colheader_justify', 'left') @@ -367,9 +368,11 @@ display.notebook_repr_html True When True, IPython notebook will pandas objects (if it is available). display.pprint_nest_depth 3 Controls the number of nested levels to process when pretty-printing -display.precision 7 Floating point output precision - (number of significant digits). This is - only a suggestion +display.precision 6 Floating point output precision in + terms of number of places after the + decimal, for regular formatting as well + as scientific notation. Similar to + numpy's ``precision`` print option display.show_dimensions truncate Whether to print out dimensions at the end of DataFrame repr. If 'truncate' is specified, only diff --git a/doc/source/r_interface.rst b/doc/source/r_interface.rst index da37c92c88ecf..74cdc5a526585 100644 --- a/doc/source/r_interface.rst +++ b/doc/source/r_interface.rst @@ -5,8 +5,8 @@ .. ipython:: python :suppress: - from pandas import * - options.display.max_rows=15 + import pandas as pd + pd.options.display.max_rows = 15 ****************** @@ -136,10 +136,8 @@ DataFrames into the equivalent R object (that is, **data.frame**): .. ipython:: python - from pandas import DataFrame - - df = DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6], 'C':[7,8,9]}, - index=["one", "two", "three"]) + df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6], 'C':[7,8,9]}, + index=["one", "two", "three"]) r_dataframe = com.convert_to_r_dataframe(df) print(type(r_dataframe)) diff --git a/doc/source/timedeltas.rst b/doc/source/timedeltas.rst index 8215414e425fe..e62f4f9387526 100644 --- a/doc/source/timedeltas.rst +++ b/doc/source/timedeltas.rst @@ -97,6 +97,8 @@ It will construct Series if the input is a Series, a scalar if the input is scal to_timedelta(np.arange(5),unit='s') to_timedelta(np.arange(5),unit='d') +.. _timedeltas.operations: + Operations ---------- diff --git a/doc/source/timeseries.rst b/doc/source/timeseries.rst index ce1035e91391a..6f30ff3f51ad5 100644 --- a/doc/source/timeseries.rst +++ b/doc/source/timeseries.rst @@ -71,6 +71,23 @@ Resample: ts.resample('D', how='mean') +.. _timeseries.overview: + +Overview +-------- + +Following table shows the type of time-related classes pandas can handle and +how to create them. + +================= ============================== ================================================== +Class Remarks How to create +================= ============================== ================================================== +``Timestamp`` Represents a single time stamp ``to_datetime``, ``Timestamp`` +``DatetimeIndex`` Index of ``Timestamps`` ``to_datetime``, ``date_range``, ``DatetimeIndex`` +``Period`` Represents a single time span ``Period`` +``PeriodIndex`` Index of ``Period`` ``period_range``, ``PeriodIndex`` +================= ============================== ================================================== + .. _timeseries.representation: Time Stamps vs. Time Spans @@ -78,30 +95,45 @@ Time Stamps vs. Time Spans Time-stamped data is the most basic type of timeseries data that associates values with points in time. For pandas objects it means using the points in -time to create the index +time. .. ipython:: python - dates = [datetime(2012, 5, 1), datetime(2012, 5, 2), datetime(2012, 5, 3)] - ts = Series(np.random.randn(3), dates) - - type(ts.index) - - ts + Timestamp(datetime(2012, 5, 1)) + Timestamp('2012-05-01') However, in many cases it is more natural to associate things like change -variables with a time span instead. +variables with a time span instead. The span represented by ``Period`` can be +specified explicitly, or inferred from datetime string format. For example: .. ipython:: python - periods = PeriodIndex([Period('2012-01'), Period('2012-02'), - Period('2012-03')]) + Period('2011-01') + + Period('2012-05', freq='D') + +``Timestamp`` and ``Period`` can be the index. Lists of ``Timestamp`` and +``Period`` are automatically coerce to ``DatetimeIndex`` and ``PeriodIndex`` +respectively. + +.. ipython:: python + + dates = [Timestamp('2012-05-01'), Timestamp('2012-05-02'), Timestamp('2012-05-03')] + ts = Series(np.random.randn(3), dates) + + type(ts.index) + ts.index + + ts + + periods = [Period('2012-01'), Period('2012-02'), Period('2012-03')] ts = Series(np.random.randn(3), periods) type(ts.index) + ts.index ts @@ -150,24 +182,39 @@ you can pass the ``dayfirst`` flag: considerably and on versions later then 0.13.0 explicitly specifying a format string of '%Y%m%d' takes a faster path still. +If you pass a single string to ``to_datetime``, it returns single ``Timestamp``. +Also, ``Timestamp`` can accept the string input. +Note that ``Timestamp`` doesn't accept string parsing option like ``dayfirst`` +or ``format``, use ``to_datetime`` if these are required. -Invalid Data -~~~~~~~~~~~~ +.. ipython:: python -Pass ``coerce=True`` to convert invalid data to ``NaT`` (not a time): + to_datetime('2010/11/12') -.. ipython:: python + Timestamp('2010/11/12') - to_datetime(['2009-07-31', 'asd']) - to_datetime(['2009-07-31', 'asd'], coerce=True) +Invalid Data +~~~~~~~~~~~~ +.. note:: + + In version 0.17.0, the default for ``to_datetime`` is now ``errors='raise'``, rather than ``errors='ignore'``. This means + that invalid parsing will raise rather that return the original input as in previous versions. -Take care, ``to_datetime`` may not act as you expect on mixed data: +Pass ``errors='coerce'`` to convert invalid data to ``NaT`` (not a time): .. ipython:: python + :okexcept: - to_datetime([1, '1']) + # this is the default, raise when unparseable + to_datetime(['2009/07/31', 'asd'], errors='raise') + + # return the original input when unparseable + to_datetime(['2009/07/31', 'asd'], errors='ignore') + + # return NaT for input when unparseable + to_datetime(['2009/07/31', 'asd'], errors='coerce') Epoch Timestamps ~~~~~~~~~~~~~~~~ @@ -592,6 +639,46 @@ Another example is parameterizing ``YearEnd`` with the specific ending month: d + YearEnd() d + YearEnd(month=6) + +.. _timeseries.offsetseries: + +Using offsets with ``Series`` / ``DatetimeIndex`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Offsets can be used with either a ``Series`` or ``DatetimeIndex`` to +apply the offset to each element. + +.. ipython:: python + + rng = date_range('2012-01-01', '2012-01-03') + s = Series(rng) + rng + rng + DateOffset(months=2) + s + DateOffset(months=2) + s - DateOffset(months=2) + +If the offset class maps directly to a ``Timedelta`` (``Day``, ``Hour``, +``Minute``, ``Second``, ``Micro``, ``Milli``, ``Nano``) it can be +used exactly like a ``Timedelta`` - see the +:ref:`Timedelta section` for more examples. + +.. ipython:: python + + s - Day(2) + td = s - Series(date_range('2011-12-29', '2011-12-31')) + td + td + Minute(15) + +Note that some offsets (such as ``BQuarterEnd``) do not have a +vectorized implementation. They can still be used but may +calculate signficantly slower and will raise a ``PerformanceWarning`` + +.. ipython:: python + :okwarning: + + rng + BQuarterEnd() + + .. _timeseries.alias: Custom Business Days (Experimental) diff --git a/doc/source/visualization.rst b/doc/source/visualization.rst index 51912b5d6b106..4378d182b3128 100644 --- a/doc/source/visualization.rst +++ b/doc/source/visualization.rst @@ -1649,6 +1649,7 @@ values, the resulting grid has two columns and two rows. A histogram is displayed for each cell of the grid. .. ipython:: python + :okwarning: plt.figure() @@ -1680,6 +1681,7 @@ Example below is the same as previous except the plot is set to kernel density estimation. A ``seaborn`` example is included beneath. .. ipython:: python + :okwarning: plt.figure() @@ -1706,6 +1708,7 @@ The plot below shows that it is possible to have two or more plots for the same data displayed on the same Trellis grid cell. .. ipython:: python + :okwarning: plt.figure() @@ -1745,6 +1748,7 @@ Below is a similar plot but with 2D kernel density estimation plot superimposed, followed by a ``seaborn`` equivalent: .. ipython:: python + :okwarning: plt.figure() @@ -1774,6 +1778,7 @@ only uses 'sex' attribute. If the second grouping attribute is not specified, the plots will be arranged in a column. .. ipython:: python + :okwarning: plt.figure() @@ -1792,6 +1797,7 @@ the plots will be arranged in a column. If the first grouping attribute is not specified the plots will be arranged in a row. .. ipython:: python + :okwarning: plt.figure() @@ -1816,6 +1822,7 @@ scale objects to specify these mappings. The list of scale classes is given below with initialization arguments for quick reference. .. ipython:: python + :okwarning: plt.figure() diff --git a/doc/source/whatsnew/v0.11.0.txt b/doc/source/whatsnew/v0.11.0.txt index befdf848ad23b..50b74fc5af090 100644 --- a/doc/source/whatsnew/v0.11.0.txt +++ b/doc/source/whatsnew/v0.11.0.txt @@ -103,6 +103,7 @@ Conversion Mixed Conversion .. ipython:: python + :okwarning: df3['D'] = '1.' df3['E'] = '1' @@ -116,6 +117,7 @@ Mixed Conversion Forcing Date coercion (and setting ``NaT`` when not datelike) .. ipython:: python + :okwarning: from datetime import datetime s = Series([datetime(2001,1,1,0,0), 'foo', 1.0, 1, @@ -328,4 +330,3 @@ Enhancements See the :ref:`full release notes ` or issue tracker on GitHub for a complete list. - diff --git a/doc/source/whatsnew/v0.17.0.txt b/doc/source/whatsnew/v0.17.0.txt index 164ab73def894..039772f68ee85 100644 --- a/doc/source/whatsnew/v0.17.0.txt +++ b/doc/source/whatsnew/v0.17.0.txt @@ -1,14 +1,26 @@ .. _whatsnew_0170: -v0.17.0 (July 31, 2015) ------------------------ +v0.17.0 (???) +------------- This is a major release from 0.16.2 and includes a small number of API changes, several new features, enhancements, and performance improvements along with a large number of bug fixes. We recommend that all users upgrade to this version. +.. warning:: + + pandas >= 0.17.0 will no longer support compatibility with Python version 3.2 (:issue:`9118`) + Highlights include: +- Release the Global Interpreter Lock (GIL) on some cython operations, see :ref:`here ` +- The default for ``to_datetime`` will now be to ``raise`` when presented with unparseable formats, + previously this would return the original input, see :ref:`here ` +- The default for ``dropna`` in ``HDFStore`` has changed to ``False``, to store by default all rows even + if they are all ``NaN``, see :ref:`here ` +- Support for ``Series.dt.strftime`` to generate formatted strings for datetime-likes, see :ref:`here ` +- Development installed versions of pandas will now have ``PEP440`` compliant version strings (:issue:`9518`) +- Support for reading SAS xport files, see :ref:`here ` Check the :ref:`API Changes ` and :ref:`deprecations ` before updating. @@ -21,40 +33,668 @@ Check the :ref:`API Changes ` and :ref:`deprecations `_ + +.. _whatsnew_0170.enhancements.sas_xport: + +Support for SAS XPORT files +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +:meth:`~pandas.io.read_sas` provides support for reading *SAS XPORT* format files. (:issue:`4052`). + +.. code-block:: python + + df = pd.read_sas('sas_xport.xpt') + +It is also possible to obtain an iterator and read an XPORT file +incrementally. + +.. code-block:: python + + for df in pd.read_sas('sas_xport.xpt', chunksize=10000) + do_something(df) + +See the :ref:`docs ` for more details. .. _whatsnew_0170.enhancements.other: Other enhancements ^^^^^^^^^^^^^^^^^^ +- `read_sql` and `to_sql` can accept database URI as con parameter (:issue:`10214`) + +- Enable `read_hdf` to be used without specifying a key when the HDF file contains a single dataset (:issue:`10443`) + +- Added functionality to use the ``base`` argument when resampling a ``TimeDeltaIndex`` (:issue:`10530`) + +- ``DatetimeIndex`` can be instantiated using strings contains ``NaT`` (:issue:`7599`) +- The string parsing of ``to_datetime``, ``Timestamp`` and ``DatetimeIndex`` has been made consistent. (:issue:`7599`) + + Prior to v0.17.0, ``Timestamp`` and ``to_datetime`` may parse year-only datetime-string incorrectly using today's date, otherwise ``DatetimeIndex`` + uses the beginning of the year. ``Timestamp`` and ``to_datetime`` may raise ``ValueError`` in some types of datetime-string which ``DatetimeIndex`` + can parse, such as a quarterly string. + + Previous Behavior + + .. code-block:: python + + In [1]: Timestamp('2012Q2') + Traceback + ... + ValueError: Unable to parse 2012Q2 + + # Results in today's date. + In [2]: Timestamp('2014') + Out [2]: 2014-08-12 00:00:00 + + v0.17.0 can parse them as below. It works on ``DatetimeIndex`` also. + + New Behaviour + + .. ipython:: python + + Timestamp('2012Q2') + Timestamp('2014') + DatetimeIndex(['2012Q2', '2014']) + + .. note:: If you want to perform calculations based on today's date, use ``Timestamp.now()`` and ``pandas.tseries.offsets``. + + .. ipython:: python + + import pandas.tseries.offsets as offsets + Timestamp.now() + Timestamp.now() + offsets.DateOffset(years=1) + +- ``to_datetime`` can now accept ``yearfirst`` keyword (:issue:`7599`) + +- ``pandas.tseries.offsets`` larger than the ``Day`` offset can now be used with with ``Series`` for addition/subtraction (:issue:`10699`). See the :ref:`Documentation ` for more details. + +- ``.as_blocks`` will now take a ``copy`` optional argument to return a copy of the data, default is to copy (no change in behavior from prior versions), (:issue:`9607`) + +- ``regex`` argument to ``DataFrame.filter`` now handles numeric column names instead of raising ``ValueError`` (:issue:`10384`). +- ``pd.read_stata`` will now read Stata 118 type files. (:issue:`9882`) + +- ``pd.merge`` will now allow duplicate column names if they are not merged upon (:issue:`10639`). + +- ``pd.pivot`` will now allow passing index as ``None`` (:issue:`3962`). + +- ``read_sql_table`` will now allow reading from views (:issue:`10750`). + +- ``drop_duplicates`` and ``duplicated`` now accept ``keep`` keyword to target first, last, and all duplicates. ``take_last`` keyword is deprecated, see :ref:`deprecations ` (:issue:`6511`, :issue:`8505`) + +- ``msgpack`` submodule has been updated to 0.4.6 with backward compatibility (:issue:`10581`) + +.. ipython :: python + + s = pd.Series(['A', 'B', 'C', 'A', 'B', 'D']) + s.drop_duplicates() + s.drop_duplicates(keep='last') + s.drop_duplicates(keep=False) + + +- Reindex now has a ``tolerance`` argument that allows for finer control of :ref:`basics.limits_on_reindex_fill`: + + .. ipython:: python + + df = pd.DataFrame({'x': range(5), 't': pd.date_range('2000-01-01', periods=5)}) + df.reindex([0.1, 1.9, 3.5], method='nearest', tolerance=0.2) + + When used on a ``DatetimeIndex``, ``TimedeltaIndex`` or ``PeriodIndex``, ``tolerance`` will coerced into a ``Timedelta`` if possible. This allows you to specify tolerance with a string: + + .. ipython:: python + + df = df.set_index('t') + df.reindex(pd.to_datetime(['1999-12-31']), method='nearest', tolerance='1 day') + + ``tolerance`` is also exposed by the lower level ``Index.get_indexer`` and ``Index.get_loc`` methods. + .. _whatsnew_0170.api: +.. _whatsnew_0170.api_breaking: + Backwards incompatible API changes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. _whatsnew_0170.api_breaking: +.. _whatsnew_0170.api_breaking.to_datetime: + +Changes to to_datetime and to_timedelta +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The default for ``pd.to_datetime`` error handling has changed to ``errors='raise'``. In prior versions it was ``errors='ignore'``. +Furthermore, the ``coerce`` argument has been deprecated in favor of ``errors='coerce'``. This means that invalid parsing will raise rather that return the original +input as in previous versions. (:issue:`10636`) + +Previous Behavior: + +.. code-block:: python + + In [2]: pd.to_datetime(['2009-07-31', 'asd']) + Out[2]: array(['2009-07-31', 'asd'], dtype=object) + +New Behavior: + +.. code-block:: python + + In [3]: pd.to_datetime(['2009-07-31', 'asd']) + ValueError: Unknown string format + +.. ipython:: python + +Of course you can coerce this as well. + +.. ipython:: python + + to_datetime(['2009-07-31', 'asd'], errors='coerce') + +To keep the previous behaviour, you can use ``errors='ignore'``: + +.. ipython:: python + + to_datetime(['2009-07-31', 'asd'], errors='ignore') + +Furthermore, ``pd.to_timedelta`` has gained a similar API, of ``errors='raise'|'ignore'|'coerce'``, and the ``coerce`` keyword +has been deprecated in favor of ``errors='coerce'``. + +.. _whatsnew_0170.api_breaking.convert_objects: + +Changes to convert_objects +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``DataFrame.convert_objects`` keyword arguments have been shortened. (:issue:`10265`) + + ===================== ============= + Old New + ===================== ============= + ``convert_dates`` ``datetime`` + ``convert_numeric`` ``numeric`` + ``convert_timedelta`` ``timedelta`` + ===================== ============= + +Coercing types with ``DataFrame.convert_objects`` is now implemented using the +keyword argument ``coerce=True``. Previously types were coerced by setting a +keyword argument to ``'coerce'`` instead of ``True``, as in ``convert_dates='coerce'``. + +.. ipython:: python + + df = pd.DataFrame({'i': ['1','2'], + 'f': ['apple', '4.2'], + 's': ['apple','banana']}) + df + +The old usage of ``DataFrame.convert_objects`` used `'coerce'` along with the +type. + +.. code-block:: python + + In [2]: df.convert_objects(convert_numeric='coerce') + +Now the ``coerce`` keyword must be explicitly used. + +.. ipython:: python + + df.convert_objects(numeric=True, coerce=True) + +In earlier versions of pandas, ``DataFrame.convert_objects`` would not coerce +numeric types when there were no values convertible to a numeric type. This returns +the original DataFrame with no conversion. This change alters +this behavior so that converts all non-number-like strings to ``NaN``. + +.. code-block:: python + + In [1]: df = pd.DataFrame({'s': ['a','b']}) + In [2]: df.convert_objects(convert_numeric='coerce') + Out[2]: + s + 0 a + 1 b + +.. ipython:: python + + pd.DataFrame({'s': ['a','b']}) + df.convert_objects(numeric=True, coerce=True) + +In earlier versions of pandas, the default behavior was to try and convert +datetimes and timestamps. The new default is for ``DataFrame.convert_objects`` +to do nothing, and so it is necessary to pass at least one conversion target +in the method call. + +Changes to Index Comparisons +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Operator equal on Index should behavior similarly to Series (:issue:`9947`, :issue:`10637`) + +Starting in v0.17.0, comparing ``Index`` objects of different lengths will raise +a ``ValueError``. This is to be consistent with the behavior of ``Series``. + +Previous behavior: + +.. code-block:: python + + In [2]: pd.Index([1, 2, 3]) == pd.Index([1, 4, 5]) + Out[2]: array([ True, False, False], dtype=bool) + + In [3]: pd.Index([1, 2, 3]) == pd.Index([2]) + Out[3]: array([False, True, False], dtype=bool) + + In [4]: pd.Index([1, 2, 3]) == pd.Index([1, 2]) + Out[4]: False + + In [5]: pd.Series([1, 2, 3]) == pd.Series([1, 4, 5]) + Out[5]: + 0 True + 1 False + 2 False + dtype: bool + + In [6]: pd.Series([1, 2, 3]) == pd.Series([2]) + ValueError: Series lengths must match to compare + + In [7]: pd.Series([1, 2, 3]) == pd.Series([1, 2]) + ValueError: Series lengths must match to compare + +New behavior: + +.. code-block:: python + + In [8]: pd.Index([1, 2, 3]) == pd.Index([1, 4, 5]) + Out[8]: array([ True, False, False], dtype=bool) + + In [9]: pd.Index([1, 2, 3]) == pd.Index([2]) + ValueError: Lengths must match to compare + + In [10]: pd.Index([1, 2, 3]) == pd.Index([1, 2]) + ValueError: Lengths must match to compare + + In [11]: pd.Series([1, 2, 3]) == pd.Series([1, 4, 5]) + Out[11]: + 0 True + 1 False + 2 False + dtype: bool + + In [12]: pd.Series([1, 2, 3]) == pd.Series([2]) + ValueError: Series lengths must match to compare + + In [13]: pd.Series([1, 2, 3]) == pd.Series([1, 2]) + ValueError: Series lengths must match to compare + +Note that this is different from the ``numpy`` behavior where a comparison can +be broadcast: + +.. ipython:: python + + np.array([1, 2, 3]) == np.array([1]) + +or it can return False if broadcasting can not be done: + +.. ipython:: python + + np.array([1, 2, 3]) == np.array([1, 2]) + +Changes to Boolean Comparisons vs. None +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Boolean comparisons of a ``Series`` vs ``None`` will now be equivalent to comparing with ``np.nan``, rather than raise ``TypeError``. xref (:issue:`1079`). + +.. ipython:: python + + s = Series(range(3)) + s.iloc[1] = None + s + +Previous behavior: + +.. code-block:: python + + In [5]: s==None + TypeError: Could not compare type with Series + +New behavior: + +.. ipython:: python + + s==None + +Usually you simply want to know which values are null. + +.. ipython:: python + + s.isnull() + +.. warning:: + + You generally will want to use ``isnull/notnull`` for these types of comparisons, as ``isnull/notnull`` tells you which elements are null. One has to be + mindful that ``nan's`` don't compare equal, but ``None's`` do. Note that Pandas/numpy uses the fact that ``np.nan != np.nan``, and treats ``None`` like ``np.nan``. + + .. ipython:: python + + None == None + np.nan == np.nan + +.. _whatsnew_0170.api_breaking.hdf_dropna: + +HDFStore dropna behavior +^^^^^^^^^^^^^^^^^^^^^^^^ + +The default behavior for HDFStore write functions with ``format='table'`` is now to keep rows that are all missing. Previously, the behavior was to drop rows that were all missing save the index. The previous behavior can be replicated using the ``dropna=True`` option. (:issue:`9382`) + +Previously: + +.. ipython:: python + + df_with_missing = pd.DataFrame({'col1':[0, np.nan, 2], + 'col2':[1, np.nan, np.nan]}) + + df_with_missing + + +.. code-block:: python + + In [28]: + df_with_missing.to_hdf('file.h5', 'df_with_missing', format='table', mode='w') + + pd.read_hdf('file.h5', 'df_with_missing') + + Out [28]: + col1 col2 + 0 0 1 + 2 2 NaN + + +New behavior: + +.. ipython:: python + :suppress: + + import os + +.. ipython:: python + + df_with_missing.to_hdf('file.h5', 'df_with_missing', format = 'table', mode='w') + + pd.read_hdf('file.h5', 'df_with_missing') + +.. ipython:: python + :suppress: + + os.remove('file.h5') + +See :ref:`documentation ` for more details. + +Changes to ``display.precision`` option +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The ``display.precision`` option has been clarified to refer to decimal places (:issue:`10451`). + +Earlier versions of pandas would format floating point numbers to have one less decimal place than the value in +``display.precision``. + +.. code-block:: python + + In [1]: pd.set_option('display.precision', 2) + + In [2]: pd.DataFrame({'x': [123.456789]}) + Out[2]: + x + 0 123.5 + +If interpreting precision as "significant figures" this did work for scientific notation but that same interpretation +did not work for values with standard formatting. It was also out of step with how numpy handles formatting. + +Going forward the value of ``display.precision`` will directly control the number of places after the decimal, for +regular formatting as well as scientific notation, similar to how numpy's ``precision`` print option works. + +.. ipython:: python + + pd.set_option('display.precision', 2) + pd.DataFrame({'x': [123.456789]}) + +To preserve output behavior with prior versions the default value of ``display.precision`` has been reduced to ``6`` +from ``7``. + +.. ipython:: python + :suppress: + + pd.set_option('display.precision', 6) + .. _whatsnew_0170.api_breaking.other: Other API Changes ^^^^^^^^^^^^^^^^^ +- Line and kde plot with ``subplots=True`` now uses default colors, not all black. Specify ``color='k'`` to draw all lines in black (:issue:`9894`) +- Calling the ``.value_counts`` method on a Series with ``categorical`` dtype now returns a Series with a ``CategoricalIndex`` (:issue:`10704`) +- Enable writing Excel files in :ref:`memory <_io.excel_writing_buffer>` using StringIO/BytesIO (:issue:`7074`) +- Enable serialization of lists and dicts to strings in ExcelWriter (:issue:`8188`) +- Allow passing `kwargs` to the interpolation methods (:issue:`10378`). +- Serialize metadata properties of subclasses of pandas objects (:issue:`10553`). +- ``Categorical.unique`` now returns new ``Categorical`` which ``categories`` and ``codes`` are unique, rather than returning ``np.array`` (:issue:`10508`) + + - unordered category: values and categories are sorted by appearance order. + - ordered category: values are sorted by appearance order, categories keeps existing order. + + .. ipython :: python + + cat = pd.Categorical(['C', 'A', 'B', 'C'], categories=['A', 'B', 'C'], ordered=True) + cat + cat.unique() + + cat = pd.Categorical(['C', 'A', 'B', 'C'], categories=['A', 'B', 'C']) + cat + cat.unique() + +- ``groupby`` using ``Categorical`` follows the same rule as ``Categorical.unique`` described above (:issue:`10508`) +- ``NaT``'s methods now either raise ``ValueError``, or return ``np.nan`` or ``NaT`` (:issue:`9513`) + + =============================== =============================================================== + Behavior Methods + =============================== =============================================================== + ``return np.nan`` ``weekday``, ``isoweekday`` + ``return NaT`` ``date``, ``now``, ``replace``, ``to_datetime``, ``today`` + ``return np.datetime64('NaT')`` ``to_datetime64`` (unchanged) + ``raise ValueError`` All other public methods (names not beginning with underscores) + =============================== =============================================================== + +- Improved error message when concatenating an empty iterable of dataframes (:issue:`9157`) + .. _whatsnew_0170.deprecations: Deprecations ^^^^^^^^^^^^ +.. note:: These indexing function have been deprecated in the documentation since 0.11.0. + +- For ``Series`` the following indexing functions are deprecated (:issue:`10177`). + + ===================== ================================= + Deprecated Function Replacement + ===================== ================================= + ``.irow(i)`` ``.iloc[i]`` or ``.iat[i]`` + ``.iget(i)`` ``.iloc[i]`` + ``.iget_value(i)`` ``.iloc[i]`` or ``.iat[i]`` + ===================== ================================= + +- For ``DataFrame`` the following indexing functions are deprecated (:issue:`10177`). + + ===================== ================================= + Deprecated Function Replacement + ===================== ================================= + ``.irow(i)`` ``.iloc[i]`` + ``.iget_value(i, j)`` ``.iloc[i, j]`` or ``.iat[i, j]`` + ``.icol(j)`` ``.iloc[:, j]`` + ===================== ================================= + +- ``Categorical.name`` was deprecated to make ``Categorical`` more ``numpy.ndarray`` like. Use ``Series(cat, name="whatever")`` instead (:issue:`10482`). +- ``drop_duplicates`` and ``duplicated``'s ``take_last`` keyword was deprecated in favor of ``keep``. (:issue:`6511`, :issue:`8505`) +- ``DataFrame.combineAdd`` and ``DataFrame.combineMult`` are deprecated. They + can easily be replaced by using the ``add`` and ``mul`` methods: + ``DataFrame.add(other, fill_value=0)`` and ``DataFrame.mul(other, fill_value=1.)`` + (:issue:`10735`). + .. _whatsnew_0170.prior_deprecations: Removal of prior version deprecations/changes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +- Remove use of some deprecated numpy comparison operations, mainly in tests. (:issue:`10569`) + + .. _whatsnew_0170.performance: Performance Improvements ~~~~~~~~~~~~~~~~~~~~~~~~ +- Added vbench benchmarks for alternative ExcelWriter engines and reading Excel files (:issue:`7171`) + +- 4x improvement in ``timedelta`` string parsing (:issue:`6755`, :issue:`10426`) +- 8x improvement in ``timedelta64`` and ``datetime64`` ops (:issue:`6755`) +- Significantly improved performance of indexing ``MultiIndex`` with slicers (:issue:`10287`) +- 8x improvement in ``iloc`` using list-like input (:issue:`10791`) +- Improved performance of ``Series.isin`` for datetimelike/integer Series (:issue:`10287`) +- 20x improvement in ``concat`` of Categoricals when categories are identical (:issue:`10587`) +- Improved performance of ``to_datetime`` when specified format string is ISO8601 (:issue:`10178`) +- 2x improvement of ``Series.value_counts`` for float dtype (:issue:`10821`) .. _whatsnew_0170.bug_fixes: Bug Fixes ~~~~~~~~~ +- Bug in ``DataFrame.to_html(index=False)`` renders unnecessary ``name`` row (:issue:`10344`) +- Bug in ``DataFrame.apply`` when function returns categorical series. (:issue:`9573`) +- Bug in ``to_datetime`` with invalid dates and formats supplied (:issue:`10154`) +- Bug in ``Index.drop_duplicates`` dropping name(s) (:issue:`10115`) +- Bug in ``pd.Series`` when setting a value on an empty ``Series`` whose index has a frequency. (:issue:`10193`) +- Bug in ``DataFrame.plot`` raises ``ValueError`` when color name is specified by multiple characters (:issue:`10387`) +- Bug in ``Index`` construction with a mixed list of tuples (:issue:`10697`) +- Bug in ``DataFrame.reset_index`` when index contains `NaT`. (:issue:`10388`) +- Bug in ``ExcelReader`` when worksheet is empty (:issue:`6403`) + + +- Bug causing ``DataFrame.where`` to not respect the ``axis`` parameter when the frame has a symmetric shape. (:issue:`9736`) + +- Bug in ``Table.select_column`` where name is not preserved (:issue:`10392`) +- Bug in ``offsets.generate_range`` where ``start`` and ``end`` have finer precision than ``offset`` (:issue:`9907`) +- Bug in ``pd.rolling_*`` where ``Series.name`` would be lost in the output (:issue:`10565`) +- Bug in ``stack`` when index or columns are not unique. (:issue:`10417`) +- Bug in setting a Panel when an axis has a multi-index (:issue:`10360`) +- Bug in ``USFederalHolidayCalendar`` where ``USMemorialDay`` and ``USMartinLutherKingJr`` were incorrect (:issue:`10278` and :issue:`9760` ) +- Bug in ``.sample()`` where returned object, if set, gives unnecessary ``SettingWithCopyWarning`` (:issue:`10738`) +- Bug in ``.sample()`` where weights passed as Series were not aligned along axis before being treated positionally, potentially causing problems if weight indices were not aligned with sampled object. (:issue:`10738`) + + + +- Bug in ``DataFrame.interpolate`` with ``axis=1`` and ``inplace=True`` (:issue:`10395`) +- Bug in ``io.sql.get_schema`` when specifying multiple columns as primary + key (:issue:`10385`). + +- Bug in ``groupby(sort=False)`` with datetime-like ``Categorical`` raises ``ValueError`` (:issue:`10505`) + +- Bug in ``test_categorical`` on big-endian builds (:issue:`10425`) +- Bug in ``Series.shift`` and ``DataFrame.shift`` not supporting categorical data (:issue:`9416`) +- Bug in ``Series.map`` using categorical ``Series`` raises ``AttributeError`` (:issue:`10324`) +- Bug in ``MultiIndex.get_level_values`` including ``Categorical`` raises ``AttributeError`` (:issue:`10460`) +- Bug in ``pd.get_dummies`` with `sparse=True` not returning ``SparseDataFrame`` (:issue:`10531`) +- Bug in ``Index`` subtypes (such as ``PeriodIndex``) not returning their own type for ``.drop`` and ``.insert`` methods (:issue:`10620`) +- Bug in ``algos.outer_join_indexer`` when ``right`` array is empty (:issue:`10618`) + +- Bug in ``filter`` (regression from 0.16.0) and ``transform`` when grouping on multiple keys, one of which is datetime-like (:issue:`10114`) + + + + + +- Bug that caused segfault when resampling an empty Series (:issue:`10228`) +- Bug in ``DatetimeIndex`` and ``PeriodIndex.value_counts`` resets name from its result, but retains in result's ``Index``. (:issue:`10150`) +- Bug in ``pd.eval`` using ``numexpr`` engine coerces 1 element numpy array to scalar (:issue:`10546`) +- Bug in ``pd.concat`` with ``axis=0`` when column is of dtype ``category`` (:issue:`10177`) +- Bug in ``read_msgpack`` where input type is not always checked (:issue:`10369`, :issue:`10630`) +- Bug in ``pd.read_csv`` with kwargs ``index_col=False``, ``index_col=['a', 'b']`` or ``dtype`` + (:issue:`10413`, :issue:`10467`, :issue:`10577`) +- Bug in ``Series.from_csv`` with ``header`` kwarg not setting the ``Series.name`` or the ``Series.index.name`` (:issue:`10483`) +- Bug in ``groupby.var`` which caused variance to be inaccurate for small float values (:issue:`10448`) +- Bug in ``Series.plot(kind='hist')`` Y Label not informative (:issue:`10485`) +- Bug in ``read_csv`` when using a converter which generates a ``uint8`` type (:issue:`9266`) + +- Bug causes memory leak in time-series line and area plot (:issue:`9003`) + + +- Bug in line and kde plot cannot accept multiple colors when ``subplots=True`` (:issue:`9894`) +- Bug in ``DataFrame.plot`` raises ``ValueError`` when color name is specified by multiple characters (:issue:`10387`) + +- Bug in left and right ``align`` of ``Series`` with ``MultiIndex`` may be inverted (:issue:`10665`) +- Bug in left and right ``join`` of with ``MultiIndex`` may be inverted (:issue:`10741`) + +- Bug in ``read_stata`` when reading a file with a different order set in ``columns`` (:issue:`10757`) +- Bug in ``Categorical`` may not representing properly when category contains ``tz`` or ``Period`` (:issue:`10713`) +- Bug in ``Categorical.__iter__`` may not returning correct ``datetime`` and ``Period`` (:issue:`10713`) + +- Bug in ``read_csv`` with ``engine='c'``: EOF preceded by a comment, blank line, etc. was not handled correctly (:issue:`10728`, :issue:`10548`) + +- Reading "famafrench" data via ``DataReader`` results in HTTP 404 error because of the website url is changed (:issue:`10591`). +- Bug in ``read_msgpack`` where DataFrame to decode has duplicate column names (:issue:`9618`) +- Bug in ``io.common.get_filepath_or_buffer`` which caused reading of valid S3 files to fail if the bucket also contained keys for which the user does not have read permission (:issue:`10604`) +- Bug in vectorised setting of timestamp columns with python ``datetime.date`` and numpy ``datetime64`` (:issue:`10408`, :issue:`10412`) +- Bug in ``Index.take`` may add unnecessary ``freq`` attribute (:issue:`10791`) +- Bug in ``merge`` with empty ``DataFrame`` may raise ``IndexError`` (:issue:`10824`) + + +- Bug in ``read_csv`` when using the ``nrows`` or ``chunksize`` parameters if file contains only a header line (:issue:`9535`) + +- Bug in ``pd.DataFrame`` when constructing an empty DataFrame with a string dtype (:issue:`9428`) +- Bug in ``pd.unique`` for arrays with the ``datetime64`` or ``timedelta64`` dtype that meant an array with object dtype was returned instead the original dtype (:issue: `9431`) +- Bug in ``DatetimeIndex.take`` and ``TimedeltaIndex.take`` may not raise ``IndexError`` against invalid index (:issue:`10295`) +- Bug in ``Series([np.nan]).astype('M8[ms]')``, which now returns ``Series([pd.NaT])`` (:issue:`10747`) +- Bug in ``PeriodIndex.order`` reset freq (:issue:`10295`) +- Bug in ``iloc`` allowing memory outside bounds of a Series to be accessed with negative integers (:issue:`10779`) +- Bug in ``read_msgpack`` where encoding is not respected (:issue:`10580`) +- Bug preventing access to the first index when using ``iloc`` with a list containing the appropriate negative integer (:issue:`10547`, :issue:`10779`) diff --git a/ez_setup.py b/ez_setup.py deleted file mode 100644 index 6f63b856f06c9..0000000000000 --- a/ez_setup.py +++ /dev/null @@ -1,264 +0,0 @@ -#!python -"""Bootstrap setuptools installation - -If you want to use setuptools in your package's setup.py, just include this -file in the same directory with it, and add this to the top of your setup.py:: - - from ez_setup import use_setuptools - use_setuptools() - -If you want to require a specific version of setuptools, set a download -mirror, or use an alternate download directory, you can do so by supplying -the appropriate options to ``use_setuptools()``. - -This file can also be run as a script to install or upgrade setuptools. -""" -from __future__ import print_function -import sys -DEFAULT_VERSION = "0.6c11" -DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[ - :3] - -md5_data = { - 'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca', - 'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb', - 'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b', - 'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a', - 'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618', - 'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac', - 'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5', - 'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4', - 'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c', - 'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b', - 'setuptools-0.6c10-py2.3.egg': 'ce1e2ab5d3a0256456d9fc13800a7090', - 'setuptools-0.6c10-py2.4.egg': '57d6d9d6e9b80772c59a53a8433a5dd4', - 'setuptools-0.6c10-py2.5.egg': 'de46ac8b1c97c895572e5e8596aeb8c7', - 'setuptools-0.6c10-py2.6.egg': '58ea40aef06da02ce641495523a0b7f5', - 'setuptools-0.6c11-py2.3.egg': '2baeac6e13d414a9d28e7ba5b5a596de', - 'setuptools-0.6c11-py2.4.egg': 'bd639f9b0eac4c42497034dec2ec0c2b', - 'setuptools-0.6c11-py2.5.egg': '64c94f3bf7a72a13ec83e0b24f2749b2', - 'setuptools-0.6c11-py2.6.egg': 'bfa92100bd772d5a213eedd356d64086', - 'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27', - 'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277', - 'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa', - 'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e', - 'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e', - 'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f', - 'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2', - 'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc', - 'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167', - 'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64', - 'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d', - 'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20', - 'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab', - 'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53', - 'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2', - 'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e', - 'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372', - 'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902', - 'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de', - 'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b', - 'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03', - 'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a', - 'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6', - 'setuptools-0.6c9-py2.6.egg': 'ca37b1ff16fa2ede6e19383e7b59245a', -} - -import sys -import os -try: - from hashlib import md5 -except ImportError: - from md5 import md5 - - -def _validate_md5(egg_name, data): - if egg_name in md5_data: - digest = md5(data).hexdigest() - if digest != md5_data[egg_name]: - print(( - "md5 validation of %s failed! (Possible download problem?)" - % egg_name - ), file=sys.stderr) - sys.exit(2) - return data - - -def use_setuptools( - version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, - download_delay=15 -): - """Automatically find/download setuptools and make it available on sys.path - - `version` should be a valid setuptools version number that is available - as an egg for download under the `download_base` URL (which should end with - a '/'). `to_dir` is the directory where setuptools will be downloaded, if - it is not already available. If `download_delay` is specified, it should - be the number of seconds that will be paused before initiating a download, - should one be required. If an older version of setuptools is installed, - this routine will print a message to ``sys.stderr`` and raise SystemExit in - an attempt to abort the calling script. - """ - was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules - - def do_download(): - egg = download_setuptools( - version, download_base, to_dir, download_delay) - sys.path.insert(0, egg) - import setuptools - setuptools.bootstrap_install_from = egg - try: - import pkg_resources - except ImportError: - return do_download() - try: - pkg_resources.require("setuptools>=" + version) - return - except pkg_resources.VersionConflict as e: - if was_imported: - print(( - "The required version of setuptools (>=%s) is not available, and\n" - "can't be installed while this script is running. Please install\n" - " a more recent version first, using 'easy_install -U setuptools'." - "\n\n(Currently using %r)" - ) % (version, e.args[0]), file=sys.stderr) - sys.exit(2) - else: - del pkg_resources, sys.modules['pkg_resources'] # reload ok - return do_download() - except pkg_resources.DistributionNotFound: - return do_download() - - -def download_setuptools( - version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, - delay=15 -): - """Download setuptools from a specified location and return its filename - - `version` should be a valid setuptools version number that is available - as an egg for download under the `download_base` URL (which should end - with a '/'). `to_dir` is the directory where the egg will be downloaded. - `delay` is the number of seconds to pause before an actual download attempt. - """ - import urllib2 - import shutil - egg_name = "setuptools-%s-py%s.egg" % (version, sys.version[:3]) - url = download_base + egg_name - saveto = os.path.join(to_dir, egg_name) - src = dst = None - if not os.path.exists(saveto): # Avoid repeated downloads - try: - from distutils import log - if delay: - log.warn(""" ---------------------------------------------------------------------------- -This script requires setuptools version %s to run (even to display -help). I will attempt to download it for you (from -%s), but -you may need to enable firewall access for this script first. -I will start the download in %d seconds. - -(Note: if this machine does not have network access, please obtain the file - - %s - -and place it in this directory before rerunning this script.) ----------------------------------------------------------------------------""", - version, download_base, delay, url - ) - from time import sleep - sleep(delay) - log.warn("Downloading %s", url) - src = urllib2.urlopen(url) - # Read/write all in one block, so we don't create a corrupt file - # if the download is interrupted. - data = _validate_md5(egg_name, src.read()) - dst = open(saveto, "wb") - dst.write(data) - finally: - if src: - src.close() - if dst: - dst.close() - return os.path.realpath(saveto) - - -def main(argv, version=DEFAULT_VERSION): - """Install or upgrade setuptools and EasyInstall""" - try: - import setuptools - except ImportError: - egg = None - try: - egg = download_setuptools(version, delay=0) - sys.path.insert(0, egg) - from setuptools.command.easy_install import main - return main(list(argv) + [egg]) # we're done here - finally: - if egg and os.path.exists(egg): - os.unlink(egg) - else: - if setuptools.__version__ == '0.0.1': - print(( - "You have an obsolete version of setuptools installed. Please\n" - "remove it from your system entirely before rerunning this script." - ), file=sys.stderr) - sys.exit(2) - - req = "setuptools>=" + version - import pkg_resources - try: - pkg_resources.require(req) - except pkg_resources.VersionConflict: - try: - from setuptools.command.easy_install import main - except ImportError: - from easy_install import main - main(list(argv) + [download_setuptools(delay=0)]) - sys.exit(0) # try to force an exit - else: - if argv: - from setuptools.command.easy_install import main - main(argv) - else: - print("Setuptools version", version, "or greater has been installed.") - print('(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)') - - -def update_md5(filenames): - """Update our built-in md5 registry""" - - import re - - for name in filenames: - base = os.path.basename(name) - f = open(name, 'rb') - md5_data[base] = md5(f.read()).hexdigest() - f.close() - - data = sorted([" %r: %r,\n" % it for it in md5_data.items()]) - repl = "".join(data) - - import inspect - srcfile = inspect.getsourcefile(sys.modules[__name__]) - f = open(srcfile, 'rb') - src = f.read() - f.close() - - match = re.search("\nmd5_data = {\n([^}]+)}", src) - if not match: - print("Internal error!", file=sys.stderr) - sys.exit(2) - - src = src[:match.start(1)] + repl + src[match.end(1):] - f = open(srcfile, 'w') - f.write(src) - f.close() - - -if __name__ == '__main__': - if len(sys.argv) > 2 and sys.argv[1] == '--md5update': - update_md5(sys.argv[2:]) - else: - main(sys.argv[1:]) diff --git a/fake_pyrex/Pyrex/Distutils/__init__.py b/fake_pyrex/Pyrex/Distutils/__init__.py deleted file mode 100644 index 51c8e16b8e546..0000000000000 --- a/fake_pyrex/Pyrex/Distutils/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# work around broken setuptools monkey patching diff --git a/fake_pyrex/Pyrex/Distutils/build_ext.py b/fake_pyrex/Pyrex/Distutils/build_ext.py deleted file mode 100644 index 4f846f6282cbb..0000000000000 --- a/fake_pyrex/Pyrex/Distutils/build_ext.py +++ /dev/null @@ -1 +0,0 @@ -build_ext = "yes, it's there!" diff --git a/fake_pyrex/Pyrex/__init__.py b/fake_pyrex/Pyrex/__init__.py deleted file mode 100644 index 51c8e16b8e546..0000000000000 --- a/fake_pyrex/Pyrex/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# work around broken setuptools monkey patching diff --git a/pandas/__init__.py b/pandas/__init__.py index 0e7bc628fdb6a..dbc697410da80 100644 --- a/pandas/__init__.py +++ b/pandas/__init__.py @@ -29,7 +29,6 @@ _np_version_under1p9 = LooseVersion(_np_version) < '1.9' -from pandas.version import version as __version__ from pandas.info import __doc__ @@ -57,3 +56,8 @@ from pandas.util.print_versions import show_versions import pandas.util.testing +# use the closest tagged version if possible +from ._version import get_versions +v = get_versions() +__version__ = v.get('closest-tag',v['version']) +del get_versions, v diff --git a/pandas/_version.py b/pandas/_version.py new file mode 100644 index 0000000000000..61e9f3ff187ea --- /dev/null +++ b/pandas/_version.py @@ -0,0 +1,460 @@ + +# This file helps to compute a version number in source trees obtained from +# git-archive tarball (such as those provided by githubs download-from-tag +# feature). Distribution tarballs (built by setup.py sdist) and build +# directories (produced by setup.py build) will contain a much shorter file +# that just contains the computed version number. + +# This file is released into the public domain. Generated by +# versioneer-0.15 (https://github.com/warner/python-versioneer) + +import errno +import os +import re +import subprocess +import sys + + +def get_keywords(): + # these strings will be replaced by git during git-archive. + # setup.py/versioneer.py will grep for the variable names, so they must + # each be defined on a line of their own. _version.py will just call + # get_keywords(). + git_refnames = "$Format:%d$" + git_full = "$Format:%H$" + keywords = {"refnames": git_refnames, "full": git_full} + return keywords + + +class VersioneerConfig: + pass + + +def get_config(): + # these strings are filled in when 'setup.py versioneer' creates + # _version.py + cfg = VersioneerConfig() + cfg.VCS = "git" + cfg.style = "pep440" + cfg.tag_prefix = "v" + cfg.parentdir_prefix = "pandas-" + cfg.versionfile_source = "pandas/_version.py" + cfg.verbose = False + return cfg + + +class NotThisMethod(Exception): + pass + + +LONG_VERSION_PY = {} +HANDLERS = {} + + +def register_vcs_handler(vcs, method): # decorator + def decorate(f): + if vcs not in HANDLERS: + HANDLERS[vcs] = {} + HANDLERS[vcs][method] = f + return f + return decorate + + +def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False): + assert isinstance(commands, list) + p = None + for c in commands: + try: + dispcmd = str([c] + args) + # remember shell=False, so use git.cmd on windows, not just git + p = subprocess.Popen([c] + args, cwd=cwd, stdout=subprocess.PIPE, + stderr=(subprocess.PIPE if hide_stderr + else None)) + break + except EnvironmentError: + e = sys.exc_info()[1] + if e.errno == errno.ENOENT: + continue + if verbose: + print("unable to run %s" % dispcmd) + print(e) + return None + else: + if verbose: + print("unable to find command, tried %s" % (commands,)) + return None + stdout = p.communicate()[0].strip() + if sys.version_info[0] >= 3: + stdout = stdout.decode() + if p.returncode != 0: + if verbose: + print("unable to run %s (error)" % dispcmd) + return None + return stdout + + +def versions_from_parentdir(parentdir_prefix, root, verbose): + # Source tarballs conventionally unpack into a directory that includes + # both the project name and a version string. + dirname = os.path.basename(root) + if not dirname.startswith(parentdir_prefix): + if verbose: + print("guessing rootdir is '%s', but '%s' doesn't start with " + "prefix '%s'" % (root, dirname, parentdir_prefix)) + raise NotThisMethod("rootdir doesn't start with parentdir_prefix") + return {"version": dirname[len(parentdir_prefix):], + "full-revisionid": None, + "dirty": False, "error": None} + + +@register_vcs_handler("git", "get_keywords") +def git_get_keywords(versionfile_abs): + # the code embedded in _version.py can just fetch the value of these + # keywords. When used from setup.py, we don't want to import _version.py, + # so we do it with a regexp instead. This function is not used from + # _version.py. + keywords = {} + try: + f = open(versionfile_abs, "r") + for line in f.readlines(): + if line.strip().startswith("git_refnames ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["refnames"] = mo.group(1) + if line.strip().startswith("git_full ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["full"] = mo.group(1) + f.close() + except EnvironmentError: + pass + return keywords + + +@register_vcs_handler("git", "keywords") +def git_versions_from_keywords(keywords, tag_prefix, verbose): + if not keywords: + raise NotThisMethod("no keywords at all, weird") + refnames = keywords["refnames"].strip() + if refnames.startswith("$Format"): + if verbose: + print("keywords are unexpanded, not using") + raise NotThisMethod("unexpanded keywords, not a git-archive tarball") + refs = set([r.strip() for r in refnames.strip("()").split(",")]) + # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of + # just "foo-1.0". If we see a "tag: " prefix, prefer those. + TAG = "tag: " + tags = set([r[len(TAG):] for r in refs if r.startswith(TAG)]) + if not tags: + # Either we're using git < 1.8.3, or there really are no tags. We use + # a heuristic: assume all version tags have a digit. The old git %d + # expansion behaves like git log --decorate=short and strips out the + # refs/heads/ and refs/tags/ prefixes that would let us distinguish + # between branches and tags. By ignoring refnames without digits, we + # filter out many common branch names like "release" and + # "stabilization", as well as "HEAD" and "master". + tags = set([r for r in refs if re.search(r'\d', r)]) + if verbose: + print("discarding '%s', no digits" % ",".join(refs-tags)) + if verbose: + print("likely tags: %s" % ",".join(sorted(tags))) + for ref in sorted(tags): + # sorting will prefer e.g. "2.0" over "2.0rc1" + if ref.startswith(tag_prefix): + r = ref[len(tag_prefix):] + if verbose: + print("picking %s" % r) + return {"version": r, + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": None + } + # no suitable tags, so version is "0+unknown", but full hex is still there + if verbose: + print("no suitable tags, using unknown + full revision id") + return {"version": "0+unknown", + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": "no suitable tags"} + + +@register_vcs_handler("git", "pieces_from_vcs") +def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): + # this runs 'git' from the root of the source tree. This only gets called + # if the git-archive 'subst' keywords were *not* expanded, and + # _version.py hasn't already been rewritten with a short version string, + # meaning we're inside a checked out source tree. + + if not os.path.exists(os.path.join(root, ".git")): + if verbose: + print("no .git in %s" % root) + raise NotThisMethod("no .git directory") + + GITS = ["git"] + if sys.platform == "win32": + GITS = ["git.cmd", "git.exe"] + # if there is a tag, this yields TAG-NUM-gHEX[-dirty] + # if there are no tags, this yields HEX[-dirty] (no NUM) + describe_out = run_command(GITS, ["describe", "--tags", "--dirty", + "--always", "--long"], + cwd=root) + # --long was added in git-1.5.5 + if describe_out is None: + raise NotThisMethod("'git describe' failed") + describe_out = describe_out.strip() + full_out = run_command(GITS, ["rev-parse", "HEAD"], cwd=root) + if full_out is None: + raise NotThisMethod("'git rev-parse' failed") + full_out = full_out.strip() + + pieces = {} + pieces["long"] = full_out + pieces["short"] = full_out[:7] # maybe improved later + pieces["error"] = None + + # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] + # TAG might have hyphens. + git_describe = describe_out + + # look for -dirty suffix + dirty = git_describe.endswith("-dirty") + pieces["dirty"] = dirty + if dirty: + git_describe = git_describe[:git_describe.rindex("-dirty")] + + # now we have TAG-NUM-gHEX or HEX + + if "-" in git_describe: + # TAG-NUM-gHEX + mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) + if not mo: + # unparseable. Maybe git-describe is misbehaving? + pieces["error"] = ("unable to parse git-describe output: '%s'" + % describe_out) + return pieces + + # tag + full_tag = mo.group(1) + if not full_tag.startswith(tag_prefix): + if verbose: + fmt = "tag '%s' doesn't start with prefix '%s'" + print(fmt % (full_tag, tag_prefix)) + pieces["error"] = ("tag '%s' doesn't start with prefix '%s'" + % (full_tag, tag_prefix)) + return pieces + pieces["closest-tag"] = full_tag[len(tag_prefix):] + + # distance: number of commits since tag + pieces["distance"] = int(mo.group(2)) + + # commit: short hex revision ID + pieces["short"] = mo.group(3) + + else: + # HEX: no tags + pieces["closest-tag"] = None + count_out = run_command(GITS, ["rev-list", "HEAD", "--count"], + cwd=root) + pieces["distance"] = int(count_out) # total number of commits + + return pieces + + +def plus_or_dot(pieces): + if "+" in pieces.get("closest-tag", ""): + return "." + return "+" + + +def render_pep440(pieces): + # now build up version string, with post-release "local version + # identifier". Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you + # get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty + + # exceptions: + # 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] + + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += plus_or_dot(pieces) + rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0+untagged.%d.g%s" % (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_pre(pieces): + # TAG[.post.devDISTANCE] . No -dirty + + # exceptions: + # 1: no tags. 0.post.devDISTANCE + + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"]: + rendered += ".post.dev%d" % pieces["distance"] + else: + # exception #1 + rendered = "0.post.dev%d" % pieces["distance"] + return rendered + + +def render_pep440_post(pieces): + # TAG[.postDISTANCE[.dev0]+gHEX] . The ".dev0" means dirty. Note that + # .dev0 sorts backwards (a dirty tree will appear "older" than the + # corresponding clean one), but you shouldn't be releasing software with + # -dirty anyways. + + # exceptions: + # 1: no tags. 0.postDISTANCE[.dev0] + + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%s" % pieces["short"] + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += "+g%s" % pieces["short"] + return rendered + + +def render_pep440_old(pieces): + # TAG[.postDISTANCE[.dev0]] . The ".dev0" means dirty. + + # exceptions: + # 1: no tags. 0.postDISTANCE[.dev0] + + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + return rendered + + +def render_git_describe(pieces): + # TAG[-DISTANCE-gHEX][-dirty], like 'git describe --tags --dirty + # --always' + + # exceptions: + # 1: no tags. HEX[-dirty] (note: no 'g' prefix) + + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"]: + rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render_git_describe_long(pieces): + # TAG-DISTANCE-gHEX[-dirty], like 'git describe --tags --dirty + # --always -long'. The distance/hash is unconditional. + + # exceptions: + # 1: no tags. HEX[-dirty] (note: no 'g' prefix) + + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render(pieces, style): + if pieces["error"]: + return {"version": "unknown", + "full-revisionid": pieces.get("long"), + "dirty": None, + "error": pieces["error"]} + + if not style or style == "default": + style = "pep440" # the default + + if style == "pep440": + rendered = render_pep440(pieces) + elif style == "pep440-pre": + rendered = render_pep440_pre(pieces) + elif style == "pep440-post": + rendered = render_pep440_post(pieces) + elif style == "pep440-old": + rendered = render_pep440_old(pieces) + elif style == "git-describe": + rendered = render_git_describe(pieces) + elif style == "git-describe-long": + rendered = render_git_describe_long(pieces) + else: + raise ValueError("unknown style '%s'" % style) + + return {"version": rendered, "full-revisionid": pieces["long"], + "dirty": pieces["dirty"], "error": None} + + +def get_versions(): + # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have + # __file__, we can work backwards from there to the root. Some + # py2exe/bbfreeze/non-CPython implementations don't do __file__, in which + # case we can only use expanded keywords. + + cfg = get_config() + verbose = cfg.verbose + + try: + return git_versions_from_keywords(get_keywords(), cfg.tag_prefix, + verbose) + except NotThisMethod: + pass + + try: + root = os.path.realpath(__file__) + # versionfile_source is the relative path from the top of the source + # tree (where the .git directory might live) to this file. Invert + # this to find the root from __file__. + for i in cfg.versionfile_source.split('/'): + root = os.path.dirname(root) + except NameError: + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, + "error": "unable to find root of source tree"} + + try: + pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose) + return render(pieces, cfg.style) + except NotThisMethod: + pass + + try: + if cfg.parentdir_prefix: + return versions_from_parentdir(cfg.parentdir_prefix, root, verbose) + except NotThisMethod: + pass + + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, + "error": "unable to compute version"} diff --git a/pandas/algos.pyx b/pandas/algos.pyx index 5f68c1ee26e87..9b6bdf57d4509 100644 --- a/pandas/algos.pyx +++ b/pandas/algos.pyx @@ -2157,6 +2157,8 @@ def group_nth_bin_object(ndarray[object, ndim=2] out, nobs = np.zeros(( out).shape, dtype=np.float64) resx = np.empty(( out).shape, dtype=object) + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: @@ -2247,6 +2249,8 @@ def group_last_bin_object(ndarray[object, ndim=2] out, nobs = np.zeros(( out).shape, dtype=np.float64) resx = np.empty(( out).shape, dtype=object) + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: diff --git a/pandas/compat/__init__.py b/pandas/compat/__init__.py index 2a273629544cb..2ac81f15a6d6c 100644 --- a/pandas/compat/__init__.py +++ b/pandas/compat/__init__.py @@ -14,7 +14,7 @@ * Uses the original method if available, otherwise uses items, keys, values. * types: * text_type: unicode in Python 2, str in Python 3 - * binary_type: str in Python 2, bythes in Python 3 + * binary_type: str in Python 2, bytes in Python 3 * string_types: basestring in Python 2, str in Python 3 * bind_method: binds functions to classes * add_metaclass(metaclass) - class decorator that recreates class with with the @@ -37,7 +37,6 @@ import types PY3 = (sys.version_info[0] >= 3) -PY3_2 = sys.version_info[:2] == (3, 2) PY2 = sys.version_info[0] == 2 diff --git a/pandas/computation/align.py b/pandas/computation/align.py index 2e0845bddf7e2..9834dd1a9e7fc 100644 --- a/pandas/computation/align.py +++ b/pandas/computation/align.py @@ -172,12 +172,11 @@ def _reconstruct_object(typ, obj, axes, dtype): ret_value = res_t.type(obj) else: ret_value = typ(obj).astype(res_t) - - try: - ret = ret_value.item() - except (ValueError, IndexError): - # XXX: we catch IndexError to absorb a - # regression in numpy 1.7.0 - # fixed by numpy/numpy@04b89c63 - ret = ret_value - return ret + # The condition is to distinguish 0-dim array (returned in case of scalar) + # and 1 element array + # e.g. np.array(0) and np.array([0]) + if len(obj.shape) == 1 and len(obj) == 1: + if not isinstance(ret_value, np.ndarray): + ret_value = np.array([ret_value]).astype(res_t) + + return ret_value diff --git a/pandas/computation/tests/test_eval.py b/pandas/computation/tests/test_eval.py index 8f82e2eaea711..4f998319d922d 100644 --- a/pandas/computation/tests/test_eval.py +++ b/pandas/computation/tests/test_eval.py @@ -10,7 +10,7 @@ from numpy.random import randn, rand, randint import numpy as np -from numpy.testing import assert_array_equal, assert_allclose +from numpy.testing import assert_allclose from numpy.testing.decorators import slow import pandas as pd @@ -163,9 +163,7 @@ def test_floor_division(self): self.check_floor_division(lhs, '//', rhs) def test_pow(self): - import platform - if platform.system() == 'Windows': - raise nose.SkipTest('not testing pow on Windows') + tm._skip_if_windows() # odd failure on win32 platform, so skip for lhs, rhs in product(self.lhses, self.rhses): @@ -222,7 +220,7 @@ def check_complex_cmp_op(self, lhs, cmp1, rhs, binop, cmp2): expected = _eval_single_bin( lhs_new, binop, rhs_new, self.engine) result = pd.eval(ex, engine=self.engine, parser=self.parser) - assert_array_equal(result, expected) + tm.assert_numpy_array_equal(result, expected) def check_chained_cmp_op(self, lhs, cmp1, mid, cmp2, rhs): skip_these = _scalar_skip @@ -242,7 +240,7 @@ def check_operands(left, right, cmp_op): for ex in (ex1, ex2, ex3): result = pd.eval(ex, engine=self.engine, parser=self.parser) - assert_array_equal(result, expected) + tm.assert_numpy_array_equal(result, expected) def check_simple_cmp_op(self, lhs, cmp1, rhs): ex = 'lhs {0} rhs'.format(cmp1) @@ -253,13 +251,13 @@ def check_simple_cmp_op(self, lhs, cmp1, rhs): else: expected = _eval_single_bin(lhs, cmp1, rhs, self.engine) result = pd.eval(ex, engine=self.engine, parser=self.parser) - assert_array_equal(result, expected) + tm.assert_numpy_array_equal(result, expected) def check_binary_arith_op(self, lhs, arith1, rhs): ex = 'lhs {0} rhs'.format(arith1) result = pd.eval(ex, engine=self.engine, parser=self.parser) expected = _eval_single_bin(lhs, arith1, rhs, self.engine) - assert_array_equal(result, expected) + tm.assert_numpy_array_equal(result, expected) ex = 'lhs {0} rhs {0} rhs'.format(arith1) result = pd.eval(ex, engine=self.engine, parser=self.parser) nlhs = _eval_single_bin(lhs, arith1, rhs, @@ -275,7 +273,7 @@ def check_alignment(self, result, nlhs, ghs, op): pass else: expected = self.ne.evaluate('nlhs {0} ghs'.format(op)) - assert_array_equal(result, expected) + tm.assert_numpy_array_equal(result, expected) # modulus, pow, and floor division require special casing @@ -293,7 +291,7 @@ def check_floor_division(self, lhs, arith1, rhs): if self.engine == 'python': res = pd.eval(ex, engine=self.engine, parser=self.parser) expected = lhs // rhs - assert_array_equal(res, expected) + tm.assert_numpy_array_equal(res, expected) else: self.assertRaises(TypeError, pd.eval, ex, local_dict={'lhs': lhs, 'rhs': rhs}, @@ -327,8 +325,8 @@ def check_pow(self, lhs, arith1, rhs): if (np.isscalar(lhs) and np.isscalar(rhs) and _is_py3_complex_incompat(result, expected)): - self.assertRaises(AssertionError, assert_array_equal, result, - expected) + self.assertRaises(AssertionError, tm.assert_numpy_array_equal, + result, expected) else: assert_allclose(result, expected) @@ -347,12 +345,12 @@ def check_single_invert_op(self, lhs, cmp1, rhs): elb = np.array([bool(el)]) expected = ~elb result = pd.eval('~elb', engine=self.engine, parser=self.parser) - assert_array_equal(expected, result) + tm.assert_numpy_array_equal(expected, result) for engine in self.current_engines: tm.skip_if_no_ne(engine) - assert_array_equal(result, pd.eval('~elb', engine=engine, - parser=self.parser)) + tm.assert_numpy_array_equal(result, pd.eval('~elb', engine=engine, + parser=self.parser)) def check_compound_invert_op(self, lhs, cmp1, rhs): skip_these = 'in', 'not in' @@ -372,13 +370,13 @@ def check_compound_invert_op(self, lhs, cmp1, rhs): else: expected = ~expected result = pd.eval(ex, engine=self.engine, parser=self.parser) - assert_array_equal(expected, result) + tm.assert_numpy_array_equal(expected, result) # make sure the other engines work the same as this one for engine in self.current_engines: tm.skip_if_no_ne(engine) ev = pd.eval(ex, engine=self.engine, parser=self.parser) - assert_array_equal(ev, result) + tm.assert_numpy_array_equal(ev, result) def ex(self, op, var_name='lhs'): return '{0}{1}'.format(op, var_name) @@ -622,6 +620,38 @@ def test_disallow_scalar_bool_ops(self): with tm.assertRaises(NotImplementedError): pd.eval(ex, engine=self.engine, parser=self.parser) + def test_identical(self): + # GH 10546 + x = 1 + result = pd.eval('x', engine=self.engine, parser=self.parser) + self.assertEqual(result, 1) + self.assertTrue(np.isscalar(result)) + + x = 1.5 + result = pd.eval('x', engine=self.engine, parser=self.parser) + self.assertEqual(result, 1.5) + self.assertTrue(np.isscalar(result)) + + x = False + result = pd.eval('x', engine=self.engine, parser=self.parser) + self.assertEqual(result, False) + self.assertTrue(np.isscalar(result)) + + x = np.array([1]) + result = pd.eval('x', engine=self.engine, parser=self.parser) + tm.assert_numpy_array_equal(result, np.array([1])) + self.assertEqual(result.shape, (1, )) + + x = np.array([1.5]) + result = pd.eval('x', engine=self.engine, parser=self.parser) + tm.assert_numpy_array_equal(result, np.array([1.5])) + self.assertEqual(result.shape, (1, )) + + x = np.array([False]) + result = pd.eval('x', engine=self.engine, parser=self.parser) + tm.assert_numpy_array_equal(result, np.array([False])) + self.assertEqual(result.shape, (1, )) + class TestEvalNumexprPython(TestEvalNumexprPandas): @@ -677,7 +707,7 @@ def check_alignment(self, result, nlhs, ghs, op): pass else: expected = eval('nlhs {0} ghs'.format(op)) - assert_array_equal(result, expected) + tm.assert_numpy_array_equal(result, expected) class TestEvalPythonPandas(TestEvalPythonPython): @@ -1088,10 +1118,10 @@ def test_truediv(self): if PY3: res = self.eval(ex, truediv=False) - assert_array_equal(res, np.array([1.0])) + tm.assert_numpy_array_equal(res, np.array([1.0])) res = self.eval(ex, truediv=True) - assert_array_equal(res, np.array([1.0])) + tm.assert_numpy_array_equal(res, np.array([1.0])) res = self.eval('1 / 2', truediv=True) expec = 0.5 @@ -1110,10 +1140,10 @@ def test_truediv(self): self.assertEqual(res, expec) else: res = self.eval(ex, truediv=False) - assert_array_equal(res, np.array([1])) + tm.assert_numpy_array_equal(res, np.array([1])) res = self.eval(ex, truediv=True) - assert_array_equal(res, np.array([1.0])) + tm.assert_numpy_array_equal(res, np.array([1.0])) res = self.eval('1 / 2', truediv=True) expec = 0.5 @@ -1416,8 +1446,8 @@ class TestScope(object): def check_global_scope(self, e, engine, parser): tm.skip_if_no_ne(engine) - assert_array_equal(_var_s * 2, pd.eval(e, engine=engine, - parser=parser)) + tm.assert_numpy_array_equal(_var_s * 2, pd.eval(e, engine=engine, + parser=parser)) def test_global_scope(self): e = '_var_s * 2' diff --git a/pandas/core/algorithms.py b/pandas/core/algorithms.py index c97d459fb96df..0b11a2bae3973 100644 --- a/pandas/core/algorithms.py +++ b/pandas/core/algorithms.py @@ -36,7 +36,7 @@ def match(to_match, values, na_sentinel=-1): values = np.array(values, dtype='O') f = lambda htype, caster: _match_generic(to_match, values, htype, caster) - result = _hashtable_algo(f, values.dtype) + result = _hashtable_algo(f, values.dtype, np.int64) if na_sentinel != -1: @@ -66,7 +66,7 @@ def unique(values): return _hashtable_algo(f, values.dtype) -def _hashtable_algo(f, dtype): +def _hashtable_algo(f, dtype, return_dtype=None): """ f(HashTable, type_caster) -> result """ @@ -74,6 +74,12 @@ def _hashtable_algo(f, dtype): return f(htable.Float64HashTable, com._ensure_float64) elif com.is_integer_dtype(dtype): return f(htable.Int64HashTable, com._ensure_int64) + elif com.is_datetime64_dtype(dtype): + return_dtype = return_dtype or 'M8[ns]' + return f(htable.Int64HashTable, com._ensure_int64).view(return_dtype) + elif com.is_timedelta64_dtype(dtype): + return_dtype = return_dtype or 'm8[ns]' + return f(htable.Int64HashTable, com._ensure_int64).view(return_dtype) else: return f(htable.PyObjectHashTable, com._ensure_object) @@ -202,6 +208,7 @@ def value_counts(values, sort=True, ascending=False, normalize=False, from pandas.tools.tile import cut from pandas.tseries.period import PeriodIndex + name = getattr(values, 'name', None) values = Series(values).values if bins is not None: @@ -222,10 +229,10 @@ def value_counts(values, sort=True, ascending=False, normalize=False, if com.is_datetime_or_timedelta_dtype(dtype) or is_period: if is_period: - values = PeriodIndex(values) + values = PeriodIndex(values, name=name) values = values.view(np.int64) - keys, counts = htable.value_count_int64(values) + keys, counts = htable.value_count_scalar64(values, dropna) if dropna: from pandas.tslib import iNaT @@ -237,7 +244,10 @@ def value_counts(values, sort=True, ascending=False, normalize=False, elif com.is_integer_dtype(dtype): values = com._ensure_int64(values) - keys, counts = htable.value_count_int64(values) + keys, counts = htable.value_count_scalar64(values, dropna) + elif com.is_float_dtype(dtype): + values = com._ensure_float64(values) + keys, counts = htable.value_count_scalar64(values, dropna) else: values = com._ensure_object(values) @@ -247,7 +257,7 @@ def value_counts(values, sort=True, ascending=False, normalize=False, keys = np.insert(keys, 0, np.NaN) counts = np.insert(counts, 0, mask.sum()) - result = Series(counts, index=com._values_from_object(keys)) + result = Series(counts, index=com._values_from_object(keys), name=name) if bins is not None: # TODO: This next line should be more efficient diff --git a/pandas/core/base.py b/pandas/core/base.py index 540b900844a9e..6d1c89a7a2f89 100644 --- a/pandas/core/base.py +++ b/pandas/core/base.py @@ -6,7 +6,7 @@ from pandas.core import common as com import pandas.core.nanops as nanops import pandas.lib as lib -from pandas.util.decorators import Appender, cache_readonly +from pandas.util.decorators import Appender, cache_readonly, deprecate_kwarg from pandas.core.strings import StringMethods from pandas.core.common import AbstractMethodError @@ -431,10 +431,10 @@ def value_counts(self, normalize=False, sort=True, ascending=False, if isinstance(self, PeriodIndex): # preserve freq - result.index = self._simple_new(result.index.values, self.name, + result.index = self._simple_new(result.index.values, freq=self.freq) elif isinstance(self, DatetimeIndex): - result.index = self._simple_new(result.index.values, self.name, + result.index = self._simple_new(result.index.values, tz=getattr(self, 'tz', None)) return result @@ -543,8 +543,12 @@ def _dir_deletions(self): Parameters ---------- - take_last : boolean, default False - Take the last observed index in a group. Default first + + keep : {'first', 'last', False}, default 'first' + - ``first`` : Drop duplicates except for the first occurrence. + - ``last`` : Drop duplicates except for the last occurrence. + - False : Drop all duplicates. + take_last : deprecated %(inplace)s Returns @@ -552,9 +556,10 @@ def _dir_deletions(self): deduplicated : %(klass)s """) + @deprecate_kwarg('take_last', 'keep', mapping={True: 'last', False: 'first'}) @Appender(_shared_docs['drop_duplicates'] % _indexops_doc_kwargs) - def drop_duplicates(self, take_last=False, inplace=False): - duplicated = self.duplicated(take_last=take_last) + def drop_duplicates(self, keep='first', inplace=False): + duplicated = self.duplicated(keep=keep) result = self[np.logical_not(duplicated)] if inplace: return self._update_inplace(result) @@ -566,18 +571,22 @@ def drop_duplicates(self, take_last=False, inplace=False): Parameters ---------- - take_last : boolean, default False - Take the last observed index in a group. Default first + keep : {'first', 'last', False}, default 'first' + - ``first`` : Mark duplicates as ``True`` except for the first occurrence. + - ``last`` : Mark duplicates as ``True`` except for the last occurrence. + - False : Mark all duplicates as ``True``. + take_last : deprecated Returns ------- duplicated : %(duplicated)s """) + @deprecate_kwarg('take_last', 'keep', mapping={True: 'last', False: 'first'}) @Appender(_shared_docs['duplicated'] % _indexops_doc_kwargs) - def duplicated(self, take_last=False): + def duplicated(self, keep='first'): keys = com._ensure_object(self.values) - duplicated = lib.duplicated(keys, take_last=take_last) + duplicated = lib.duplicated(keys, keep=keep) try: return self._constructor(duplicated, index=self.index).__finalize__(self) diff --git a/pandas/core/categorical.py b/pandas/core/categorical.py index a9e5d1f3f0ebd..af3d13e1ec4a9 100644 --- a/pandas/core/categorical.py +++ b/pandas/core/categorical.py @@ -12,7 +12,7 @@ import pandas.core.common as com from pandas.util.decorators import cache_readonly, deprecate_kwarg -from pandas.core.common import (CategoricalDtype, ABCSeries, ABCIndexClass, ABCPeriodIndex, ABCCategoricalIndex, +from pandas.core.common import (CategoricalDtype, ABCSeries, ABCIndexClass, ABCCategoricalIndex, isnull, notnull, is_dtype_equal, is_categorical_dtype, is_integer_dtype, is_object_dtype, _possibly_infer_to_datetimelike, get_dtype_kinds, @@ -147,9 +147,6 @@ class Categorical(PandasObject): ordered : boolean, (default False) Whether or not this categorical is treated as a ordered categorical. If not given, the resulting categorical will not be ordered. - name : str, optional - Name for the Categorical variable. If name is None, will attempt - to infer from values. Attributes ---------- @@ -159,8 +156,6 @@ class Categorical(PandasObject): The codes (integer positions, which point to the categories) of this categorical, read only. ordered : boolean Whether or not this Categorical is ordered. - name : string - The name of this Categorical. Raises ------ @@ -182,7 +177,7 @@ class Categorical(PandasObject): [a, b, c, a, b, c] Categories (3, object): [a < b < c] - >>> a = Categorical(['a','b','c','a','b','c'], ['c', 'b', 'a']) + >>> a = Categorical(['a','b','c','a','b','c'], ['c', 'b', 'a'], ordered=True) >>> a.min() 'c' """ @@ -205,7 +200,6 @@ class Categorical(PandasObject): # For comparisons, so that numpy uses our implementation if the compare ops, which raise __array_priority__ = 1000 _typ = 'categorical' - name = None def __init__(self, values, categories=None, ordered=False, name=None, fastpath=False, levels=None): @@ -213,23 +207,24 @@ def __init__(self, values, categories=None, ordered=False, name=None, fastpath=F if fastpath: # fast path self._codes = _coerce_indexer_dtype(values, categories) - self.name = name self.categories = categories self._ordered = ordered return - if name is None: - name = getattr(values, 'name', None) + if not name is None: + msg = "the 'name' keyword is removed, use 'name' with consumers of the " \ + "categorical instead (e.g. 'Series(cat, name=\"something\")'" + warn(msg, UserWarning, stacklevel=2) # TODO: Remove after deprecation period in 2017/ after 0.18 if not levels is None: warn("Creating a 'Categorical' with 'levels' is deprecated, use 'categories' instead", - FutureWarning) + FutureWarning, stacklevel=2) if categories is None: categories = levels else: raise ValueError("Cannot pass in both 'categories' and (deprecated) 'levels', " - "use only 'categories'") + "use only 'categories'", stacklevel=2) # sanitize input if is_categorical_dtype(values): @@ -293,21 +288,20 @@ def __init__(self, values, categories=None, ordered=False, name=None, fastpath=F # TODO: check for old style usage. These warnings should be removes after 0.18/ in 2016 if is_integer_dtype(values) and not is_integer_dtype(categories): warn("Values and categories have different dtypes. Did you mean to use\n" - "'Categorical.from_codes(codes, categories)'?", RuntimeWarning) + "'Categorical.from_codes(codes, categories)'?", RuntimeWarning, stacklevel=2) if len(values) and is_integer_dtype(values) and (codes == -1).all(): warn("None of the categories were found in values. Did you mean to use\n" - "'Categorical.from_codes(codes, categories)'?", RuntimeWarning) + "'Categorical.from_codes(codes, categories)'?", RuntimeWarning, stacklevel=2) self.set_ordered(ordered or False, inplace=True) self.categories = categories - self.name = name self._codes = _coerce_indexer_dtype(codes, categories) def copy(self): """ Copy constructor. """ return Categorical(values=self._codes.copy(),categories=self.categories, - name=self.name, ordered=self.ordered, fastpath=True) + ordered=self.ordered, fastpath=True) def astype(self, dtype): """ coerce this type to another dtype """ @@ -373,9 +367,12 @@ def from_codes(cls, codes, categories, ordered=False, name=None): ordered : boolean, (default False) Whether or not this categorical is treated as a ordered categorical. If not given, the resulting categorical will be unordered. - name : str, optional - Name for the Categorical variable. """ + if not name is None: + msg = "the 'name' keyword is removed, use 'name' with consumers of the " \ + "categorical instead (e.g. 'Series(cat, name=\"something\")'" + warn(msg, UserWarning, stacklevel=2) + try: codes = np.asarray(codes, np.int64) except: @@ -386,7 +383,7 @@ def from_codes(cls, codes, categories, ordered=False, name=None): if len(codes) and (codes.max() >= len(categories) or codes.min() < -1): raise ValueError("codes need to be between -1 and len(categories)-1") - return Categorical(codes, categories=categories, ordered=ordered, name=name, fastpath=True) + return Categorical(codes, categories=categories, ordered=ordered, fastpath=True) _codes = None @@ -416,8 +413,7 @@ def _get_labels(self): Deprecated, use .codes! """ - import warnings - warnings.warn("'labels' is deprecated. Use 'codes' instead", FutureWarning) + warn("'labels' is deprecated. Use 'codes' instead", FutureWarning, stacklevel=3) return self.codes labels = property(fget=_get_labels, fset=_set_codes) @@ -464,12 +460,12 @@ def _get_categories(self): def _set_levels(self, levels): """ set new levels (deprecated, use "categories") """ - warn("Assigning to 'levels' is deprecated, use 'categories'", FutureWarning) + warn("Assigning to 'levels' is deprecated, use 'categories'", FutureWarning, stacklevel=3) self.categories = levels def _get_levels(self): """ Gets the levels (deprecated, use "categories") """ - warn("Accessing 'levels' is deprecated, use 'categories'", FutureWarning) + warn("Accessing 'levels' is deprecated, use 'categories'", FutureWarning, stacklevel=3) return self.categories # TODO: Remove after deprecation period in 2017/ after 0.18 @@ -479,7 +475,8 @@ def _get_levels(self): def _set_ordered(self, value): """ Sets the ordered attribute to the boolean value """ - warn("Setting 'ordered' directly is deprecated, use 'set_ordered'", FutureWarning) + warn("Setting 'ordered' directly is deprecated, use 'set_ordered'", FutureWarning, + stacklevel=3) self.set_ordered(value, inplace=True) def set_ordered(self, value, inplace=False): @@ -820,6 +817,35 @@ def shape(self): return tuple([len(self._codes)]) + def shift(self, periods): + """ + Shift Categorical by desired number of periods. + + Parameters + ---------- + periods : int + Number of periods to move, can be positive or negative + + Returns + ------- + shifted : Categorical + """ + # since categoricals always have ndim == 1, an axis parameter + # doesnt make any sense here. + codes = self.codes + if codes.ndim > 1: + raise NotImplementedError("Categorical with ndim > 1.") + if np.prod(codes.shape) and (periods != 0): + codes = np.roll(codes, com._ensure_platform_int(periods), axis=0) + if periods > 0: + codes[:periods] = -1 + else: + codes[periods:] = -1 + + return Categorical.from_codes(codes, + categories=self.categories, + ordered=self.ordered) + def __array__(self, dtype=None): """ The numpy array interface. @@ -1001,19 +1027,22 @@ def value_counts(self, dropna=True): """ import pandas.hashtable as htable from pandas.core.series import Series + from pandas.core.index import CategoricalIndex cat = self.dropna() if dropna else self - keys, counts = htable.value_count_int64(com._ensure_int64(cat._codes)) + keys, counts = htable.value_count_scalar64(com._ensure_int64(cat._codes), dropna) result = Series(counts, index=keys) ix = np.arange(len(cat.categories), dtype='int64') if not dropna and -1 in keys: ix = np.append(ix, -1) result = result.reindex(ix, fill_value=0) - result.index = (np.append(cat.categories, np.nan) + index = (np.append(cat.categories, np.nan) if not dropna and -1 in keys else cat.categories) + result.index = CategoricalIndex(index, self.categories, self.ordered) + return result def get_values(self): @@ -1024,15 +1053,12 @@ def get_values(self): Returns ------- values : numpy array - A numpy array of the same dtype as categorical.categories.dtype or dtype string if - periods + A numpy array of the same dtype as categorical.categories.dtype or + Index if datetime / periods """ - - # if we are a period index, return a string repr - if isinstance(self.categories, ABCPeriodIndex): - return take_1d(np.array(self.categories.to_native_types(), dtype=object), - self._codes) - + # if we are a datetime and period index, return Index to keep metadata + if com.is_datetimelike(self.categories): + return self.categories.take(self._codes) return np.array(self) def check_for_ordered(self, op): @@ -1111,7 +1137,7 @@ def order(self, inplace=False, ascending=True, na_position='last'): return else: return Categorical(values=codes,categories=self.categories, ordered=self.ordered, - name=self.name, fastpath=True) + fastpath=True) def sort(self, inplace=True, ascending=True, na_position='last'): @@ -1237,7 +1263,7 @@ def fillna(self, value=None, method=None, limit=None): values[mask] = self.categories.get_loc(value) return Categorical(values, categories=self.categories, ordered=self.ordered, - name=self.name, fastpath=True) + fastpath=True) def take_nd(self, indexer, allow_fill=True, fill_value=None): """ Take the codes by the indexer, fill with the fill_value. @@ -1251,7 +1277,7 @@ def take_nd(self, indexer, allow_fill=True, fill_value=None): codes = take_1d(self._codes, indexer, allow_fill=True, fill_value=-1) result = Categorical(codes, categories=self.categories, ordered=self.ordered, - name=self.name, fastpath=True) + fastpath=True) return result take = take_nd @@ -1271,7 +1297,7 @@ def _slice(self, slicer): _codes = self._codes[slicer] return Categorical(values=_codes,categories=self.categories, ordered=self.ordered, - name=self.name, fastpath=True) + fastpath=True) def __len__(self): """The length of this Categorical.""" @@ -1279,14 +1305,13 @@ def __len__(self): def __iter__(self): """Returns an Iterator over the values of this Categorical.""" - return iter(np.array(self)) + return iter(self.get_values()) def _tidy_repr(self, max_vals=10, footer=True): """ a short repr displaying only max_vals and an optional (but default footer) """ num = max_vals // 2 - head = self[:num]._get_repr(length=False, name=False, footer=False) + head = self[:num]._get_repr(length=False, footer=False) tail = self[-(max_vals - num):]._get_repr(length=False, - name=False, footer=False) result = '%s, ..., %s' % (head[:-1], tail[1:]) @@ -1300,7 +1325,7 @@ def _repr_categories(self): max_categories = (10 if get_option("display.max_categories") == 0 else get_option("display.max_categories")) from pandas.core import format as fmt - category_strs = fmt.format_array(self.categories.get_values(), None) + category_strs = fmt.format_array(self.categories, None) if len(category_strs) > max_categories: num = max_categories // 2 head = category_strs[:num] @@ -1315,8 +1340,9 @@ def _repr_categories_info(self): """ Returns a string representation of the footer.""" category_strs = self._repr_categories() - levheader = "Categories (%d, %s): " % (len(self.categories), - self.categories.dtype) + dtype = getattr(self.categories, 'dtype_str', str(self.categories.dtype)) + + levheader = "Categories (%d, %s): " % (len(self.categories), dtype) width, height = get_terminal_size() max_width = get_option("display.width") or width if com.in_ipython_frontend(): @@ -1324,13 +1350,14 @@ def _repr_categories_info(self): max_width = 0 levstring = "" start = True - cur_col_len = len(levheader) + cur_col_len = len(levheader) # header sep_len, sep = (3, " < ") if self.ordered else (2, ", ") + linesep = sep.rstrip() + "\n" # remove whitespace for val in category_strs: if max_width != 0 and cur_col_len + sep_len + len(val) > max_width: - levstring += "\n" + (" "* len(levheader)) - cur_col_len = len(levheader) - if not start: + levstring += linesep + (" " * (len(levheader) + 1)) + cur_col_len = len(levheader) + 1 # header + a whitespace + elif not start: levstring += sep cur_col_len += len(val) levstring += val @@ -1340,14 +1367,11 @@ def _repr_categories_info(self): def _repr_footer(self): - namestr = "Name: %s, " % self.name if self.name is not None else "" - return u('%sLength: %d\n%s') % (namestr, - len(self), self._repr_categories_info()) + return u('Length: %d\n%s') % (len(self), self._repr_categories_info()) - def _get_repr(self, name=False, length=True, na_rep='NaN', footer=True): + def _get_repr(self, length=True, na_rep='NaN', footer=True): from pandas.core import format as fmt formatter = fmt.CategoricalFormatter(self, - name=name, length=length, na_rep=na_rep, footer=footer) @@ -1360,11 +1384,9 @@ def __unicode__(self): if len(self._codes) > _maxlen: result = self._tidy_repr(_maxlen) elif len(self._codes) > 0: - result = self._get_repr(length=len(self) > _maxlen, - name=True) + result = self._get_repr(length=len(self) > _maxlen) else: - result = '[], %s' % self._get_repr(name=True, - length=False, + result = '[], %s' % self._get_repr(length=False, footer=True, ).replace("\n",", ") @@ -1533,32 +1555,40 @@ def mode(self): import pandas.hashtable as htable good = self._codes != -1 result = Categorical(sorted(htable.mode_int64(_ensure_int64(self._codes[good]))), - categories=self.categories,ordered=self.ordered, name=self.name, - fastpath=True) + categories=self.categories,ordered=self.ordered, fastpath=True) return result def unique(self): """ - Return the unique values. + Return the ``Categorical`` which ``categories`` and ``codes`` are unique. + Unused categories are NOT returned. - Unused categories are NOT returned. Unique values are returned in order - of appearance. + - unordered category: values and categories are sorted by appearance + order. + - ordered category: values are sorted by appearance order, categories + keeps existing order. Returns ------- - unique values : array + unique values : ``Categorical`` """ + from pandas.core.nanops import unique1d # unlike np.unique, unique1d does not sort unique_codes = unique1d(self.codes) - return take_1d(self.categories.values, unique_codes) + cat = self.copy() + # keep nan in codes + cat._codes = unique_codes + # exclude nan from indexer for categories + take_codes = unique_codes[unique_codes != -1] + if self.ordered: + take_codes = sorted(take_codes) + return cat.set_categories(cat.categories.take(take_codes)) def equals(self, other): """ Returns True if categorical arrays are equal. - The name of the `Categorical` is not compared! - Parameters ---------- other : `Categorical` @@ -1567,7 +1597,6 @@ def equals(self, other): ------- are_equal : boolean """ - # TODO: should this also test if name is equal? return self.is_dtype_equal(other) and np.array_equal(self._codes, other._codes) def is_dtype_equal(self, other): @@ -1618,7 +1647,7 @@ def repeat(self, repeats): """ codes = self._codes.repeat(repeats) return Categorical(values=codes, categories=self.categories, - ordered=self.ordered, name=self.name, fastpath=True) + ordered=self.ordered, fastpath=True) ##### The Series.cat accessor ##### @@ -1667,7 +1696,6 @@ def _delegate_method(self, name, *args, **kwargs): if not res is None: return Series(res, index=self.index) -# TODO: remove levels after the deprecation period CategoricalAccessor._add_delegate_accessors(delegate=Categorical, accessors=["categories", "ordered"], typ='property') @@ -1715,17 +1743,20 @@ def _convert_to_list_like(list_like): return [list_like] def _concat_compat(to_concat, axis=0): - """ - provide concatenation of an object/categorical array of arrays each of which is a single dtype + """Concatenate an object/categorical array of arrays, each of which is a + single dtype Parameters ---------- to_concat : array of arrays - axis : axis to provide concatenation + axis : int + Axis to provide concatenation in the current implementation this is + always 0, e.g. we only have 1D categoricals Returns ------- - a single array, preserving the combined dtypes + Categorical + A single array, preserving the combined dtypes """ def convert_categorical(x): @@ -1734,31 +1765,34 @@ def convert_categorical(x): return x.get_values() return x.ravel() - typs = get_dtype_kinds(to_concat) - if not len(typs-set(['object','category'])): - - # we only can deal with object & category types - pass - - else: - + if get_dtype_kinds(to_concat) - set(['object', 'category']): # convert to object type and perform a regular concat from pandas.core.common import _concat_compat - return _concat_compat([ np.array(x,copy=False).astype('object') for x in to_concat ],axis=axis) + return _concat_compat([np.array(x, copy=False, dtype=object) + for x in to_concat], axis=0) - # we could have object blocks and categorical's here - # if we only have a single cateogoricals then combine everything + # we could have object blocks and categoricals here + # if we only have a single categoricals then combine everything # else its a non-compat categorical - categoricals = [ x for x in to_concat if is_categorical_dtype(x.dtype) ] - objects = [ x for x in to_concat if is_object_dtype(x.dtype) ] + categoricals = [x for x in to_concat if is_categorical_dtype(x.dtype)] # validate the categories - categories = None - for x in categoricals: - if categories is None: - categories = x.categories - if not categories.equals(x.categories): + categories = categoricals[0] + rawcats = categories.categories + for x in categoricals[1:]: + if not categories.is_dtype_equal(x): raise ValueError("incompatible categories in categorical concat") - # concat them - return Categorical(np.concatenate([ convert_categorical(x) for x in to_concat ],axis=axis), categories=categories) + # we've already checked that all categoricals are the same, so if their + # length is equal to the input then we have all the same categories + if len(categoricals) == len(to_concat): + # concating numeric types is much faster than concating object types + # and fastpath takes a shorter path through the constructor + return Categorical(np.concatenate([x.codes for x in to_concat], axis=0), + rawcats, + ordered=categoricals[0].ordered, + fastpath=True) + else: + concatted = np.concatenate(list(map(convert_categorical, to_concat)), + axis=0) + return Categorical(concatted, rawcats) diff --git a/pandas/core/common.py b/pandas/core/common.py index 84ef421128cd0..aaa341240f538 100644 --- a/pandas/core/common.py +++ b/pandas/core/common.py @@ -47,7 +47,7 @@ def __init__(self, class_instance): self.class_instance = class_instance def __str__(self): - return "This method must be defined on the concrete class of " \ + return "This method must be defined in the concrete class of " \ + self.class_instance.__class__.__name__ _POSSIBLY_CAST_DTYPES = set([np.dtype(t).name @@ -113,30 +113,6 @@ def __instancecheck__(cls, inst): ABCGeneric = _ABCGeneric("ABCGeneric", tuple(), {}) -def bind_method(cls, name, func): - """Bind a method to class, python 2 and python 3 compatible. - - Parameters - ---------- - - cls : type - class to receive bound method - name : basestring - name of method on class instance - func : function - function to be bound as method - - - Returns - ------- - None - """ - # only python 2 has bound/unbound method issue - if not compat.PY3: - setattr(cls, name, types.MethodType(func, None, cls)) - else: - setattr(cls, name, func) - class CategoricalDtypeType(type): """ the type of CategoricalDtype, this metaclass determines subclass ability @@ -462,6 +438,10 @@ def array_equivalent(left, right, strict_nan=False): if issubclass(left.dtype.type, (np.floating, np.complexfloating)): return ((left == right) | (np.isnan(left) & np.isnan(right))).all() + # numpy will will not allow this type of datetimelike vs integer comparison + elif is_datetimelike_v_numeric(left, right): + return False + # NaNs cannot occur otherwise. return np.array_equal(left, right) @@ -782,6 +762,11 @@ def take_nd(arr, indexer, axis=0, out=None, fill_value=np.nan, will be done. This short-circuits computation of a mask. Result is undefined if allow_fill == False and -1 is present in indexer. """ + + if is_categorical(arr): + return arr.take_nd(indexer, fill_value=fill_value, + allow_fill=allow_fill) + if indexer is None: indexer = np.arange(arr.shape[axis], dtype=np.int64) dtype, fill_value = arr.dtype, arr.dtype.type() @@ -839,7 +824,6 @@ def take_nd(arr, indexer, axis=0, out=None, fill_value=np.nan, func = _get_take_nd_function(arr.ndim, arr.dtype, out.dtype, axis=axis, mask_info=mask_info) - indexer = _ensure_int64(indexer) func(arr, indexer, out, fill_value) @@ -1194,7 +1178,7 @@ def _maybe_upcast_putmask(result, mask, other): if result.dtype in _DATELIKE_DTYPES: if lib.isscalar(other): if isnull(other): - other = tslib.iNaT + other = result.dtype.type('nat') elif is_integer(other): other = np.array(other, dtype=result.dtype) elif is_integer_dtype(other): @@ -1588,7 +1572,8 @@ def backfill_2d(values, limit=None, mask=None, dtype=None): return values -def _clean_interp_method(method, order=None): +def _clean_interp_method(method, **kwargs): + order = kwargs.get('order') valid = ['linear', 'time', 'index', 'values', 'nearest', 'zero', 'slinear', 'quadratic', 'cubic', 'barycentric', 'polynomial', 'krogh', 'piecewise_polynomial', @@ -1603,7 +1588,7 @@ def _clean_interp_method(method, order=None): def interpolate_1d(xvalues, yvalues, method='linear', limit=None, - fill_value=None, bounds_error=False, order=None): + fill_value=None, bounds_error=False, order=None, **kwargs): """ Logic for the 1-d interpolation. The result should be 1-d, inputs xvalues and yvalues will each be 1-d arrays of the same length. @@ -1682,18 +1667,17 @@ def _interp_limit(invalid, limit): 'piecewise_polynomial', 'pchip'] if method in sp_methods: new_x = new_x[firstIndex:] - xvalues = xvalues[firstIndex:] result[firstIndex:][invalid] = _interpolate_scipy_wrapper( valid_x, valid_y, new_x, method=method, fill_value=fill_value, - bounds_error=bounds_error, order=order) + bounds_error=bounds_error, order=order, **kwargs) if limit: result[violate_limit] = np.nan return result def _interpolate_scipy_wrapper(x, y, new_x, method, fill_value=None, - bounds_error=False, order=None): + bounds_error=False, order=None, **kwargs): """ passed off to scipy.interpolate.interp1d. method is scipy's kind. Returns an array interpolated at new_x. Add any new methods to @@ -1734,7 +1718,7 @@ def _interpolate_scipy_wrapper(x, y, new_x, method, fill_value=None, bounds_error=bounds_error) new_y = terp(new_x) elif method == 'spline': - terp = interpolate.UnivariateSpline(x, y, k=order) + terp = interpolate.UnivariateSpline(x, y, k=order, **kwargs) new_y = terp(new_x) else: # GH 7295: need to be able to write for some reason @@ -1746,7 +1730,7 @@ def _interpolate_scipy_wrapper(x, y, new_x, method, fill_value=None, if not new_x.flags.writeable: new_x = new_x.copy() method = alt_methods[method] - new_y = method(x, y, new_x) + new_y = method(x, y, new_x, **kwargs) return new_y @@ -1883,65 +1867,68 @@ def _maybe_box_datetimelike(value): _values_from_object = lib.values_from_object -def _possibly_convert_objects(values, convert_dates=True, - convert_numeric=True, - convert_timedeltas=True): + +def _possibly_convert_objects(values, + datetime=True, + numeric=True, + timedelta=True, + coerce=False, + copy=True): """ if we have an object dtype, try to coerce dates and/or numbers """ - # if we have passed in a list or scalar + conversion_count = sum((datetime, numeric, timedelta)) + if conversion_count == 0: + import warnings + warnings.warn('Must explicitly pass type for conversion. Defaulting to ' + 'pre-0.17 behavior where datetime=True, numeric=True, ' + 'timedelta=True and coerce=False', DeprecationWarning) + datetime = numeric = timedelta = True + coerce = False + if isinstance(values, (list, tuple)): + # List or scalar values = np.array(values, dtype=np.object_) - if not hasattr(values, 'dtype'): + elif not hasattr(values, 'dtype'): values = np.array([values], dtype=np.object_) - - # convert dates - if convert_dates and values.dtype == np.object_: - - # we take an aggressive stance and convert to datetime64[ns] - if convert_dates == 'coerce': - new_values = _possibly_cast_to_datetime( - values, 'M8[ns]', coerce=True) - - # if we are all nans then leave me alone - if not isnull(new_values).all(): - values = new_values - - else: - values = lib.maybe_convert_objects( - values, convert_datetime=convert_dates) - - # convert timedeltas - if convert_timedeltas and values.dtype == np.object_: - - if convert_timedeltas == 'coerce': - from pandas.tseries.timedeltas import to_timedelta - values = to_timedelta(values, coerce=True) - - # if we are all nans then leave me alone - if not isnull(new_values).all(): - values = new_values - - else: - values = lib.maybe_convert_objects( - values, convert_timedelta=convert_timedeltas) - - # convert to numeric - if values.dtype == np.object_: - if convert_numeric: - try: - new_values = lib.maybe_convert_numeric( - values, set(), coerce_numeric=True) - - # if we are all nans then leave me alone - if not isnull(new_values).all(): - values = new_values - - except: - pass - else: - - # soft-conversion - values = lib.maybe_convert_objects(values) + elif not is_object_dtype(values.dtype): + # If not object, do not attempt conversion + values = values.copy() if copy else values + return values + + # If 1 flag is coerce, ensure 2 others are False + if coerce: + if conversion_count > 1: + raise ValueError("Only one of 'datetime', 'numeric' or " + "'timedelta' can be True when when coerce=True.") + + # Immediate return if coerce + if datetime: + return pd.to_datetime(values, errors='coerce', box=False) + elif timedelta: + return pd.to_timedelta(values, errors='coerce', box=False) + elif numeric: + return lib.maybe_convert_numeric(values, set(), coerce_numeric=True) + + # Soft conversions + if datetime: + values = lib.maybe_convert_objects(values, + convert_datetime=datetime) + + if timedelta and is_object_dtype(values.dtype): + # Object check to ensure only run if previous did not convert + values = lib.maybe_convert_objects(values, + convert_timedelta=timedelta) + + if numeric and is_object_dtype(values.dtype): + try: + converted = lib.maybe_convert_numeric(values, + set(), + coerce_numeric=True) + # If all NaNs, then do not-alter + values = converted if not isnull(converted).all() else values + values = values.copy() if copy else values + except: + pass return values @@ -1971,7 +1958,7 @@ def _possibly_convert_platform(values): return values -def _possibly_cast_to_datetime(value, dtype, coerce=False): +def _possibly_cast_to_datetime(value, dtype, errors='raise'): """ try to cast the array/value to a datetimelike dtype, converting float nan to iNaT """ @@ -2015,9 +2002,9 @@ def _possibly_cast_to_datetime(value, dtype, coerce=False): elif np.prod(value.shape) and value.dtype != dtype: try: if is_datetime64: - value = to_datetime(value, coerce=coerce).values + value = to_datetime(value, errors=errors).values elif is_timedelta64: - value = to_timedelta(value, coerce=coerce).values + value = to_timedelta(value, errors=errors).values except (AttributeError, ValueError): pass @@ -2079,7 +2066,7 @@ def _possibly_infer_to_datetimelike(value, convert_dates=False): def _try_datetime(v): # safe coerce to datetime64 try: - return tslib.array_to_datetime(v, raise_=True).reshape(shape) + return tslib.array_to_datetime(v, errors='raise').reshape(shape) except: return v @@ -2497,6 +2484,10 @@ def is_integer_dtype(arr_or_dtype): return (issubclass(tipo, np.integer) and not issubclass(tipo, (np.datetime64, np.timedelta64))) +def is_int64_dtype(arr_or_dtype): + tipo = _get_dtype_type(arr_or_dtype) + return issubclass(tipo, np.int64) + def is_int_or_datetime_dtype(arr_or_dtype): tipo = _get_dtype_type(arr_or_dtype) @@ -2528,6 +2519,26 @@ def is_datetime_or_timedelta_dtype(arr_or_dtype): return issubclass(tipo, (np.datetime64, np.timedelta64)) +def is_datetimelike_v_numeric(a, b): + # return if we have an i8 convertible and numeric comparision + if not hasattr(a,'dtype'): + a = np.asarray(a) + if not hasattr(b, 'dtype'): + b = np.asarray(b) + f = lambda x: is_integer_dtype(x) or is_float_dtype(x) + return (needs_i8_conversion(a) and f(b)) or ( + needs_i8_conversion(b) and f(a)) + +def is_datetimelike_v_object(a, b): + # return if we have an i8 convertible and object comparision + if not hasattr(a,'dtype'): + a = np.asarray(a) + if not hasattr(b, 'dtype'): + b = np.asarray(b) + f = lambda x: is_object_dtype(x) + return (needs_i8_conversion(a) and f(b)) or ( + needs_i8_conversion(b) and f(a)) + needs_i8_conversion = is_datetime_or_timedelta_dtype def i8_boxer(arr_or_dtype): @@ -2605,9 +2616,14 @@ def is_list_like(arg): not isinstance(arg, compat.string_and_binary_types)) def is_null_slice(obj): + """ we have a null slice """ return (isinstance(obj, slice) and obj.start is None and obj.stop is None and obj.step is None) +def is_full_slice(obj, l): + """ we have a full length slice """ + return (isinstance(obj, slice) and obj.start == 0 and + obj.stop == l and obj.step is None) def is_hashable(arg): """Return True if hash(arg) will succeed, False otherwise. @@ -2813,11 +2829,7 @@ def _get_handle(path, mode, encoding=None, compression=None): else: raise ValueError('Unrecognized compression type: %s' % compression) - if compat.PY3_2: - # gzip and bz2 don't work with TextIOWrapper in 3.2 - encoding = encoding or get_option('display.encoding') - f = StringIO(f.read().decode(encoding)) - elif compat.PY3: + if compat.PY3: from io import TextIOWrapper f = TextIOWrapper(f, encoding=encoding) return f diff --git a/pandas/core/config_init.py b/pandas/core/config_init.py index a56d3b93d87da..03eaa45582bef 100644 --- a/pandas/core/config_init.py +++ b/pandas/core/config_init.py @@ -236,7 +236,7 @@ def mpl_style_cb(key): return val with cf.config_prefix('display'): - cf.register_option('precision', 7, pc_precision_doc, validator=is_int) + cf.register_option('precision', 6, pc_precision_doc, validator=is_int) cf.register_option('float_format', None, float_format_doc) cf.register_option('column_space', 12, validator=is_int) cf.register_option('max_info_rows', 1690785, pc_max_info_rows_doc, diff --git a/pandas/core/format.py b/pandas/core/format.py index 4f0e57130006b..4ec4375349764 100644 --- a/pandas/core/format.py +++ b/pandas/core/format.py @@ -68,10 +68,9 @@ class CategoricalFormatter(object): def __init__(self, categorical, buf=None, length=True, - na_rep='NaN', name=False, footer=True): + na_rep='NaN', footer=True): self.categorical = categorical self.buf = buf if buf is not None else StringIO(u("")) - self.name = name self.na_rep = na_rep self.length = length self.footer = footer @@ -79,12 +78,6 @@ def __init__(self, categorical, buf=None, length=True, def _get_footer(self): footer = '' - if self.name: - name = com.pprint_thing(self.categorical.name, - escape_chars=('\t', '\r', '\n')) - footer += ('Name: %s' % name if self.categorical.name is not None - else '') - if self.length: if footer: footer += ', ' @@ -214,7 +207,7 @@ def _get_formatted_index(self): return fmt_index, have_header def _get_formatted_values(self): - return format_array(self.tr_series.get_values(), None, + return format_array(self.tr_series.values, None, float_format=self.float_format, na_rep=self.na_rep) @@ -688,7 +681,7 @@ def _format_col(self, i): frame = self.tr_frame formatter = self._get_formatter(i) return format_array( - (frame.iloc[:, i]).get_values(), + frame.iloc[:, i].values, formatter, float_format=self.float_format, na_rep=self.na_rep, space=self.col_space ) @@ -1044,7 +1037,7 @@ def _column_header(): self.write_tr(col_row, indent, self.indent_delta, header=True, align=align) - if self.fmt.has_index_names: + if self.fmt.has_index_names and self.fmt.index: row = [ x if x is not None else '' for x in self.frame.index.names ] + [''] * min(len(self.columns), self.max_cols) @@ -1902,8 +1895,13 @@ def get_formatted_cells(self): def format_array(values, formatter, float_format=None, na_rep='NaN', digits=None, space=None, justify='right'): - if com.is_float_dtype(values.dtype): + + if com.is_categorical_dtype(values): + fmt_klass = CategoricalArrayFormatter + elif com.is_float_dtype(values.dtype): fmt_klass = FloatArrayFormatter + elif com.is_period_arraylike(values): + fmt_klass = PeriodArrayFormatter elif com.is_integer_dtype(values.dtype): fmt_klass = IntArrayFormatter elif com.is_datetime64_dtype(values.dtype): @@ -1970,6 +1968,8 @@ def _format(x): return '%s' % formatter(x) vals = self.values + if isinstance(vals, Index): + vals = vals.values is_float = lib.map_infer(vals, com.is_float) & notnull(vals) leading_space = is_float.any() @@ -2021,7 +2021,7 @@ def _format_strings(self): if self.formatter is not None: fmt_values = [self.formatter(x) for x in self.values] else: - fmt_str = '%% .%df' % (self.digits - 1) + fmt_str = '%% .%df' % self.digits fmt_values = self._format_with(fmt_str) if len(fmt_values) > 0: @@ -2029,20 +2029,20 @@ def _format_strings(self): else: maxlen = 0 - too_long = maxlen > self.digits + 5 + too_long = maxlen > self.digits + 6 abs_vals = np.abs(self.values) # this is pretty arbitrary for now has_large_values = (abs_vals > 1e8).any() - has_small_values = ((abs_vals < 10 ** (-self.digits+1)) & + has_small_values = ((abs_vals < 10 ** (-self.digits)) & (abs_vals > 0)).any() if too_long and has_large_values: - fmt_str = '%% .%de' % (self.digits - 1) + fmt_str = '%% .%de' % self.digits fmt_values = self._format_with(fmt_str) elif has_small_values: - fmt_str = '%% .%de' % (self.digits - 1) + fmt_str = '%% .%de' % self.digits fmt_values = self._format_with(fmt_str) return fmt_values @@ -2083,8 +2083,30 @@ def _format_strings(self): values = values.asobject is_dates_only = _is_dates_only(values) formatter = (self.formatter or _get_format_datetime64(is_dates_only, values, date_format=self.date_format)) - fmt_values = [ formatter(x) for x in self.values ] + fmt_values = [ formatter(x) for x in values ] + + return fmt_values + +class PeriodArrayFormatter(IntArrayFormatter): + + def _format_strings(self): + values = np.array(self.values.to_native_types(), dtype=object) + formatter = self.formatter or (lambda x: '%s' % x) + fmt_values = [formatter(x) for x in values] + return fmt_values + + +class CategoricalArrayFormatter(GenericArrayFormatter): + + def __init__(self, values, *args, **kwargs): + GenericArrayFormatter.__init__(self, values, *args, **kwargs) + + def _format_strings(self): + fmt_values = format_array(self.values.get_values(), self.formatter, + float_format=self.float_format, + na_rep=self.na_rep, digits=self.digits, + space=self.space, justify=self.justify) return fmt_values diff --git a/pandas/core/frame.py b/pandas/core/frame.py index cf7f1fa033f6e..8f7aee0cb6f15 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -184,7 +184,6 @@ class DataFrame(NDFrame): DataFrame.from_items : from sequence of (key, value) pairs pandas.read_csv, pandas.read_table, pandas.read_clipboard """ - _auto_consolidate = True @property def _constructor(self): @@ -322,6 +321,8 @@ def _init_dict(self, data, index, columns, dtype=None): if dtype is None: # 1783 v = np.empty(len(index), dtype=object) + elif np.issubdtype(dtype, np.flexible): + v = np.empty(len(index), dtype=object) else: v = np.empty(len(index), dtype=dtype) @@ -545,35 +546,63 @@ def _repr_html_(self): return None def iteritems(self): - """Iterator over (column, series) pairs""" + """ + Iterator over (column name, Series) pairs. + + See also + -------- + iterrows : Iterate over the rows of a DataFrame as (index, Series) pairs. + itertuples : Iterate over the rows of a DataFrame as tuples of the values. + + """ if self.columns.is_unique and hasattr(self, '_item_cache'): for k in self.columns: yield k, self._get_item_cache(k) else: for i, k in enumerate(self.columns): - yield k, self.icol(i) + yield k, self._ixs(i,axis=1) def iterrows(self): """ - Iterate over rows of DataFrame as (index, Series) pairs. + Iterate over the rows of a DataFrame as (index, Series) pairs. Notes ----- - * ``iterrows`` does **not** preserve dtypes across the rows (dtypes - are preserved across columns for DataFrames). For example, - - >>> df = DataFrame([[1, 1.0]], columns=['x', 'y']) - >>> row = next(df.iterrows())[1] - >>> print(row['x'].dtype) - float64 - >>> print(df['x'].dtype) - int64 + 1. Because ``iterrows` returns a Series for each row, + it does **not** preserve dtypes across the rows (dtypes are + preserved across columns for DataFrames). For example, + + >>> df = pd.DataFrame([[1, 1.5]], columns=['int', 'float']) + >>> row = next(df.iterrows())[1] + >>> row + int 1.0 + float 1.5 + Name: 0, dtype: float64 + >>> print(row['int'].dtype) + float64 + >>> print(df['int'].dtype) + int64 + + To preserve dtypes while iterating over the rows, it is better + to use :meth:`itertuples` which returns tuples of the values + and which is generally faster as ``iterrows``. + + 2. You should **never modify** something you are iterating over. + This is not guaranteed to work in all cases. Depending on the + data types, the iterator returns a copy and not a view, and writing + to it will have no effect. Returns ------- it : generator A generator that iterates over the rows of the frame. + + See also + -------- + itertuples : Iterate over the rows of a DataFrame as tuples of the values. + iteritems : Iterate over (column name, Series) pairs. + """ columns = self.columns for k, v in zip(self.index, self.values): @@ -582,8 +611,32 @@ def iterrows(self): def itertuples(self, index=True): """ - Iterate over rows of DataFrame as tuples, with index value - as first element of the tuple + Iterate over the rows of DataFrame as tuples, with index value + as first element of the tuple. + + Parameters + ---------- + index : boolean, default True + If True, return the index as the first element of the tuple. + + See also + -------- + iterrows : Iterate over the rows of a DataFrame as (index, Series) pairs. + iteritems : Iterate over (column name, Series) pairs. + + Examples + -------- + + >>> df = pd.DataFrame({'col1': [1, 2], 'col2': [0.1, 0.2]}, index=['a', 'b']) + >>> df + col1 col2 + a 1 0.1 + b 2 0.2 + >>> for row in df.itertuples(): + ... print(row) + ('a', 1, 0.10000000000000001) + ('b', 2, 0.20000000000000001) + """ arrays = [] if index: @@ -1114,14 +1167,14 @@ def to_csv(self, path_or_buf=None, sep=",", na_rep='', float_format=None, quotechar='"', line_terminator='\n', chunksize=None, tupleize_cols=False, date_format=None, doublequote=True, escapechar=None, decimal='.', **kwds): - r"""Write DataFrame to a comma-separated values (csv) file + """Write DataFrame to a comma-separated values (csv) file Parameters ---------- path_or_buf : string or file handle, default None File path or object, if None is provided the result is returned as a string. - sep : character, default "," + sep : character, default ',' Field delimiter for the output file. na_rep : string, default '' Missing data representation @@ -1152,7 +1205,7 @@ def to_csv(self, path_or_buf=None, sep=",", na_rep='', float_format=None, file quoting : optional constant from csv module defaults to csv.QUOTE_MINIMAL - quotechar : string (length 1), default '"' + quotechar : string (length 1), default '\"' character used to quote fields doublequote : boolean, default True Control quoting of `quotechar` inside a field @@ -1246,6 +1299,9 @@ def to_excel(self, excel_writer, sheet_name='Sheet1', na_rep='', >>> df1.to_excel(writer,'Sheet1') >>> df2.to_excel(writer,'Sheet2') >>> writer.save() + + For compatibility with to_csv, to_excel serializes lists and dicts to + strings before writing. """ from pandas.io.excel import ExcelWriter if self.columns.nlevels > 1: @@ -1693,9 +1749,20 @@ def set_value(self, index, col, value, takeable=False): return self def irow(self, i, copy=False): + """ + DEPRECATED. Use ``.iloc[i]`` instead + """ + + warnings.warn("irow(i) is deprecated. Please use .iloc[i]", + FutureWarning, stacklevel=2) return self._ixs(i, axis=0) def icol(self, i): + """ + DEPRECATED. Use ``.iloc[:, i]`` instead + """ + warnings.warn("icol(i) is deprecated. Please use .iloc[:,i]", + FutureWarning, stacklevel=2) return self._ixs(i, axis=1) def _ixs(self, i, axis=0): @@ -1769,6 +1836,11 @@ def _ixs(self, i, axis=0): return result def iget_value(self, i, j): + """ + DEPRECATED. Use ``.iat[i, j]`` instead + """ + warnings.warn("iget_value(i, j) is deprecated. Please use .iat[i, j]", + FutureWarning, stacklevel=2) return self.iat[i, j] def __getitem__(self, key): @@ -2166,16 +2238,11 @@ def _ensure_valid_index(self, value): ensure that if we don't have an index, that we can create one from the passed value """ - if not len(self.index): - - # GH5632, make sure that we are a Series convertible - if is_list_like(value): + # GH5632, make sure that we are a Series convertible + if not len(self.index) and is_list_like(value): try: value = Series(value) except: - pass - - if not isinstance(value, Series): raise ValueError('Cannot set a frame with no defined index ' 'and a value that cannot be converted to a ' 'Series') @@ -2183,11 +2250,6 @@ def _ensure_valid_index(self, value): self._data = self._data.reindex_axis(value.index.copy(), axis=1, fill_value=np.nan) - # we are a scalar - # noop - else: - - pass def _set_item(self, key, value): """ @@ -2456,33 +2518,36 @@ def lookup(self, row_labels, col_labels): #---------------------------------------------------------------------- # Reindexing and alignment - def _reindex_axes(self, axes, level, limit, method, fill_value, copy): + def _reindex_axes(self, axes, level, limit, tolerance, method, + fill_value, copy): frame = self columns = axes['columns'] if columns is not None: frame = frame._reindex_columns(columns, copy, level, fill_value, - limit) + limit, tolerance) index = axes['index'] if index is not None: frame = frame._reindex_index(index, method, copy, level, - fill_value, limit) + fill_value, limit, tolerance) return frame def _reindex_index(self, new_index, method, copy, level, fill_value=NA, - limit=None): + limit=None, tolerance=None): new_index, indexer = self.index.reindex(new_index, method, level, - limit=limit) + limit=limit, + tolerance=tolerance) return self._reindex_with_indexers({0: [new_index, indexer]}, copy=copy, fill_value=fill_value, allow_dups=False) def _reindex_columns(self, new_columns, copy, level, fill_value=NA, - limit=None): + limit=None, tolerance=None): new_columns, indexer = self.columns.reindex(new_columns, level=level, - limit=limit) + limit=limit, + tolerance=tolerance) return self._reindex_with_indexers({1: [new_columns, indexer]}, copy=copy, fill_value=fill_value, allow_dups=False) @@ -2804,8 +2869,9 @@ def dropna(self, axis=0, how='any', thresh=None, subset=None, else: return result + @deprecate_kwarg('take_last', 'keep', mapping={True: 'last', False: 'first'}) @deprecate_kwarg(old_arg_name='cols', new_arg_name='subset') - def drop_duplicates(self, subset=None, take_last=False, inplace=False): + def drop_duplicates(self, subset=None, keep='first', inplace=False): """ Return DataFrame with duplicate rows removed, optionally only considering certain columns @@ -2815,8 +2881,11 @@ def drop_duplicates(self, subset=None, take_last=False, inplace=False): subset : column label or sequence of labels, optional Only consider certain columns for identifying duplicates, by default use all of the columns - take_last : boolean, default False - Take the last observed row in a row. Defaults to the first row + keep : {'first', 'last', False}, default 'first' + - ``first`` : Drop duplicates except for the first occurrence. + - ``last`` : Drop duplicates except for the last occurrence. + - False : Drop all duplicates. + take_last : deprecated inplace : boolean, default False Whether to drop duplicates in place or to return a copy cols : kwargs only argument of subset [deprecated] @@ -2825,7 +2894,7 @@ def drop_duplicates(self, subset=None, take_last=False, inplace=False): ------- deduplicated : DataFrame """ - duplicated = self.duplicated(subset, take_last=take_last) + duplicated = self.duplicated(subset, keep=keep) if inplace: inds, = (-duplicated).nonzero() @@ -2834,8 +2903,9 @@ def drop_duplicates(self, subset=None, take_last=False, inplace=False): else: return self[-duplicated] + @deprecate_kwarg('take_last', 'keep', mapping={True: 'last', False: 'first'}) @deprecate_kwarg(old_arg_name='cols', new_arg_name='subset') - def duplicated(self, subset=None, take_last=False): + def duplicated(self, subset=None, keep='first'): """ Return boolean Series denoting duplicate rows, optionally only considering certain columns @@ -2845,9 +2915,13 @@ def duplicated(self, subset=None, take_last=False): subset : column label or sequence of labels, optional Only consider certain columns for identifying duplicates, by default use all of the columns - take_last : boolean, default False - For a set of distinct duplicate rows, flag all but the last row as - duplicated. Default is for all but the first row to be flagged + keep : {'first', 'last', False}, default 'first' + - ``first`` : Mark duplicates as ``True`` except for the + first occurrence. + - ``last`` : Mark duplicates as ``True`` except for the + last occurrence. + - False : Mark all duplicates as ``True``. + take_last : deprecated cols : kwargs only argument of subset [deprecated] Returns @@ -2873,7 +2947,7 @@ def f(vals): labels, shape = map(list, zip( * map(f, vals))) ids = get_group_index(labels, shape, sort=False, xnull=False) - return Series(duplicated_int64(ids, take_last), index=self.index) + return Series(duplicated_int64(ids, keep), index=self.index) #---------------------------------------------------------------------- # Sorting @@ -3065,6 +3139,79 @@ def sortlevel(self, level=0, axis=0, ascending=True, else: return self._constructor(new_data).__finalize__(self) + def _nsorted(self, columns, n, method, take_last): + if not com.is_list_like(columns): + columns = [columns] + columns = list(columns) + ser = getattr(self[columns[0]], method)(n, take_last=take_last) + ascending = dict(nlargest=False, nsmallest=True)[method] + return self.loc[ser.index].sort(columns, ascending=ascending, + kind='mergesort') + + def nlargest(self, n, columns, take_last=False): + """Get the rows of a DataFrame sorted by the `n` largest + values of `columns`. + + .. versionadded:: 0.17.0 + + Parameters + ---------- + n : int + Number of items to retrieve + columns : list or str + Column name or names to order by + take_last : bool, optional + Where there are duplicate values, take the last duplicate + + Returns + ------- + DataFrame + + Examples + -------- + >>> df = DataFrame({'a': [1, 10, 8, 11, -1], + ... 'b': list('abdce'), + ... 'c': [1.0, 2.0, np.nan, 3.0, 4.0]}) + >>> df.nlargest(3, 'a') + a b c + 3 11 c 3 + 1 10 b 2 + 2 8 d NaN + """ + return self._nsorted(columns, n, 'nlargest', take_last) + + def nsmallest(self, n, columns, take_last=False): + """Get the rows of a DataFrame sorted by the `n` smallest + values of `columns`. + + .. versionadded:: 0.17.0 + + Parameters + ---------- + n : int + Number of items to retrieve + columns : list or str + Column name or names to order by + take_last : bool, optional + Where there are duplicate values, take the last duplicate + + Returns + ------- + DataFrame + + Examples + -------- + >>> df = DataFrame({'a': [1, 10, 8, 11, -1], + ... 'b': list('abdce'), + ... 'c': [1.0, 2.0, np.nan, 3.0, 4.0]}) + >>> df.nsmallest(3, 'a') + a b c + 4 -1 e 4 + 0 1 a 1 + 2 8 d NaN + """ + return self._nsorted(columns, n, 'nsmallest', take_last) + def swaplevel(self, i, j, axis=0): """ Swap levels i and j in a MultiIndex on a particular axis @@ -3348,7 +3495,7 @@ def combine(self, other, func, fill_value=None, overwrite=True): return self._constructor(result, index=new_index, columns=new_columns).convert_objects( - convert_dates=True, + datetime=True, copy=False) def combine_first(self, other): @@ -3466,8 +3613,9 @@ def pivot(self, index=None, columns=None, values=None): Parameters ---------- - index : string or object - Column name to use to make new frame's index + index : string or object, optional + Column name to use to make new frame's index. If None, uses + existing index. columns : string or object Column name to use to make new frame's columns values : string or object, optional @@ -3774,7 +3922,7 @@ def _apply_standard(self, func, axis, ignore_failures=False, reduce=True): dtype = object if self._is_mixed_type else None if axis == 0: - series_gen = (self.icol(i) for i in range(len(self.columns))) + series_gen = (self._ixs(i,axis=1) for i in range(len(self.columns))) res_index = self.columns res_columns = self.index elif axis == 1: @@ -3827,7 +3975,9 @@ def _apply_standard(self, func, axis, ignore_failures=False, reduce=True): if axis == 1: result = result.T - result = result.convert_objects(copy=False) + result = result.convert_objects(datetime=True, + timedelta=True, + copy=False) else: @@ -3955,7 +4105,10 @@ def append(self, other, ignore_index=False, verify_integrity=False): combined_columns = self.columns.tolist() + self.columns.union(other.index).difference(self.columns).tolist() other = other.reindex(combined_columns, copy=False) other = DataFrame(other.values.reshape((1, len(other))), - index=index, columns=combined_columns).convert_objects() + index=index, + columns=combined_columns) + other = other.convert_objects(datetime=True, timedelta=True) + if not self.columns.equals(combined_columns): self = self.reindex(columns=combined_columns) elif isinstance(other, list) and not isinstance(other[0], DataFrame): @@ -4484,7 +4637,7 @@ def quantile(self, q=0.5, axis=0, numeric_only=True): q : float or array-like, default 0.5 (50% quantile) 0 <= q <= 1, the quantile(s) to compute axis : {0, 1, 'index', 'columns'} (default 0) - 0 or 'index' for row-wise, 1 or 'columns' for column-wise + 0 or 'index' for row-wise, 1 or 'columns' for column-wise Returns @@ -4750,6 +4903,8 @@ def isin(self, values): def combineAdd(self, other): """ + DEPRECATED. Use ``DataFrame.add(other, fill_value=0.)`` instead. + Add two DataFrame objects and do not propagate NaN values, so if for a (column, time) one frame is missing a value, it will default to the other frame's value (which might @@ -4762,11 +4917,21 @@ def combineAdd(self, other): Returns ------- DataFrame + + See also + -------- + DataFrame.add + """ + warnings.warn("'combineAdd' is deprecated. Use " + "'DataFrame.add(other, fill_value=0.)' instead", + FutureWarning, stacklevel=2) return self.add(other, fill_value=0.) def combineMult(self, other): """ + DEPRECATED. Use ``DataFrame.mul(other, fill_value=1.)`` instead. + Multiply two DataFrame objects and do not propagate NaN values, so if for a (column, time) one frame is missing a value, it will default to the other frame's value (which might be NaN as well) @@ -4778,7 +4943,15 @@ def combineMult(self, other): Returns ------- DataFrame + + See also + -------- + DataFrame.mul + """ + warnings.warn("'combineMult' is deprecated. Use " + "'DataFrame.mul(other, fill_value=1.)' instead", + FutureWarning, stacklevel=2) return self.mul(other, fill_value=1.) @@ -4900,11 +5073,11 @@ def _to_arrays(data, columns, coerce_float=False, dtype=None): """ if isinstance(data, DataFrame): if columns is not None: - arrays = [data.icol(i).values for i, col in enumerate(data.columns) + arrays = [data._ixs(i,axis=1).values for i, col in enumerate(data.columns) if col in columns] else: columns = data.columns - arrays = [data.icol(i).values for i in range(len(columns))] + arrays = [data._ixs(i,axis=1).values for i in range(len(columns))] return arrays, columns diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 35db4051c60c8..0e8afbdafb866 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -80,8 +80,8 @@ class NDFrame(PandasObject): """ _internal_names = ['_data', '_cacher', '_item_cache', '_cache', 'is_copy', '_subtyp', '_index', - '_default_kind', '_default_fill_value', - '__array_struct__','__array_interface__'] + '_default_kind', '_default_fill_value', '_metadata', + '__array_struct__', '__array_interface__'] _internal_names_set = set(_internal_names) _accessors = frozenset([]) _metadata = [] @@ -138,6 +138,9 @@ def _init_mgr(self, mgr, axes=None, dtype=None, copy=False): @property def _constructor(self): + """Used when a manipulation result has the same dimesions as the + original. + """ raise AbstractMethodError(self) def __unicode__(self): @@ -153,10 +156,16 @@ def _dir_additions(self): @property def _constructor_sliced(self): + """Used when a manipulation result has one lower dimension(s) as the + original, such as DataFrame single columns slicing. + """ raise AbstractMethodError(self) @property def _constructor_expanddim(self): + """Used when a manipulation result has one higher dimension as the + original, such as Series.to_frame() and DataFrame.to_panel() + """ raise NotImplementedError #---------------------------------------------------------------------- @@ -760,7 +769,9 @@ def to_dense(self): # Picklability def __getstate__(self): - return self._data + meta = dict((k, getattr(self, k, None)) for k in self._metadata) + return dict(_data=self._data, _typ=self._typ, + _metadata=self._metadata, **meta) def __setstate__(self, state): @@ -879,7 +890,7 @@ def to_hdf(self, path_or_buf, key, **kwargs): Parameters ---------- - path_or_buf : the path (string) or buffer to put the store + path_or_buf : the path (string) or HDFStore object key : string indentifier for the group in the store mode : optional, {'a', 'w', 'r', 'r+'}, default 'a' @@ -911,6 +922,8 @@ def to_hdf(self, path_or_buf, key, **kwargs): in the store wherever possible fletcher32 : bool, default False If applying compression use the fletcher32 checksum + dropna : boolean, default False. + If true, ALL nan rows will not be written to store. """ @@ -1287,7 +1300,7 @@ def _check_setitem_copy(self, stacklevel=4, t='setting', force=False): t = ("\n" "A value is trying to be set on a copy of a slice from a " "DataFrame\n\n" - "See the the caveats in the documentation: " + "See the caveats in the documentation: " "http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy") else: @@ -1295,7 +1308,7 @@ def _check_setitem_copy(self, stacklevel=4, t='setting', force=False): "A value is trying to be set on a copy of a slice from a " "DataFrame.\n" "Try using .loc[row_indexer,col_indexer] = value instead\n\n" - "See the the caveats in the documentation: " + "See the caveats in the documentation: " "http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy") if value == 'raise': @@ -1538,7 +1551,8 @@ def select(self, crit, axis=0): return self.reindex(**{axis_name: new_axis}) - def reindex_like(self, other, method=None, copy=True, limit=None): + def reindex_like(self, other, method=None, copy=True, limit=None, + tolerance=None): """ return an object with matching indicies to myself Parameters @@ -1547,7 +1561,12 @@ def reindex_like(self, other, method=None, copy=True, limit=None): method : string or None copy : boolean, default True limit : int, default None - Maximum size gap to forward or backward fill + Maximum number of consecutive labels to fill for inexact matches. + tolerance : optional + Maximum distance between labels of the other object and this + object for inexact matches. + + .. versionadded:: 0.17.0 Notes ----- @@ -1559,7 +1578,8 @@ def reindex_like(self, other, method=None, copy=True, limit=None): reindexed : same as input """ d = other._construct_axes_dict(axes=self._AXIS_ORDERS, - method=method, copy=copy, limit=limit) + method=method, copy=copy, limit=limit, + tolerance=tolerance) return self.reindex(**d) @@ -1723,7 +1743,13 @@ def sort_index(self, axis=0, ascending=True): Value to use for missing values. Defaults to NaN, but can be any "compatible" value limit : int, default None - Maximum size gap to forward or backward fill + Maximum number of consecutive elements to forward or backward fill + tolerance : optional + Maximum distance between original and new labels for inexact + matches. The values of the index at the matching locations most + satisfy the equation ``abs(index[indexer] - target) <= tolerance``. + + .. versionadded:: 0.17.0 Examples -------- @@ -1745,6 +1771,7 @@ def reindex(self, *args, **kwargs): level = kwargs.pop('level', None) copy = kwargs.pop('copy', True) limit = kwargs.pop('limit', None) + tolerance = kwargs.pop('tolerance', None) fill_value = kwargs.pop('fill_value', np.nan) if kwargs: @@ -1769,10 +1796,11 @@ def reindex(self, *args, **kwargs): pass # perform the reindex on the axes - return self._reindex_axes(axes, level, limit, + return self._reindex_axes(axes, level, limit, tolerance, method, fill_value, copy).__finalize__(self) - def _reindex_axes(self, axes, level, limit, method, fill_value, copy): + def _reindex_axes(self, axes, level, limit, tolerance, method, + fill_value, copy): """ perform the reinxed for all the axes """ obj = self for a in self._AXIS_ORDERS: @@ -1782,7 +1810,8 @@ def _reindex_axes(self, axes, level, limit, method, fill_value, copy): ax = self._get_axis(a) new_index, indexer = ax.reindex( - labels, level=level, limit=limit, method=method) + labels, level=level, limit=limit, tolerance=tolerance, + method=method) axis = self._get_axis_number(a) obj = obj._reindex_with_indexers( @@ -1823,7 +1852,13 @@ def _reindex_multi(self, axes, copy, fill_value): Broadcast across a level, matching Index values on the passed MultiIndex level limit : int, default None - Maximum size gap to forward or backward fill + Maximum number of consecutive elements to forward or backward fill + tolerance : optional + Maximum distance between original and new labels for inexact + matches. The values of the index at the matching locations most + satisfy the equation ``abs(index[indexer] - target) <= tolerance``. + + .. versionadded:: 0.17.0 Examples -------- @@ -1928,7 +1963,7 @@ def filter(self, items=None, like=None, regex=None, axis=None): return self.select(matchf, axis=axis_name) elif regex: matcher = re.compile(regex) - return self.select(lambda x: matcher.search(x) is not None, + return self.select(lambda x: matcher.search(str(x)) is not None, axis=axis_name) else: raise TypeError('Must pass either `items`, `like`, or `regex`') @@ -1969,9 +2004,14 @@ def sample(self, n=None, frac=None, replace=False, weights=None, random_state=No Sample with or without replacement. Default = False. weights : str or ndarray-like, optional Default 'None' results in equal probability weighting. + If passed a Series, will align with target object on index. Index + values in weights not found in sampled object will be ignored and + index values in sampled object not in weights will be assigned + weights of zero. If called on a DataFrame, will accept the name of a column when axis = 0. - Weights must be same length as axis being sampled. + Unless weights are a Series, weights must be same length as axis + being sampled. If weights do not sum to 1, they will be normalized to sum to 1. Missing values in the weights column will be treated as zero. inf and -inf values not allowed. @@ -1984,7 +2024,7 @@ def sample(self, n=None, frac=None, replace=False, weights=None, random_state=No Returns ------- - Same type as caller. + A new object of same type as caller. """ if axis is None: @@ -1999,6 +2039,10 @@ def sample(self, n=None, frac=None, replace=False, weights=None, random_state=No # Check weights for compliance if weights is not None: + # If a series, align with frame + if isinstance(weights, pd.Series): + weights = weights.reindex(self.axes[axis]) + # Strings acceptable if a dataframe and axis = 0 if isinstance(weights, string_types): if isinstance(self, pd.DataFrame): @@ -2028,7 +2072,10 @@ def sample(self, n=None, frac=None, replace=False, weights=None, random_state=No # Renormalize if don't sum to 1 if weights.sum() != 1: - weights = weights / weights.sum() + if weights.sum() != 0: + weights = weights / weights.sum() + else: + raise ValueError("Invalid weights: weights sum to zero") weights = weights.values @@ -2047,7 +2094,8 @@ def sample(self, n=None, frac=None, replace=False, weights=None, random_state=No raise ValueError("A negative number of rows requested. Please provide positive value.") locs = rs.choice(axis_length, size=n, replace=replace, p=weights) - return self.take(locs, axis=axis) + return self.take(locs, axis=axis, is_copy=False) + _shared_docs['pipe'] = (""" Apply func(self, \*args, \*\*kwargs) @@ -2359,7 +2407,7 @@ def ftypes(self): return Series(self._data.get_ftypes(), index=self._info_axis, dtype=np.object_) - def as_blocks(self): + def as_blocks(self, copy=True): """ Convert the frame to a dict of dtype -> Constructor Types that each has a homogeneous dtype. @@ -2367,6 +2415,10 @@ def as_blocks(self): NOTE: the dtypes of the blocks WILL BE PRESERVED HERE (unlike in as_matrix) + Parameters + ---------- + copy : boolean, default True + Returns ------- values : a dict of dtype -> Constructor Types @@ -2381,7 +2433,7 @@ def as_blocks(self): for dtype, blocks in bd.items(): # Must combine even after consolidation, because there may be # sparse items which are never consolidated into one block. - combined = self._data.combine(blocks, copy=True) + combined = self._data.combine(blocks, copy=copy) result[dtype] = self._constructor(combined).__finalize__(self) return result @@ -2427,22 +2479,26 @@ def copy(self, deep=True): data = self._data.copy(deep=deep) return self._constructor(data).__finalize__(self) - def convert_objects(self, convert_dates=True, convert_numeric=False, - convert_timedeltas=True, copy=True): + @deprecate_kwarg(old_arg_name='convert_dates', new_arg_name='datetime') + @deprecate_kwarg(old_arg_name='convert_numeric', new_arg_name='numeric') + @deprecate_kwarg(old_arg_name='convert_timedeltas', new_arg_name='timedelta') + def convert_objects(self, datetime=False, numeric=False, + timedelta=False, coerce=False, copy=True): """ Attempt to infer better dtype for object columns Parameters ---------- - convert_dates : boolean, default True - If True, convert to date where possible. If 'coerce', force - conversion, with unconvertible values becoming NaT. - convert_numeric : boolean, default False - If True, attempt to coerce to numbers (including strings), with + datetime : boolean, default False + If True, convert to date where possible. + numeric : boolean, default False + If True, attempt to convert to numbers (including strings), with unconvertible values becoming NaN. - convert_timedeltas : boolean, default True - If True, convert to timedelta where possible. If 'coerce', force - conversion, with unconvertible values becoming NaT. + timedelta : boolean, default False + If True, convert to timedelta where possible. + coerce : boolean, default False + If True, force conversion with unconvertible values converted to + nulls (NaN or NaT) copy : boolean, default True If True, return a copy even if no copy is necessary (e.g. no conversion was done). Note: This is meant for internal use, and @@ -2453,9 +2509,10 @@ def convert_objects(self, convert_dates=True, convert_numeric=False, converted : same as input object """ return self._constructor( - self._data.convert(convert_dates=convert_dates, - convert_numeric=convert_numeric, - convert_timedeltas=convert_timedeltas, + self._data.convert(datetime=datetime, + numeric=numeric, + timedelta=timedelta, + coerce=coerce, copy=copy)).__finalize__(self) #---------------------------------------------------------------------- @@ -2853,7 +2910,7 @@ def replace(self, to_replace=None, value=None, inplace=False, limit=None, '{0!r}').format(type(to_replace).__name__) raise TypeError(msg) # pragma: no cover - new_data = new_data.convert(copy=not inplace, convert_numeric=False) + new_data = new_data.convert(copy=not inplace, numeric=False) if inplace: self._update_inplace(new_data) @@ -2865,6 +2922,9 @@ def interpolate(self, method='linear', axis=0, limit=None, inplace=False, """ Interpolate values according to different methods. + Please note that only ``method='linear'`` is supported for DataFrames/Series + with a MultiIndex. + Parameters ---------- method : {'linear', 'time', 'index', 'values', 'nearest', 'zero', @@ -2872,18 +2932,21 @@ def interpolate(self, method='linear', axis=0, limit=None, inplace=False, 'polynomial', 'spline' 'piecewise_polynomial', 'pchip'} * 'linear': ignore the index and treat the values as equally - spaced. default + spaced. This is the only method supported on MultiIndexes. + default * 'time': interpolation works on daily and higher resolution data to interpolate given length of interval * 'index', 'values': use the actual numerical values of the index * 'nearest', 'zero', 'slinear', 'quadratic', 'cubic', 'barycentric', 'polynomial' is passed to - `scipy.interpolate.interp1d` with the order given both + `scipy.interpolate.interp1d` with the order given. Both 'polynomial' and 'spline' requre that you also specify and order - (int) e.g. df.interpolate(method='polynomial', order=4) + (int) e.g. df.interpolate(method='polynomial', order=4). These + use the actual numerical values of the index * 'krogh', 'piecewise_polynomial', 'spline', and 'pchip' are all wrappers around the scipy interpolation methods of similar - names. See the scipy documentation for more on their behavior: + names. These use the actual numerical values of the index. See + the scipy documentation for more on their behavior: http://docs.scipy.org/doc/scipy/reference/interpolate.html#univariate-interpolation http://docs.scipy.org/doc/scipy/reference/tutorial/interpolate.html @@ -2896,6 +2959,7 @@ def interpolate(self, method='linear', axis=0, limit=None, inplace=False, Update the NDFrame in place if possible. downcast : optional, 'infer' or None, defaults to None Downcast dtypes if possible. + kwargs : keyword arguments to pass on to the interpolating function. Returns ------- @@ -2925,47 +2989,50 @@ def interpolate(self, method='linear', axis=0, limit=None, inplace=False, if axis == 0: ax = self._info_axis_name + _maybe_transposed_self = self elif axis == 1: - self = self.T + _maybe_transposed_self = self.T ax = 1 - ax = self._get_axis_number(ax) + else: + _maybe_transposed_self = self + ax = _maybe_transposed_self._get_axis_number(ax) - if self.ndim == 2: + if _maybe_transposed_self.ndim == 2: alt_ax = 1 - ax else: alt_ax = ax - if isinstance(self.index, MultiIndex) and method != 'linear': + if isinstance(_maybe_transposed_self.index, MultiIndex) and method != 'linear': raise ValueError("Only `method=linear` interpolation is supported " "on MultiIndexes.") - if self._data.get_dtype_counts().get('object') == len(self.T): + if _maybe_transposed_self._data.get_dtype_counts().get('object') == len(_maybe_transposed_self.T): raise TypeError("Cannot interpolate with all NaNs.") # create/use the index if method == 'linear': - index = np.arange(len(self._get_axis(alt_ax))) # prior default + index = np.arange(len(_maybe_transposed_self._get_axis(alt_ax))) # prior default else: - index = self._get_axis(alt_ax) + index = _maybe_transposed_self._get_axis(alt_ax) if pd.isnull(index).any(): raise NotImplementedError("Interpolation with NaNs in the index " "has not been implemented. Try filling " "those NaNs before interpolating.") - new_data = self._data.interpolate(method=method, - axis=ax, - index=index, - values=self, - limit=limit, - inplace=inplace, - downcast=downcast, - **kwargs) + new_data = _maybe_transposed_self._data.interpolate( + method=method, + axis=ax, + index=index, + values=_maybe_transposed_self, + limit=limit, + inplace=inplace, + downcast=downcast, + **kwargs + ) if inplace: if axis == 1: - self._update_inplace(new_data) - self = self.T - else: - self._update_inplace(new_data) + new_data = self._constructor(new_data).T._data + self._update_inplace(new_data) else: res = self._constructor(new_data).__finalize__(self) if axis == 1: @@ -3556,7 +3623,14 @@ def where(self, cond, other=np.nan, inplace=False, axis=None, level=None, except ValueError: new_other = np.array(other) - matches = (new_other == np.array(other)) + # we can end up comparing integers and m8[ns] + # which is a numpy no no + is_i8 = com.needs_i8_conversion(self.dtype) + if is_i8: + matches = False + else: + matches = (new_other == np.array(other)) + if matches is False or not matches.all(): # coerce other to a common dtype if we can @@ -3626,19 +3700,31 @@ def where(self, cond, other=np.nan, inplace=False, axis=None, level=None, else: other = self._constructor(other, **self._construct_axes_dict()) + if axis is None: + axis = 0 + + if self.ndim == getattr(other, 'ndim', 0): + align = True + else: + align = (self._get_axis_number(axis) == 1) + + block_axis = self._get_block_manager_axis(axis) + if inplace: # we may have different type blocks come out of putmask, so # reconstruct the block manager self._check_inplace_setting(other) - new_data = self._data.putmask(mask=cond, new=other, align=axis is None, - inplace=True) + new_data = self._data.putmask(mask=cond, new=other, align=align, + inplace=True, axis=block_axis, + transpose=self._AXIS_REVERSED) self._update_inplace(new_data) else: - new_data = self._data.where(other=other, cond=cond, align=axis is None, + new_data = self._data.where(other=other, cond=cond, align=align, raise_on_error=raise_on_error, - try_cast=try_cast) + try_cast=try_cast, axis=block_axis, + transpose=self._AXIS_REVERSED) return self._constructor(new_data).__finalize__(self) diff --git a/pandas/core/groupby.py b/pandas/core/groupby.py index 4abdd1112c721..d23cb39c15548 100644 --- a/pandas/core/groupby.py +++ b/pandas/core/groupby.py @@ -3,6 +3,7 @@ import numpy as np import datetime import collections +import warnings from pandas.compat import( zip, builtins, range, long, lzip, @@ -71,7 +72,7 @@ 'fillna', 'mad', 'any', 'all', - 'irow', 'take', + 'take', 'idxmax', 'idxmin', 'shift', 'tshift', 'ffill', 'bfill', @@ -111,7 +112,7 @@ def f(self): except Exception: result = self.aggregate(lambda x: npfunc(x, axis=self.axis)) if _convert: - result = result.convert_objects() + result = result.convert_objects(datetime=True) return result f.__doc__ = "Compute %s of group values" % name @@ -167,9 +168,10 @@ class Grouper(object): groupby key, which selects the grouping column of the target level : name/number, defaults to None the level for the target index - freq : string / freqency object, defaults to None + freq : string / frequency object, defaults to None This will groupby the specified frequency if the target selection (via key or level) is - a datetime-like object + a datetime-like object. For full specification of available frequencies, please see + `here `_. axis : number/name of the axis, defaults to 0 sort : boolean, default to False whether to sort the resulting labels @@ -187,11 +189,19 @@ class Grouper(object): Examples -------- - >>> df.groupby(Grouper(key='A')) : syntactic sugar for df.groupby('A') - >>> df.groupby(Grouper(key='date',freq='60s')) : specify a resample on the column 'date' - >>> df.groupby(Grouper(level='date',freq='60s',axis=1)) : - specify a resample on the level 'date' on the columns axis with a frequency of 60s + Syntactic sugar for ``df.groupby('A')`` + + >>> df.groupby(Grouper(key='A')) + + Specify a resample operation on the column 'date' + + >>> df.groupby(Grouper(key='date', freq='60s')) + + Specify a resample operation on the level 'date' on the columns axis + with a frequency of 60s + + >>> df.groupby(Grouper(level='date', freq='60s', axis=1)) """ def __new__(cls, *args, **kwargs): @@ -413,46 +423,55 @@ def indices(self): """ dict {group name -> group indices} """ return self.grouper.indices - def _get_index(self, name): - """ safe get index, translate keys for datelike to underlying repr """ + def _get_indices(self, names): + """ safe get multiple indices, translate keys for datelike to underlying repr """ - def convert(key, s): + def get_converter(s): # possibly convert to they actual key types # in the indices, could be a Timestamp or a np.datetime64 - if isinstance(s, (Timestamp,datetime.datetime)): - return Timestamp(key) + return lambda key: Timestamp(key) elif isinstance(s, np.datetime64): - return Timestamp(key).asm8 - return key + return lambda key: Timestamp(key).asm8 + else: + return lambda key: key + + if len(names) == 0: + return [] if len(self.indices) > 0: - sample = next(iter(self.indices)) + index_sample = next(iter(self.indices)) else: - sample = None # Dummy sample + index_sample = None # Dummy sample - if isinstance(sample, tuple): - if not isinstance(name, tuple): + name_sample = names[0] + if isinstance(index_sample, tuple): + if not isinstance(name_sample, tuple): msg = ("must supply a tuple to get_group with multiple" " grouping keys") raise ValueError(msg) - if not len(name) == len(sample): + if not len(name_sample) == len(index_sample): try: # If the original grouper was a tuple - return self.indices[name] + return [self.indices[name] for name in names] except KeyError: # turns out it wasn't a tuple msg = ("must supply a a same-length tuple to get_group" " with multiple grouping keys") raise ValueError(msg) - name = tuple([ convert(n, k) for n, k in zip(name,sample) ]) + converters = [get_converter(s) for s in index_sample] + names = [tuple([f(n) for f, n in zip(converters, name)]) for name in names] else: + converter = get_converter(index_sample) + names = [converter(name) for name in names] - name = convert(name, sample) + return [self.indices.get(name, []) for name in names] - return self.indices[name] + def _get_index(self, name): + """ safe get index, translate keys for datelike to underlying repr """ + return self._get_indices([name])[0] @property def name(self): @@ -498,7 +517,7 @@ def _set_result_index_ordered(self, result): # shortcut of we have an already ordered grouper if not self.grouper.is_monotonic: - index = Index(np.concatenate([ indices.get(v, []) for v in self.grouper.result_index])) + index = Index(np.concatenate(self._get_indices(self.grouper.result_index))) result.index = index result = result.sort_index() @@ -603,6 +622,9 @@ def get_group(self, name, obj=None): obj = self._selected_obj inds = self._get_index(name) + if not len(inds): + raise KeyError(name) + return obj.take(inds, axis=self.axis, convert=False) def __iter__(self): @@ -690,6 +712,16 @@ def _iterate_slices(self): def transform(self, func, *args, **kwargs): raise AbstractMethodError(self) + def irow(self, i): + """ + DEPRECATED. Use ``.nth(i)`` instead + """ + + # 10177 + warnings.warn("irow(i) is deprecated. Please use .nth(i)", + FutureWarning, stacklevel=2) + return self.nth(i) + def mean(self): """ Compute mean of groups, excluding missing values @@ -1950,7 +1982,8 @@ def __init__(self, index, grouper=None, obj=None, name=None, level=None, # fix bug #GH8868 sort=False being ignored in categorical groupby else: - self.grouper = self.grouper.reorder_categories(self.grouper.unique()) + cat = self.grouper.unique() + self.grouper = self.grouper.reorder_categories(cat.categories) # we make a CategoricalIndex out of the cat grouper # preserving the categories / ordered attributes @@ -1960,8 +1993,6 @@ def __init__(self, index, grouper=None, obj=None, name=None, level=None, self._group_index = CategoricalIndex(Categorical.from_codes(np.arange(len(c)), categories=c, ordered=self.grouper.ordered)) - if self.name is None: - self.name = self.grouper.name # a passed Grouper like elif isinstance(self.grouper, Grouper): @@ -2449,9 +2480,6 @@ def transform(self, func, *args, **kwargs): wrapper = lambda x: func(x, *args, **kwargs) for i, (name, group) in enumerate(self): - if name not in self.indices: - continue - object.__setattr__(group, 'name', name) res = wrapper(group) @@ -2466,7 +2494,7 @@ def transform(self, func, *args, **kwargs): except: pass - indexer = self.indices[name] + indexer = self._get_index(name) result[indexer] = res result = _possibly_downcast_to_dtype(result, dtype) @@ -2520,11 +2548,8 @@ def true_and_notnull(x, *args, **kwargs): return b and notnull(b) try: - indices = [] - for name, group in self: - if true_and_notnull(group) and name in self.indices: - indices.append(self.indices[name]) - + indices = [self._get_index(name) for name, group in self + if true_and_notnull(group)] except ValueError: raise TypeError("the filter must return a boolean result") except TypeError: @@ -2700,7 +2725,7 @@ def aggregate(self, arg, *args, **kwargs): self._insert_inaxis_grouper_inplace(result) result.index = np.arange(len(result)) - return result.convert_objects() + return result.convert_objects(datetime=True) def _aggregate_multiple_funcs(self, arg): from pandas.tools.merge import concat @@ -2939,18 +2964,25 @@ def _wrap_applied_output(self, keys, values, not_indexed_same=False): # if we have date/time like in the original, then coerce dates # as we are stacking can easily have object dtypes here - if (self._selected_obj.ndim == 2 - and self._selected_obj.dtypes.isin(_DATELIKE_DTYPES).any()): - cd = 'coerce' + if (self._selected_obj.ndim == 2 and + self._selected_obj.dtypes.isin(_DATELIKE_DTYPES).any()): + result = result.convert_objects(numeric=True) + date_cols = self._selected_obj.select_dtypes( + include=list(_DATELIKE_DTYPES)).columns + result[date_cols] = (result[date_cols] + .convert_objects(datetime=True, + coerce=True)) else: - cd = True - result = result.convert_objects(convert_dates=cd) + result = result.convert_objects(datetime=True) + return self._reindex_output(result) else: # only coerce dates if we find at least 1 datetime - cd = 'coerce' if any([ isinstance(v,Timestamp) for v in values ]) else False - return Series(values, index=key_index).convert_objects(convert_dates=cd) + coerce = True if any([ isinstance(v,Timestamp) for v in values ]) else False + return (Series(values, index=key_index) + .convert_objects(datetime=True, + coerce=coerce)) else: # Handle cases like BinGrouper @@ -3045,15 +3077,16 @@ def transform(self, func, *args, **kwargs): results = np.empty_like(obj.values, result.values.dtype) indices = self.indices for (name, group), (i, row) in zip(self, result.iterrows()): - if name in indices: - indexer = indices[name] + indexer = self._get_index(name) + if len(indexer) > 0: results[indexer] = np.tile(row.values,len(indexer)).reshape(len(indexer),-1) counts = self.size().fillna(0).values if any(counts == 0): results = self._try_cast(results, obj[result.columns]) - return DataFrame(results,columns=result.columns,index=obj.index).convert_objects() + return (DataFrame(results,columns=result.columns,index=obj.index) + .convert_objects(datetime=True)) def _define_paths(self, func, *args, **kwargs): if isinstance(func, compat.string_types): @@ -3146,8 +3179,8 @@ def filter(self, func, dropna=True, *args, **kwargs): # interpret the result of the filter if is_bool(res) or (lib.isscalar(res) and isnull(res)): - if res and notnull(res) and name in self.indices: - indices.append(self.indices[name]) + if res and notnull(res): + indices.append(self._get_index(name)) else: # non scalars aren't allowed raise TypeError("filter function returned a %s, " @@ -3246,7 +3279,7 @@ def _wrap_aggregated_output(self, output, names=None): if self.axis == 1: result = result.T - return self._reindex_output(result).convert_objects() + return self._reindex_output(result).convert_objects(datetime=True) def _wrap_agged_blocks(self, items, blocks): if not self.as_index: @@ -3264,7 +3297,7 @@ def _wrap_agged_blocks(self, items, blocks): if self.axis == 1: result = result.T - return self._reindex_output(result).convert_objects() + return self._reindex_output(result).convert_objects(datetime=True) def _reindex_output(self, result): """ diff --git a/pandas/core/index.py b/pandas/core/index.py index fad71c94cc417..7b5a6b199bc1b 100644 --- a/pandas/core/index.py +++ b/pandas/core/index.py @@ -16,7 +16,7 @@ from pandas.lib import Timestamp, Timedelta, is_datetime_array from pandas.core.base import PandasObject, FrozenList, FrozenNDArray, IndexOpsMixin, _shared_docs, PandasDelegate from pandas.util.decorators import (Appender, Substitution, cache_readonly, - deprecate) + deprecate, deprecate_kwarg) import pandas.core.common as com from pandas.core.common import (isnull, array_equivalent, is_dtype_equal, is_object_dtype, _values_from_object, is_float, is_integer, is_iterator, is_categorical_dtype, @@ -89,7 +89,6 @@ class Index(IndexOpsMixin, PandasObject): _left_indexer = _algos.left_join_indexer_object _inner_indexer = _algos.inner_join_indexer_object _outer_indexer = _algos.outer_join_indexer_object - _box_scalars = False _typ = 'index' @@ -105,6 +104,7 @@ class Index(IndexOpsMixin, PandasObject): _is_numeric_dtype = False _engine_type = _index.ObjectEngine + _isin_type = lib.ismember def __new__(cls, data=None, dtype=None, copy=False, name=None, fastpath=False, tupleize_cols=True, **kwargs): @@ -163,18 +163,23 @@ def __new__(cls, data=None, dtype=None, copy=False, name=None, fastpath=False, elif data is None or np.isscalar(data): cls._scalar_data_error(data) else: - if tupleize_cols and isinstance(data, list) and data: - try: - sorted(data) - has_mixed_types = False - except (TypeError, UnicodeDecodeError): - has_mixed_types = True # python3 only - if isinstance(data[0], tuple) and not has_mixed_types: + if tupleize_cols and isinstance(data, list) and data and isinstance(data[0], tuple): + + # we must be all tuples, otherwise don't construct + # 10697 + if all( isinstance(e, tuple) for e in data ): + try: + + # must be orderable in py3 + if compat.PY3: + sorted(data) return MultiIndex.from_tuples( data, names=name or kwargs.get('names')) except (TypeError, KeyError): - pass # python2 - MultiIndex fails on mixed types + # python2 - MultiIndex fails on mixed types + pass + # other iterable of some kind subarr = com._asarray_tuplesafe(data, dtype=object) @@ -203,6 +208,17 @@ def __new__(cls, data=None, dtype=None, copy=False, name=None, fastpath=False, @classmethod def _simple_new(cls, values, name=None, **kwargs): + """ + we require the we have a dtype compat for the values + if we are passed a non-dtype compat, then coerce using the constructor + + Must be careful not to recurse. + """ + if not hasattr(values, 'dtype'): + values = np.array(values,copy=False) + if is_object_dtype(values): + values = cls(values, name=name, **kwargs).values + result = object.__new__(cls) result._data = values result.name = name @@ -260,6 +276,11 @@ def dtype(self): """ return the dtype object of the underlying data """ return self._data.dtype + @cache_readonly + def dtype_str(self): + """ return the dtype str of the underlying data """ + return str(self.dtype) + @property def values(self): """ return the underlying data as an ndarray """ @@ -340,15 +361,41 @@ def view(self, cls=None): result._id = self._id return result - def _shallow_copy(self, values=None, **kwargs): - """ create a new Index, don't copy the data, use the same object attributes - with passed in attributes taking precedence """ + def _shallow_copy(self, values=None, infer=False, **kwargs): + """ + create a new Index, don't copy the data, use the same object attributes + with passed in attributes taking precedence + + *this is an internal non-public method* + + Parameters + ---------- + values : the values to create the new Index, optional + infer : boolean, default False + if True, infer the new type of the passed values + kwargs : updates the default attributes for this Index + """ if values is None: values = self.values attributes = self._get_attributes_dict() attributes.update(kwargs) + + if infer: + attributes['copy'] = False + return Index(values, **attributes) + return self.__class__._simple_new(values,**attributes) + def _coerce_scalar_to_index(self, item): + """ + we need to coerce a scalar to a compat for our index type + + Parameters + ---------- + item : scalar item to coerce + """ + return Index([item], dtype=self.dtype, **self._get_attributes_dict()) + def copy(self, names=None, name=None, dtype=None, deep=False): """ Make a copy of this object. Name and dtype sets those attributes on @@ -1054,7 +1101,7 @@ def __hash__(self): raise TypeError("unhashable type: %r" % type(self).__name__) def __setitem__(self, key, value): - raise TypeError("Indexes does not support mutable operations") + raise TypeError("Index does not support mutable operations") def __getitem__(self, key): """ @@ -1131,7 +1178,9 @@ def append(self, other): appended : Index """ to_concat, name = self._ensure_compat_append(other) - return Index(np.concatenate(to_concat), name=name) + attribs = self._get_attributes_dict() + attribs['name'] = name + return self._shallow_copy(np.concatenate(to_concat), infer=True, **attribs) @staticmethod def _ensure_compat_concat(indexes): @@ -1145,7 +1194,7 @@ def _ensure_compat_concat(indexes): return indexes - def take(self, indexer, axis=0): + def take(self, indices, axis=0): """ return a new Index of the values selected by the indexer @@ -1154,11 +1203,9 @@ def take(self, indexer, axis=0): numpy.ndarray.take """ - indexer = com._ensure_platform_int(indexer) - taken = np.array(self).take(indexer) - - # by definition cannot propogate freq - return self._shallow_copy(taken, freq=None) + indices = com._ensure_platform_int(indices) + taken = self.values.take(indices) + return self._shallow_copy(taken) def putmask(self, mask, value): """ @@ -1547,31 +1594,46 @@ def sym_diff(self, other, result_name=None): other, result_name_update = self._convert_can_do_setop(other) if result_name is None: result_name = result_name_update + the_diff = sorted(set((self.difference(other)).union(other.difference(self)))) - return Index(the_diff, name=result_name) + attribs = self._get_attributes_dict() + attribs['name'] = result_name + if 'freq' in attribs: + attribs['freq'] = None + return self._shallow_copy(the_diff, infer=True, **attribs) - def get_loc(self, key, method=None): + def get_loc(self, key, method=None, tolerance=None): """ Get integer location for requested label Parameters ---------- key : label - method : {None, 'pad'/'ffill', 'backfill'/'bfill', 'nearest'} + method : {None, 'pad'/'ffill', 'backfill'/'bfill', 'nearest'}, optional * default: exact matches only. * pad / ffill: find the PREVIOUS index value if no exact match. * backfill / bfill: use NEXT index value if no exact match * nearest: use the NEAREST index value if no exact match. Tied distances are broken by preferring the larger index value. + tolerance : optional + Maximum distance from index value for inexact matches. The value of + the index at the matching location most satisfy the equation + ``abs(index[loc] - key) <= tolerance``. + + .. versionadded:: 0.17.0 Returns ------- loc : int if unique index, possibly slice or mask if not """ if method is None: + if tolerance is not None: + raise ValueError('tolerance argument only valid if using pad, ' + 'backfill or nearest lookups') return self._engine.get_loc(_values_from_object(key)) - indexer = self.get_indexer([key], method=method) + indexer = self.get_indexer([key], method=method, + tolerance=tolerance) if indexer.ndim > 1 or indexer.size > 1: raise TypeError('get_loc requires scalar valued input') loc = indexer.item() @@ -1640,7 +1702,7 @@ def get_level_values(self, level): self._validate_index_level(level) return self - def get_indexer(self, target, method=None, limit=None): + def get_indexer(self, target, method=None, limit=None, tolerance=None): """ Compute indexer and mask for new index given the current index. The indexer should be then used as an input to ndarray.take to align the @@ -1649,15 +1711,21 @@ def get_indexer(self, target, method=None, limit=None): Parameters ---------- target : Index - method : {None, 'pad'/'ffill', 'backfill'/'bfill', 'nearest'} + method : {None, 'pad'/'ffill', 'backfill'/'bfill', 'nearest'}, optional * default: exact matches only. * pad / ffill: find the PREVIOUS index value if no exact match. * backfill / bfill: use NEXT index value if no exact match * nearest: use the NEAREST index value if no exact match. Tied distances are broken by preferring the larger index value. - limit : int - Maximum number of consecuctive labels in ``target`` to match for + limit : int, optional + Maximum number of consecutive labels in ``target`` to match for inexact matches. + tolerance : optional + Maximum distance between original and new labels for inexact + matches. The values of the index at the matching locations most + satisfy the equation ``abs(index[indexer] - target) <= tolerance``. + + .. versionadded:: 0.17.0 Examples -------- @@ -1673,36 +1741,54 @@ def get_indexer(self, target, method=None, limit=None): """ method = com._clean_reindex_fill_method(method) target = _ensure_index(target) + if tolerance is not None: + tolerance = self._convert_tolerance(tolerance) pself, ptarget = self._possibly_promote(target) if pself is not self or ptarget is not target: - return pself.get_indexer(ptarget, method=method, limit=limit) + return pself.get_indexer(ptarget, method=method, limit=limit, + tolerance=tolerance) - if not is_dtype_equal(self.dtype,target.dtype): + if not is_dtype_equal(self.dtype, target.dtype): this = self.astype(object) target = target.astype(object) - return this.get_indexer(target, method=method, limit=limit) + return this.get_indexer(target, method=method, limit=limit, + tolerance=tolerance) if not self.is_unique: raise InvalidIndexError('Reindexing only valid with uniquely' ' valued Index objects') if method == 'pad' or method == 'backfill': - indexer = self._get_fill_indexer(target, method, limit) + indexer = self._get_fill_indexer(target, method, limit, tolerance) elif method == 'nearest': - indexer = self._get_nearest_indexer(target, limit) + indexer = self._get_nearest_indexer(target, limit, tolerance) else: + if tolerance is not None: + raise ValueError('tolerance argument only valid if doing pad, ' + 'backfill or nearest reindexing') + if limit is not None: + raise ValueError('limit argument only valid if doing pad, ' + 'backfill or nearest reindexing') + indexer = self._engine.get_indexer(target.values) return com._ensure_platform_int(indexer) - def _get_fill_indexer(self, target, method, limit=None): + def _convert_tolerance(self, tolerance): + # override this method on subclasses + return tolerance + + def _get_fill_indexer(self, target, method, limit=None, tolerance=None): if self.is_monotonic_increasing and target.is_monotonic_increasing: method = (self._engine.get_pad_indexer if method == 'pad' else self._engine.get_backfill_indexer) indexer = method(target.values, limit) else: indexer = self._get_fill_indexer_searchsorted(target, method, limit) + if tolerance is not None: + indexer = self._filter_indexer_tolerance( + target.values, indexer, tolerance) return indexer def _get_fill_indexer_searchsorted(self, target, method, limit=None): @@ -1735,7 +1821,7 @@ def _get_fill_indexer_searchsorted(self, target, method, limit=None): indexer[indexer == len(self)] = -1 return indexer - def _get_nearest_indexer(self, target, limit): + def _get_nearest_indexer(self, target, limit, tolerance): """ Get the indexer for the nearest index labels; requires an index with values that can be subtracted from each other (e.g., not strings or @@ -1752,6 +1838,14 @@ def _get_nearest_indexer(self, target, limit): indexer = np.where(op(left_distances, right_distances) | (right_indexer == -1), left_indexer, right_indexer) + if tolerance is not None: + indexer = self._filter_indexer_tolerance( + target, indexer, tolerance) + return indexer + + def _filter_indexer_tolerance(self, target, indexer, tolerance): + distance = abs(self.values[indexer] - target) + indexer = np.where(distance <= tolerance, indexer, -1) return indexer def get_indexer_non_unique(self, target): @@ -1838,7 +1932,7 @@ def isin(self, values, level=None): value_set = set(values) if level is not None: self._validate_index_level(level) - return lib.ismember(np.array(self), value_set) + return self._isin_type(np.array(self), value_set) def _can_reindex(self, indexer): """ @@ -1859,7 +1953,8 @@ def _can_reindex(self, indexer): if not self.is_unique and len(indexer): raise ValueError("cannot reindex from a duplicate axis") - def reindex(self, target, method=None, level=None, limit=None): + def reindex(self, target, method=None, level=None, limit=None, + tolerance=None): """ Create index with target's values (move/add/delete values as necessary) @@ -1899,7 +1994,8 @@ def reindex(self, target, method=None, level=None, limit=None): else: if self.is_unique: indexer = self.get_indexer(target, method=method, - limit=limit) + limit=limit, + tolerance=tolerance) else: if method is not None or limit is not None: raise ValueError("cannot reindex a non-unique index " @@ -2107,6 +2203,8 @@ def _join_multi(self, other, how, return_indexers=True): if self_is_mi: self, other = other, self flip_order = True + # flip if join method is right or left + how = {'right': 'left', 'left': 'right'}.get(how, how) level = other.names.index(jl) result = self._join_level(other, level, how=how, @@ -2437,7 +2535,7 @@ def get_slice_bound(self, label, side, kind): if is_bool_dtype(slc): slc = lib.maybe_booleans_to_slice(slc.view('u1')) else: - slc = lib.maybe_indices_to_slice(slc.astype('i8')) + slc = lib.maybe_indices_to_slice(slc.astype('i8'), len(self)) if isinstance(slc, np.ndarray): raise KeyError( "Cannot get %s slice bound for non-unique label:" @@ -2526,7 +2624,8 @@ def delete(self, loc): ------- new_index : Index """ - return Index(np.delete(self._data, loc), name=self.name) + attribs = self._get_attributes_dict() + return self._shallow_copy(np.delete(self._data, loc), **attribs) def insert(self, loc, item): """ @@ -2543,10 +2642,12 @@ def insert(self, loc, item): new_index : Index """ _self = np.asarray(self) - item_idx = Index([item], dtype=self.dtype).values + item = self._coerce_scalar_to_index(item).values + idx = np.concatenate( - (_self[:loc], item_idx, _self[loc:])) - return Index(idx, name=self.name) + (_self[:loc], item, _self[loc:])) + attribs = self._get_attributes_dict() + return self._shallow_copy(idx, infer=True, **attribs) def drop(self, labels, errors='raise'): """ @@ -2571,15 +2672,15 @@ def drop(self, labels, errors='raise'): indexer = indexer[~mask] return self.delete(indexer) + @deprecate_kwarg('take_last', 'keep', mapping={True: 'last', False: 'first'}) @Appender(_shared_docs['drop_duplicates'] % _index_doc_kwargs) - def drop_duplicates(self, take_last=False): - result = super(Index, self).drop_duplicates(take_last=take_last) - return self._constructor(result) + def drop_duplicates(self, keep='first'): + return super(Index, self).drop_duplicates(keep=keep) + @deprecate_kwarg('take_last', 'keep', mapping={True: 'last', False: 'first'}) @Appender(_shared_docs['duplicated'] % _index_doc_kwargs) - def duplicated(self, take_last=False): - return super(Index, self).duplicated(take_last=take_last) - + def duplicated(self, keep='first'): + return super(Index, self).duplicated(keep=keep) def _evaluate_with_timedelta_like(self, other, op, opstr): raise TypeError("can only perform ops with timedelta like values") @@ -2594,6 +2695,9 @@ def _add_comparison_methods(cls): def _make_compare(op): def _evaluate_compare(self, other): + if isinstance(other, (np.ndarray, Index, ABCSeries)): + if other.ndim > 0 and len(self) != len(other): + raise ValueError('Lengths must match to compare') func = getattr(self.values, op) result = func(np.asarray(other)) @@ -2806,7 +2910,7 @@ class CategoricalIndex(Index, PandasDelegate): _typ = 'categoricalindex' _engine_type = _index.Int64Engine - _attributes = ['name','categories','ordered'] + _attributes = ['name'] def __new__(cls, data=None, categories=None, ordered=None, dtype=None, copy=False, name=None, fastpath=False, **kwargs): @@ -2941,6 +3045,10 @@ def equals(self, other): return False + @property + def _formatter_func(self): + return self.categories._formatter_func + def _format_attrs(self): """ Return a list of tuples of the (attr,formatted_value) @@ -3003,10 +3111,11 @@ def _engine(self): def is_unique(self): return not self.duplicated().any() + @deprecate_kwarg('take_last', 'keep', mapping={True: 'last', False: 'first'}) @Appender(_shared_docs['duplicated'] % _index_doc_kwargs) - def duplicated(self, take_last=False): + def duplicated(self, keep='first'): from pandas.hashtable import duplicated_int64 - return duplicated_int64(self.codes.astype('i8'), take_last) + return duplicated_int64(self.codes.astype('i8'), keep) def get_loc(self, key, method=None): """ @@ -3035,7 +3144,8 @@ def _can_reindex(self, indexer): """ always allow reindexing """ pass - def reindex(self, target, method=None, level=None, limit=None): + def reindex(self, target, method=None, level=None, limit=None, + tolerance=None): """ Create index with target's values (move/add/delete values as necessary) @@ -3104,7 +3214,7 @@ def _reindex_non_unique(self, target): return new_target, indexer, new_indexer - def get_indexer(self, target, method=None, limit=None): + def get_indexer(self, target, method=None, limit=None, tolerance=None): """ Compute indexer and mask for new index given the current index. The indexer should be then used as an input to ndarray.take to align the @@ -3258,8 +3368,12 @@ def _evaluate_compare(self, other): elif isinstance(other, Index): other = self._create_categorical(self, other.values, categories=self.categories, ordered=self.ordered) + if isinstance(other, (ABCCategorical, np.ndarray, ABCSeries)): + if len(self.values) != len(other): + raise ValueError("Lengths must match to compare") + if isinstance(other, ABCCategorical): - if not (self.values.is_dtype_equal(other) and len(self.values) == len(other)): + if not self.values.is_dtype_equal(other): raise TypeError("categorical index comparisions must have the same categories and ordered attributes") return getattr(self.values, op)(other) @@ -3349,6 +3463,14 @@ def _maybe_cast_slice_bound(self, label, side, kind): return label + def _convert_tolerance(self, tolerance): + try: + return float(tolerance) + except ValueError: + raise ValueError('tolerance argument for %s must be numeric: %r' + % (type(self).__name__, tolerance)) + + class Int64Index(NumericIndex): """ @@ -3381,6 +3503,7 @@ class Int64Index(NumericIndex): _outer_indexer = _algos.outer_join_indexer_int64 _engine_type = _index.Int64Engine + _isin_type = lib.ismember_int64 def __new__(cls, data=None, dtype=None, copy=False, name=None, fastpath=False, **kwargs): @@ -3604,7 +3727,7 @@ def __contains__(self, other): except: return False - def get_loc(self, key, method=None): + def get_loc(self, key, method=None, tolerance=None): try: if np.all(np.isnan(key)): nan_idxs = self._nan_idxs @@ -3616,7 +3739,8 @@ def get_loc(self, key, method=None): return nan_idxs except (TypeError, NotImplementedError): pass - return super(Float64Index, self).get_loc(key, method=method) + return super(Float64Index, self).get_loc(key, method=method, + tolerance=tolerance) @property def is_all_dates(self): @@ -3671,7 +3795,7 @@ class MultiIndex(Index): Level of sortedness (must be lexicographically sorted by that level) names : optional sequence of objects - Names for each of the index levels. + Names for each of the index levels. (name is accepted for compat) copy : boolean, default False Copy the meta-data verify_integrity : boolean, default True @@ -3687,8 +3811,11 @@ class MultiIndex(Index): rename = Index.set_names def __new__(cls, levels=None, labels=None, sortorder=None, names=None, - copy=False, verify_integrity=True, _set_identity=True, **kwargs): + copy=False, verify_integrity=True, _set_identity=True, name=None, **kwargs): + # compat with Index + if name is not None: + names = name if levels is None or labels is None: raise TypeError("Must pass both levels and labels") if len(levels) != len(labels): @@ -3997,7 +4124,12 @@ def view(self, cls=None): result._id = self._id return result - _shallow_copy = view + def _shallow_copy(self, values=None, infer=False, **kwargs): + if values is not None: + if 'name' in kwargs: + kwargs['names'] = kwargs.pop('name',None) + return MultiIndex.from_tuples(values, **kwargs) + return self.view() @cache_readonly def dtype(self): @@ -4153,15 +4285,16 @@ def _has_complex_internals(self): def is_unique(self): return not self.duplicated().any() + @deprecate_kwarg('take_last', 'keep', mapping={True: 'last', False: 'first'}) @Appender(_shared_docs['duplicated'] % _index_doc_kwargs) - def duplicated(self, take_last=False): + def duplicated(self, keep='first'): from pandas.core.groupby import get_group_index from pandas.hashtable import duplicated_int64 shape = map(len, self.levels) ids = get_group_index(self.labels, shape, sort=False, xnull=False) - return duplicated_int64(ids, take_last) + return duplicated_int64(ids, keep) def get_value(self, series, key): # somewhat broken encapsulation @@ -4411,7 +4544,7 @@ def from_arrays(cls, arrays, sortorder=None, names=None): levels = [c.categories for c in cats] labels = [c.codes for c in cats] if names is None: - names = [c.name for c in cats] + names = [getattr(arr, "name", None) for arr in arrays] return MultiIndex(levels=levels, labels=labels, sortorder=sortorder, names=names, @@ -4829,7 +4962,7 @@ def sortlevel(self, level=0, ascending=True, sort_remaining=True): return new_index, indexer - def get_indexer(self, target, method=None, limit=None): + def get_indexer(self, target, method=None, limit=None, tolerance=None): """ Compute indexer and mask for new index given the current index. The indexer should be then used as an input to ndarray.take to align the @@ -4875,6 +5008,9 @@ def get_indexer(self, target, method=None, limit=None): self_index = self._tuple_index if method == 'pad' or method == 'backfill': + if tolerance is not None: + raise NotImplementedError("tolerance not implemented yet " + 'for MultiIndex') indexer = self_index._get_fill_indexer(target, method, limit) elif method == 'nearest': raise NotImplementedError("method='nearest' not implemented yet " @@ -4884,7 +5020,8 @@ def get_indexer(self, target, method=None, limit=None): return com._ensure_platform_int(indexer) - def reindex(self, target, method=None, level=None, limit=None): + def reindex(self, target, method=None, level=None, limit=None, + tolerance=None): """ Create index with target's values (move/add/delete values as necessary) @@ -4923,7 +5060,8 @@ def reindex(self, target, method=None, level=None, limit=None): else: if self.is_unique: indexer = self.get_indexer(target, method=method, - limit=limit) + limit=limit, + tolerance=tolerance) else: raise Exception( "cannot handle a non-unique multi-index!") @@ -5042,7 +5180,7 @@ def _maybe_to_slice(loc): if not isinstance(loc, np.ndarray) or loc.dtype != 'int64': return loc - loc = lib.maybe_indices_to_slice(loc) + loc = lib.maybe_indices_to_slice(loc, len(self)) if isinstance(loc, slice): return loc @@ -5237,13 +5375,40 @@ def partial_selection(key, indexer=None): indexer = self._get_level_indexer(key, level=level) return indexer, maybe_droplevels(indexer, [level], drop_level) - def _get_level_indexer(self, key, level=0): - # return a boolean indexer or a slice showing where the key is + def _get_level_indexer(self, key, level=0, indexer=None): + # return an indexer, boolean array or a slice showing where the key is # in the totality of values + # if the indexer is provided, then use this level_index = self.levels[level] labels = self.labels[level] + def convert_indexer(start, stop, step, indexer=indexer, labels=labels): + # given the inputs and the labels/indexer, compute an indexer set + # if we have a provided indexer, then this need not consider + # the entire labels set + + r = np.arange(start,stop,step) + if indexer is not None and len(indexer) != len(labels): + + # we have an indexer which maps the locations in the labels that we + # have already selected (and is not an indexer for the entire set) + # otherwise this is wasteful + # so we only need to examine locations that are in this set + # the only magic here is that the result are the mappings to the + # set that we have selected + from pandas import Series + mapper = Series(indexer) + indexer = labels.take(com._ensure_platform_int(indexer)) + result = Series(Index(indexer).isin(r).nonzero()[0]) + m = result.map(mapper).values + + else: + m = np.zeros(len(labels),dtype=bool) + m[np.in1d(labels,r,assume_unique=True)] = True + + return m + if isinstance(key, slice): # handle a slice, returnig a slice if we can # otherwise a boolean indexer @@ -5269,17 +5434,13 @@ def _get_level_indexer(self, key, level=0): # a partial date slicer on a DatetimeIndex generates a slice # note that the stop ALREADY includes the stopped point (if # it was a string sliced) - m = np.zeros(len(labels),dtype=bool) - m[np.in1d(labels,np.arange(start.start,stop.stop,step))] = True - return m + return convert_indexer(start.start,stop.stop,step) elif level > 0 or self.lexsort_depth == 0 or step is not None: # need to have like semantics here to right # searching as when we are using a slice # so include the stop+1 (so we include stop) - m = np.zeros(len(labels),dtype=bool) - m[np.in1d(labels,np.arange(start,stop+1,step))] = True - return m + return convert_indexer(start,stop+1,step) else: # sorted, so can return slice object -> view i = labels.searchsorted(start, side='left') @@ -5317,59 +5478,73 @@ def get_locs(self, tup): raise KeyError('MultiIndex Slicing requires the index to be fully lexsorted' ' tuple len ({0}), lexsort depth ({1})'.format(len(tup), self.lexsort_depth)) - def _convert_indexer(r): + # indexer + # this is the list of all values that we want to select + n = len(self) + indexer = None + + def _convert_to_indexer(r): + # return an indexer if isinstance(r, slice): - m = np.zeros(len(self),dtype=bool) + m = np.zeros(n,dtype=bool) m[r] = True - return m - return r + r = m.nonzero()[0] + elif is_bool_indexer(r): + if len(r) != n: + raise ValueError("cannot index with a boolean indexer that is" + " not the same length as the index") + r = r.nonzero()[0] + return Int64Index(r) + + def _update_indexer(idxr, indexer=indexer): + if indexer is None: + indexer = Index(np.arange(n)) + if idxr is None: + return indexer + return indexer & idxr - ranges = [] for i,k in enumerate(tup): if is_bool_indexer(k): # a boolean indexer, must be the same length! k = np.asarray(k) - if len(k) != len(self): - raise ValueError("cannot index with a boolean indexer that is" - " not the same length as the index") - ranges.append(k) + indexer = _update_indexer(_convert_to_indexer(k), indexer=indexer) + elif is_list_like(k): # a collection of labels to include from this level (these are or'd) - indexers = [] + indexers = None for x in k: try: - indexers.append(_convert_indexer(self._get_level_indexer(x, level=i))) + idxrs = _convert_to_indexer(self._get_level_indexer(x, level=i, indexer=indexer)) + indexers = idxrs if indexers is None else indexers | idxrs except (KeyError): # ignore not founds continue - if len(k): - ranges.append(reduce(np.logical_or, indexers)) + + if indexers is not None: + indexer = _update_indexer(indexers, indexer=indexer) else: - ranges.append(np.zeros(self.labels[i].shape, dtype=bool)) + + # no matches we are done + return Int64Index([]).values elif is_null_slice(k): # empty slice - pass + indexer = _update_indexer(None, indexer=indexer) elif isinstance(k,slice): # a slice, include BOTH of the labels - ranges.append(self._get_level_indexer(k,level=i)) + indexer = _update_indexer(_convert_to_indexer(self._get_level_indexer(k,level=i,indexer=indexer)), indexer=indexer) else: # a single label - ranges.append(self.get_loc_level(k,level=i,drop_level=False)[0]) - - # identity - if len(ranges) == 0: - return slice(0,len(self)) - - elif len(ranges) == 1: - return ranges[0] + indexer = _update_indexer(_convert_to_indexer(self.get_loc_level(k,level=i,drop_level=False)[0]), indexer=indexer) - # construct a boolean indexer if we have a slice or boolean indexer - return reduce(np.logical_and,[ _convert_indexer(r) for r in ranges ]) + # empty indexer + if indexer is None: + return Int64Index([]).values + return indexer.values def truncate(self, before=None, after=None): """ diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index 02309e6e4e3b5..b8ee831cdc12c 100644 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -6,7 +6,7 @@ import pandas.core.common as com from pandas.core.common import (is_bool_indexer, is_integer_dtype, _asarray_tuplesafe, is_list_like, isnull, - is_null_slice, + is_null_slice, is_full_slice, ABCSeries, ABCDataFrame, ABCPanel, is_float, _values_from_object, _infer_fill_value, is_integer) import numpy as np @@ -201,6 +201,7 @@ def _setitem_with_indexer(self, indexer, value): # also has the side effect of consolidating in-place from pandas import Panel, DataFrame, Series + info_axis = self.obj._info_axis_number # maybe partial set take_split_path = self.obj._is_mixed_type @@ -213,6 +214,16 @@ def _setitem_with_indexer(self, indexer, value): val = list(value.values()) if isinstance(value,dict) else value take_split_path = not blk._can_hold_element(val) + if isinstance(indexer, tuple) and len(indexer) == len(self.obj.axes): + + for i, ax in zip(indexer, self.obj.axes): + + # if we have any multi-indexes that have non-trivial slices (not null slices) + # then we must take the split path, xref GH 10360 + if isinstance(ax, MultiIndex) and not (is_integer(i) or is_null_slice(i)): + take_split_path = True + break + if isinstance(indexer, tuple): nindexer = [] for i, idx in enumerate(indexer): @@ -328,14 +339,8 @@ def _setitem_with_indexer(self, indexer, value): return self.obj.__setitem__(indexer, value) # set - info_axis = self.obj._info_axis_number item_labels = self.obj._get_axis(info_axis) - # if we have a complicated setup, take the split path - if (isinstance(indexer, tuple) and - any([isinstance(ax, MultiIndex) for ax in self.obj.axes])): - take_split_path = True - # align and set the values if take_split_path: @@ -399,10 +404,10 @@ def setter(item, v): pi = plane_indexer[0] if lplane_indexer == 1 else plane_indexer # perform the equivalent of a setitem on the info axis - # as we have a null slice which means essentially reassign to the columns - # of a multi-dim object - # GH6149 - if isinstance(pi, tuple) and all(is_null_slice(idx) for idx in pi): + # as we have a null slice or a slice with full bounds + # which means essentially reassign to the columns of a multi-dim object + # GH6149 (null slice), GH10408 (full bounds) + if isinstance(pi, tuple) and all(is_null_slice(idx) or is_full_slice(idx, len(self.obj)) for idx in pi): s = v else: # set the item, possibly having a dtype change @@ -431,8 +436,8 @@ def can_do_equal_len(): return False - # we need an interable, with a ndim of at least 1 - # eg. don't pass thru np.array(0) + # we need an iterable, with a ndim of at least 1 + # eg. don't pass through np.array(0) if is_list_like_indexer(value) and getattr(value,'ndim',1) > 0: # we have an equal len Frame @@ -509,7 +514,7 @@ def can_do_equal_len(): def _align_series(self, indexer, ser): # indexer to assign Series can be tuple, slice, scalar - if isinstance(indexer, (slice, np.ndarray, list)): + if isinstance(indexer, (slice, np.ndarray, list, Index)): indexer = tuple([indexer]) if isinstance(indexer, tuple): @@ -1388,7 +1393,8 @@ def _is_valid_integer(self, key, axis): # return a boolean if we have a valid integer indexer ax = self.obj._get_axis(axis) - if key > len(ax): + l = len(ax) + if key >= l or key < -l: raise IndexError("single positional indexer is out-of-bounds") return True @@ -1400,7 +1406,7 @@ def _is_valid_list_like(self, key, axis): arr = np.array(key) ax = self.obj._get_axis(axis) l = len(ax) - if len(arr) and (arr.max() >= l or arr.min() <= -l): + if len(arr) and (arr.max() >= l or arr.min() < -l): raise IndexError("positional indexers are out-of-bounds") return True @@ -1719,7 +1725,7 @@ def maybe_convert_ix(*args): ixify = True for arg in args: - if not isinstance(arg, (np.ndarray, list, ABCSeries)): + if not isinstance(arg, (np.ndarray, list, ABCSeries, Index)): ixify = False if ixify: diff --git a/pandas/core/internals.py b/pandas/core/internals.py index 7d83e45098ae1..1d6269ae904d2 100644 --- a/pandas/core/internals.py +++ b/pandas/core/internals.py @@ -2,7 +2,7 @@ import itertools import re import operator -from datetime import datetime, timedelta +from datetime import datetime, timedelta, date from collections import defaultdict import numpy as np @@ -14,7 +14,7 @@ is_null_datelike_scalar, _maybe_promote, is_timedelta64_dtype, is_datetime64_dtype, array_equivalent, _maybe_convert_string_to_object, - is_categorical) + is_categorical, needs_i8_conversion, is_datetimelike_v_numeric) from pandas.core.index import Index, MultiIndex, _ensure_index from pandas.core.indexing import maybe_convert_indices, length_of_indexer from pandas.core.categorical import Categorical, maybe_to_categorical @@ -622,7 +622,7 @@ def _is_empty_indexer(indexer): # may have to soft convert_objects here if block.is_object and not self.is_object: - block = block.convert(convert_numeric=False) + block = block.convert(numeric=False) return block except (ValueError, TypeError) as detail: @@ -632,7 +632,8 @@ def _is_empty_indexer(indexer): return [self] - def putmask(self, mask, new, align=True, inplace=False): + def putmask(self, mask, new, align=True, inplace=False, + axis=0, transpose=False): """ putmask the data to the block; it is possible that we may create a new dtype of block @@ -644,37 +645,57 @@ def putmask(self, mask, new, align=True, inplace=False): new : a ndarray/object align : boolean, perform alignment on other/cond, default is True inplace : perform inplace modification, default is False + axis : int + transpose : boolean + Set to True if self is stored with axes reversed Returns ------- - a new block(s), the result of the putmask + a list of new blocks, the result of the putmask """ new_values = self.values if inplace else self.values.copy() - # may need to align the new if hasattr(new, 'reindex_axis'): - new = new.values.T + new = new.values - # may need to align the mask if hasattr(mask, 'reindex_axis'): - mask = mask.values.T + mask = mask.values # if we are passed a scalar None, convert it here if not is_list_like(new) and isnull(new) and not self.is_object: new = self.fill_value if self._can_hold_element(new): + if transpose: + new_values = new_values.T + new = self._try_cast(new) - # pseudo-broadcast - if isinstance(new, np.ndarray) and new.ndim == self.ndim - 1: - new = np.repeat(new, self.shape[-1]).reshape(self.shape) + # If the default repeat behavior in np.putmask would go in the wrong + # direction, then explictly repeat and reshape new instead + if getattr(new, 'ndim', 0) >= 1: + if self.ndim - 1 == new.ndim and axis == 1: + new = np.repeat(new, new_values.shape[-1]).reshape( + self.shape) + new = new.astype(new_values.dtype) np.putmask(new_values, mask, new) # maybe upcast me elif mask.any(): + if transpose: + mask = mask.T + if isinstance(new, np.ndarray): + new = new.T + axis = new_values.ndim - axis - 1 + + # Pseudo-broadcast + if getattr(new, 'ndim', 0) >= 1: + if self.ndim - 1 == new.ndim: + new_shape = list(new.shape) + new_shape.insert(axis, 1) + new = new.reshape(tuple(new_shape)) # need to go column by column new_blocks = [] @@ -685,14 +706,15 @@ def putmask(self, mask, new, align=True, inplace=False): # need a new block if m.any(): - - n = new[i] if isinstance( - new, np.ndarray) else np.array(new) + if isinstance(new, np.ndarray): + n = np.squeeze(new[i % new.shape[0]]) + else: + n = np.array(new) # type of the new block dtype, _ = com._maybe_promote(n.dtype) - # we need to exiplicty astype here to make a copy + # we need to explicitly astype here to make a copy n = n.astype(dtype) nv = _putmask_smart(v, m, n) @@ -718,8 +740,10 @@ def putmask(self, mask, new, align=True, inplace=False): if inplace: return [self] - return [make_block(new_values, - placement=self.mgr_locs, fastpath=True)] + if transpose: + new_values = new_values.T + + return [make_block(new_values, placement=self.mgr_locs, fastpath=True)] def interpolate(self, method='pad', axis=0, index=None, values=None, inplace=False, limit=None, @@ -1003,7 +1027,7 @@ def handle_error(): fastpath=True, placement=self.mgr_locs)] def where(self, other, cond, align=True, raise_on_error=True, - try_cast=False): + try_cast=False, axis=0, transpose=False): """ evaluate the block; return result block(s) from the result @@ -1014,6 +1038,9 @@ def where(self, other, cond, align=True, raise_on_error=True, align : boolean, perform alignment on other/cond raise_on_error : if True, raise when I can't perform the function, False by default (and just return the data that we had coming in) + axis : int + transpose : boolean + Set to True if self is stored with axes reversed Returns ------- @@ -1021,43 +1048,23 @@ def where(self, other, cond, align=True, raise_on_error=True, """ values = self.values + if transpose: + values = values.T - # see if we can align other if hasattr(other, 'reindex_axis'): other = other.values - # make sure that we can broadcast - is_transposed = False - if hasattr(other, 'ndim') and hasattr(values, 'ndim'): - if values.ndim != other.ndim or values.shape == other.shape[::-1]: - - # if its symmetric are ok, no reshaping needed (GH 7506) - if (values.shape[0] == np.array(values.shape)).all(): - pass - - # pseodo broadcast (its a 2d vs 1d say and where needs it in a - # specific direction) - elif (other.ndim >= 1 and values.ndim - 1 == other.ndim and - values.shape[0] != other.shape[0]): - other = _block_shape(other).T - else: - values = values.T - is_transposed = True - - # see if we can align cond - if not hasattr(cond, 'shape'): - raise ValueError( - "where must have a condition that is ndarray like") - if hasattr(cond, 'reindex_axis'): cond = cond.values - # may need to undo transpose of values - if hasattr(values, 'ndim'): - if values.ndim != cond.ndim or values.shape == cond.shape[::-1]: + # If the default broadcasting would go in the wrong direction, then + # explictly reshape other instead + if getattr(other, 'ndim', 0) >= 1: + if values.ndim - 1 == other.ndim and axis == 1: + other = other.reshape(tuple(other.shape + (1,))) - values = values.T - is_transposed = not is_transposed + if not hasattr(cond, 'shape'): + raise ValueError("where must have a condition that is ndarray like") other = _maybe_convert_string_to_object(other) @@ -1090,15 +1097,14 @@ def func(c, v, o): raise TypeError('Could not compare [%s] with block values' % repr(other)) - if is_transposed: + if transpose: result = result.T # try to cast if requested if try_cast: result = self._try_cast_result(result) - return make_block(result, - ndim=self.ndim, placement=self.mgr_locs) + return make_block(result, ndim=self.ndim, placement=self.mgr_locs) # might need to separate out blocks axis = cond.ndim - 1 @@ -1455,7 +1461,7 @@ def is_bool(self): """ return lib.is_bool_array(self.values.ravel()) - def convert(self, convert_dates=True, convert_numeric=True, convert_timedeltas=True, + def convert(self, datetime=True, numeric=True, timedelta=True, coerce=False, copy=True, by_item=True): """ attempt to coerce any object types to better types return a copy of the block (if copy = True) @@ -1472,9 +1478,12 @@ def convert(self, convert_dates=True, convert_numeric=True, convert_timedeltas=T values = self.iget(i) values = com._possibly_convert_objects( - values.ravel(), convert_dates=convert_dates, - convert_numeric=convert_numeric, - convert_timedeltas=convert_timedeltas, + values.ravel(), + datetime=datetime, + numeric=numeric, + timedelta=timedelta, + coerce=coerce, + copy=copy ).reshape(values.shape) values = _block_shape(values, ndim=self.ndim) newb = make_block(values, @@ -1484,8 +1493,12 @@ def convert(self, convert_dates=True, convert_numeric=True, convert_timedeltas=T else: values = com._possibly_convert_objects( - self.values.ravel(), convert_dates=convert_dates, - convert_numeric=convert_numeric + self.values.ravel(), + datetime=datetime, + numeric=numeric, + timedelta=timedelta, + coerce=coerce, + copy=copy ).reshape(self.values.shape) blocks.append(make_block(values, ndim=self.ndim, placement=self.mgr_locs)) @@ -1529,8 +1542,8 @@ def _maybe_downcast(self, blocks, downcast=None): # split and convert the blocks result_blocks = [] for blk in blocks: - result_blocks.extend(blk.convert(convert_dates=True, - convert_numeric=False)) + result_blocks.extend(blk.convert(datetime=True, + numeric=False)) return result_blocks def _can_hold_element(self, element): @@ -1670,6 +1683,9 @@ def is_view(self): def to_dense(self): return self.values.to_dense().view() + def convert(self, copy=True, **kwargs): + return [self.copy() if copy else self] + @property def shape(self): return (len(self.mgr_locs), len(self.values)) @@ -1706,6 +1722,10 @@ def interpolate(self, method='pad', axis=0, inplace=False, limit=limit), placement=self.mgr_locs) + def shift(self, periods, axis=0): + return self.make_block_same_class(values=self.values.shift(periods), + placement=self.mgr_locs) + def take_nd(self, indexer, axis=0, new_mgr_locs=None, fill_tuple=None): """ Take values according to indexer and return them as a block.bb @@ -1730,7 +1750,8 @@ def take_nd(self, indexer, axis=0, new_mgr_locs=None, fill_tuple=None): return self.make_block_same_class(new_values, new_mgr_locs) - def putmask(self, mask, new, align=True, inplace=False): + def putmask(self, mask, new, align=True, inplace=False, + axis=0, transpose=False): """ putmask the data to the block; it is possible that we may create a new dtype of block @@ -1825,7 +1846,7 @@ def _try_coerce_args(self, values, other): if is_null_datelike_scalar(other): other = tslib.iNaT - elif isinstance(other, datetime): + elif isinstance(other, (datetime, np.datetime64, date)): other = lib.Timestamp(other).asm8.view('i8') elif hasattr(other, 'dtype') and com.is_integer_dtype(other): other = other.view('i8') @@ -2107,7 +2128,7 @@ def make_block(values, placement, klass=None, ndim=None, class BlockManager(PandasObject): """ - Core internal data structure to implement DataFrame + Core internal data structure to implement DataFrame, Series, Panel, etc. Manage a bunch of labeled 2D mixed-type ndarrays. Essentially it's a lightweight blocked set of labeled data to be manipulated by the DataFrame @@ -2422,12 +2443,18 @@ def apply(self, f, axes=None, filter=None, do_integrity_check=False, **kwargs): else: kwargs['filter'] = filter_locs - if f == 'where' and kwargs.get('align', True): + if f == 'where': align_copy = True - align_keys = ['other', 'cond'] - elif f == 'putmask' and kwargs.get('align', True): + if kwargs.get('align', True): + align_keys = ['other', 'cond'] + else: + align_keys = ['cond'] + elif f == 'putmask': align_copy = False - align_keys = ['new', 'mask'] + if kwargs.get('align', True): + align_keys = ['new', 'mask'] + else: + align_keys = ['mask'] elif f == 'eval': align_copy = False align_keys = ['other'] @@ -3875,9 +3902,16 @@ def _vstack(to_stack, dtype): def _possibly_compare(a, b, op): - res = op(a, b) + is_a_array = isinstance(a, np.ndarray) is_b_array = isinstance(b, np.ndarray) + + # numpy deprecation warning to have i8 vs integer comparisions + if is_datetimelike_v_numeric(a, b): + res = False + else: + res = op(a, b) + if np.isscalar(res) and (is_a_array or is_b_array): type_names = [type(a).__name__, type(b).__name__] @@ -4130,7 +4164,7 @@ def get_empty_dtype_and_na(join_units): else: return np.dtype(np.bool_), None elif 'category' in upcast_classes: - return com.CategoricalDtype(), np.nan + return np.dtype(np.object_), np.nan elif 'float' in upcast_classes: return np.dtype(np.float64), np.nan elif 'datetime' in upcast_classes: @@ -4378,7 +4412,11 @@ def is_null(self): # Usually it's enough to check but a small fraction of values to see if # a block is NOT null, chunks should help in such cases. 1000 value # was chosen rather arbitrarily. - values_flat = self.block.values.ravel() + values = self.block.values + if self.block.is_categorical: + values_flat = values.categories + else: + values_flat = values.ravel() total_len = values_flat.shape[0] chunk_len = max(total_len // 40, 1000) for i in range(0, total_len, chunk_len): diff --git a/pandas/core/ops.py b/pandas/core/ops.py index 0b62eb1e53ddb..8e3dd3836855c 100644 --- a/pandas/core/ops.py +++ b/pandas/core/ops.py @@ -6,6 +6,7 @@ # necessary to enforce truediv in Python 2.X from __future__ import division import operator +import warnings import numpy as np import pandas as pd from pandas import compat, lib, tslib @@ -13,9 +14,15 @@ from pandas.util.decorators import Appender import pandas.core.common as com import pandas.computation.expressions as expressions -from pandas.core.common import(bind_method, is_list_like, notnull, isnull, - _values_from_object, _maybe_match_name) - +from pandas.lib import isscalar +from pandas.tslib import iNaT +from pandas.compat import bind_method +from pandas.core.common import(is_list_like, notnull, isnull, + _values_from_object, _maybe_match_name, + needs_i8_conversion, is_datetimelike_v_numeric, + is_integer_dtype, is_categorical_dtype, is_object_dtype, + is_timedelta64_dtype, is_datetime64_dtype, is_bool_dtype) +from pandas.io.common import PerformanceWarning # ----------------------------------------------------------------------------- # Functions that add arithmetic methods to objects, given arithmetic factory # methods @@ -257,7 +264,7 @@ class _TimeOp(object): Generally, you should use classmethod ``maybe_convert_for_time_op`` as an entry point. """ - fill_value = tslib.iNaT + fill_value = iNaT wrap_results = staticmethod(lambda x: x) dtype = None @@ -270,14 +277,18 @@ def __init__(self, left, right, name): self.left = left self.right = right - lvalues = self._convert_to_array(left, name=name) - rvalues = self._convert_to_array(right, name=name, other=lvalues) - self.is_timedelta_lhs = com.is_timedelta64_dtype(left) - self.is_datetime_lhs = com.is_datetime64_dtype(left) + self.is_offset_lhs = self._is_offset(left) + self.is_offset_rhs = self._is_offset(right) + + lvalues = self._convert_to_array(left, name=name) + self.is_timedelta_lhs = is_timedelta64_dtype(left) + self.is_datetime_lhs = is_datetime64_dtype(left) self.is_integer_lhs = left.dtype.kind in ['i', 'u'] - self.is_datetime_rhs = com.is_datetime64_dtype(rvalues) - self.is_timedelta_rhs = com.is_timedelta64_dtype(rvalues) + + rvalues = self._convert_to_array(right, name=name, other=lvalues) + self.is_datetime_rhs = is_datetime64_dtype(rvalues) + self.is_timedelta_rhs = is_timedelta64_dtype(rvalues) self.is_integer_rhs = rvalues.dtype.kind in ('i', 'u') self._validate() @@ -303,7 +314,10 @@ def _validate(self): " passed" % self.name) # 2 timedeltas - elif self.is_timedelta_lhs and self.is_timedelta_rhs: + elif ((self.is_timedelta_lhs and + (self.is_timedelta_rhs or self.is_offset_rhs)) or + (self.is_timedelta_rhs and + (self.is_timedelta_lhs or self.is_offset_lhs))): if self.name not in ('__div__', '__truediv__', '__add__', '__sub__'): @@ -311,19 +325,21 @@ def _validate(self): "addition, subtraction, and division, but the" " operator [%s] was passed" % self.name) - # datetime and timedelta - elif self.is_datetime_lhs and self.is_timedelta_rhs: + # datetime and timedelta/DateOffset + elif (self.is_datetime_lhs and + (self.is_timedelta_rhs or self.is_offset_rhs)): if self.name not in ('__add__', '__sub__'): raise TypeError("can only operate on a datetime with a rhs of" - " a timedelta for addition and subtraction, " + " a timedelta/DateOffset for addition and subtraction," " but the operator [%s] was passed" % self.name) - elif self.is_timedelta_lhs and self.is_datetime_rhs: + elif ((self.is_timedelta_lhs or self.is_offset_lhs) + and self.is_datetime_rhs): if self.name != '__add__': - raise TypeError("can only operate on a timedelta and" + raise TypeError("can only operate on a timedelta/DateOffset and" " a datetime for addition, but the operator" " [%s] was passed" % self.name) else: @@ -335,7 +351,6 @@ def _convert_to_array(self, values, name=None, other=None): """converts values to ndarray""" from pandas.tseries.timedeltas import to_timedelta - coerce = True if not is_list_like(values): values = np.array([values]) inferred_type = lib.infer_dtype(values) @@ -346,17 +361,17 @@ def _convert_to_array(self, values, name=None, other=None): if (other is not None and other.dtype == 'timedelta64[ns]' and all(isnull(v) for v in values)): values = np.empty(values.shape, dtype=other.dtype) - values[:] = tslib.iNaT + values[:] = iNaT # a datelike elif isinstance(values, pd.DatetimeIndex): values = values.to_series() elif not (isinstance(values, (np.ndarray, pd.Series)) and - com.is_datetime64_dtype(values)): + is_datetime64_dtype(values)): values = tslib.array_to_datetime(values) elif inferred_type in ('timedelta', 'timedelta64'): # have a timedelta, convert to to ns here - values = to_timedelta(values, coerce=coerce) + values = to_timedelta(values, errors='coerce') elif inferred_type == 'integer': # py3 compat where dtype is 'm' but is an integer if values.dtype.kind == 'm': @@ -366,26 +381,17 @@ def _convert_to_array(self, values, name=None, other=None): elif name not in ('__truediv__', '__div__', '__mul__'): raise TypeError("incompatible type for a datetime/timedelta " "operation [{0}]".format(name)) - elif isinstance(values[0], pd.DateOffset): - # handle DateOffsets - os = np.array([getattr(v, 'delta', None) for v in values]) - mask = isnull(os) - if mask.any(): - raise TypeError("cannot use a non-absolute DateOffset in " - "datetime/timedelta operations [{0}]".format( - ', '.join([com.pprint_thing(v) - for v in values[mask]]))) - values = to_timedelta(os, coerce=coerce) elif inferred_type == 'floating': - # all nan, so ok, use the other dtype (e.g. timedelta or datetime) if isnull(values).all(): values = np.empty(values.shape, dtype=other.dtype) - values[:] = tslib.iNaT + values[:] = iNaT else: raise TypeError( 'incompatible type [{0}] for a datetime/timedelta ' 'operation'.format(np.array(values).dtype)) + elif self._is_offset(values): + return values else: raise TypeError("incompatible type [{0}] for a datetime/timedelta" " operation".format(np.array(values).dtype)) @@ -393,6 +399,7 @@ def _convert_to_array(self, values, name=None, other=None): return values def _convert_for_datetime(self, lvalues, rvalues): + from pandas.tseries.timedeltas import to_timedelta mask = None # datetimes require views if self.is_datetime_lhs or self.is_datetime_rhs: @@ -402,13 +409,40 @@ def _convert_for_datetime(self, lvalues, rvalues): else: self.dtype = 'datetime64[ns]' mask = isnull(lvalues) | isnull(rvalues) - lvalues = lvalues.view(np.int64) - rvalues = rvalues.view(np.int64) + + # if adding single offset try vectorized path + # in DatetimeIndex; otherwise elementwise apply + if self.is_offset_lhs: + if len(lvalues) == 1: + rvalues = pd.DatetimeIndex(rvalues) + lvalues = lvalues[0] + else: + warnings.warn("Adding/subtracting array of DateOffsets to Series not vectorized", + PerformanceWarning) + rvalues = rvalues.astype('O') + elif self.is_offset_rhs: + if len(rvalues) == 1: + lvalues = pd.DatetimeIndex(lvalues) + rvalues = rvalues[0] + else: + warnings.warn("Adding/subtracting array of DateOffsets to Series not vectorized", + PerformanceWarning) + lvalues = lvalues.astype('O') + else: + lvalues = lvalues.view(np.int64) + rvalues = rvalues.view(np.int64) # otherwise it's a timedelta else: self.dtype = 'timedelta64[ns]' mask = isnull(lvalues) | isnull(rvalues) + + # convert Tick DateOffset to underlying delta + if self.is_offset_lhs: + lvalues = to_timedelta(lvalues) + if self.is_offset_rhs: + rvalues = to_timedelta(rvalues) + lvalues = lvalues.astype(np.int64) rvalues = rvalues.astype(np.int64) @@ -434,6 +468,16 @@ def f(x): self.lvalues = lvalues self.rvalues = rvalues + + def _is_offset(self, arr_or_obj): + """ check if obj or all elements of list-like is DateOffset """ + if isinstance(arr_or_obj, pd.DateOffset): + return True + elif is_list_like(arr_or_obj): + return all(isinstance(x, pd.DateOffset) for x in arr_or_obj) + else: + return False + @classmethod def maybe_convert_for_time_op(cls, left, right, name): """ @@ -445,8 +489,8 @@ def maybe_convert_for_time_op(cls, left, right, name): that the data is not the right type for time ops. """ # decide if we can do it - is_timedelta_lhs = com.is_timedelta64_dtype(left) - is_datetime_lhs = com.is_datetime64_dtype(left) + is_timedelta_lhs = is_timedelta64_dtype(left) + is_datetime_lhs = is_datetime64_dtype(left) if not (is_datetime_lhs or is_timedelta_lhs): return None @@ -527,8 +571,8 @@ def wrapper(left, right, name=name): name=name, dtype=dtype) else: # scalars - if hasattr(lvalues, 'values'): - lvalues = lvalues.values + if hasattr(lvalues, 'values') and not isinstance(lvalues, pd.DatetimeIndex): + lvalues = lvalues.values return left._constructor(wrap_results(na_op(lvalues, rvalues)), index=left.index, name=left.name, dtype=dtype) @@ -544,17 +588,17 @@ def na_op(x, y): # dispatch to the categorical if we have a categorical # in either operand - if com.is_categorical_dtype(x): + if is_categorical_dtype(x): return op(x,y) - elif com.is_categorical_dtype(y) and not lib.isscalar(y): + elif is_categorical_dtype(y) and not isscalar(y): return op(y,x) - if x.dtype == np.object_: + if is_object_dtype(x.dtype): if isinstance(y, list): y = lib.list_to_object_array(y) if isinstance(y, (np.ndarray, pd.Series)): - if y.dtype != np.object_: + if not is_object_dtype(y.dtype): result = lib.vec_compare(x, y.astype(np.object_), op) else: result = lib.vec_compare(x, y, op) @@ -562,13 +606,44 @@ def na_op(x, y): result = lib.scalar_compare(x, y, op) else: + # we want to compare like types + # we only want to convert to integer like if + # we are not NotImplemented, otherwise + # we would allow datetime64 (but viewed as i8) against + # integer comparisons + if is_datetimelike_v_numeric(x, y): + raise TypeError("invalid type comparison") + + # numpy does not like comparisons vs None + if isscalar(y) and isnull(y): + y = np.nan + + # we have a datetime/timedelta and may need to convert + mask = None + if needs_i8_conversion(x) or (not isscalar(y) and needs_i8_conversion(y)): + + if isscalar(y): + y = _index.convert_scalar(x,_values_from_object(y)) + else: + y = y.view('i8') + + if name == '__ne__': + mask = notnull(x) + else: + mask = isnull(x) + + x = x.view('i8') + try: result = getattr(x, name)(y) if result is NotImplemented: raise TypeError("invalid type comparison") - except (AttributeError): + except AttributeError: result = op(x, y) + if mask is not None and mask.any(): + result[mask] = False + return result def wrapper(self, other, axis=None): @@ -590,29 +665,24 @@ def wrapper(self, other, axis=None): return self._constructor(na_op(self.values, np.asarray(other)), index=self.index).__finalize__(self) elif isinstance(other, pd.Categorical): - if not com.is_categorical_dtype(self): + if not is_categorical_dtype(self): msg = "Cannot compare a Categorical for op {op} with Series of dtype {typ}.\n"\ "If you want to compare values, use 'series np.asarray(other)'." raise TypeError(msg.format(op=op,typ=self.dtype)) - mask = isnull(self) - - if com.is_categorical_dtype(self): + if is_categorical_dtype(self): # cats are a special case as get_values() would return an ndarray, which would then # not take categories ordering into account # we can go directly to op, as the na_op would just test again and dispatch to it. res = op(self.values, other) else: values = self.get_values() - other = _index.convert_scalar(values,_values_from_object(other)) + if is_list_like(other): + other = np.asarray(other) - if issubclass(values.dtype.type, (np.datetime64, np.timedelta64)): - values = values.view('i8') - - # scalars res = na_op(values, other) - if np.isscalar(res): + if isscalar(res): raise TypeError('Could not compare %s type with Series' % type(other)) @@ -621,11 +691,6 @@ def wrapper(self, other, axis=None): res = pd.Series(res, index=self.index, name=self.name, dtype='bool') - - # mask out the invalids - if mask.any(): - res[mask] = masker - return res return wrapper @@ -643,8 +708,7 @@ def na_op(x, y): y = lib.list_to_object_array(y) if isinstance(y, (np.ndarray, pd.Series)): - if (x.dtype == np.bool_ and - y.dtype == np.bool_): # pragma: no cover + if (is_bool_dtype(x.dtype) and is_bool_dtype(y.dtype)): result = op(x, y) # when would this be hit? else: x = com._ensure_object(x) @@ -665,7 +729,7 @@ def na_op(x, y): return result def wrapper(self, other): - is_self_int_dtype = com.is_integer_dtype(self.dtype) + is_self_int_dtype = is_integer_dtype(self.dtype) fill_int = lambda x: x.fillna(0) fill_bool = lambda x: x.fillna(False).astype(bool) @@ -673,7 +737,7 @@ def wrapper(self, other): if isinstance(other, pd.Series): name = _maybe_match_name(self, other) other = other.reindex_like(self) - is_other_int_dtype = com.is_integer_dtype(other.dtype) + is_other_int_dtype = is_integer_dtype(other.dtype) other = fill_int(other) if is_other_int_dtype else fill_bool(other) filler = fill_int if is_self_int_dtype and is_other_int_dtype else fill_bool @@ -686,7 +750,7 @@ def wrapper(self, other): else: # scalars, list, tuple, np.array - filler = fill_int if is_self_int_dtype and com.is_integer_dtype(np.asarray(other)) else fill_bool + filler = fill_int if is_self_int_dtype and is_integer_dtype(np.asarray(other)) else fill_bool return filler(self._constructor(na_op(self.values, other), index=self.index)).__finalize__(self) @@ -1046,7 +1110,7 @@ def na_op(x, y): # work only for scalars def f(self, other): - if not np.isscalar(other): + if not isscalar(other): raise ValueError('Simple arithmetic with %s can only be ' 'done with scalar values' % self._constructor.__name__) diff --git a/pandas/core/panel4d.py b/pandas/core/panel4d.py index 3d480464388c8..7fafbd0eaa2b5 100644 --- a/pandas/core/panel4d.py +++ b/pandas/core/panel4d.py @@ -12,7 +12,9 @@ aliases={'major': 'major_axis', 'minor': 'minor_axis'}, stat_axis=2, ns=dict(__doc__=""" - Represents a 4 dimensional structured + Panel4D is a 4-Dimensional named container very much like a Panel, but + having 4 named dimensions. It is intended as a test bed for more + N-Dimensional named containers. Parameters ---------- diff --git a/pandas/core/reshape.py b/pandas/core/reshape.py index fd786fa30f842..fecfe5cd82c6d 100644 --- a/pandas/core/reshape.py +++ b/pandas/core/reshape.py @@ -319,11 +319,17 @@ def pivot(self, index=None, columns=None, values=None): See DataFrame.pivot """ if values is None: - indexed = self.set_index([index, columns]) + cols = [columns] if index is None else [index, columns] + append = index is None + indexed = self.set_index(cols, append=append) return indexed.unstack(columns) else: + if index is None: + index = self.index + else: + index = self[index] indexed = Series(self[values].values, - index=MultiIndex.from_arrays([self[index], + index=MultiIndex.from_arrays([index, self[columns]])) return indexed.unstack(columns) @@ -455,6 +461,12 @@ def stack(frame, level=-1, dropna=True): ------- stacked : Series """ + def factorize(index): + if index.is_unique: + return index, np.arange(len(index)) + cat = Categorical(index, ordered=True) + return cat.categories, cat.codes + N, K = frame.shape if isinstance(frame.columns, MultiIndex): if frame.columns._reference_duplicate_name(level): @@ -469,20 +481,22 @@ def stack(frame, level=-1, dropna=True): return _stack_multi_columns(frame, level_num=level_num, dropna=dropna) elif isinstance(frame.index, MultiIndex): new_levels = list(frame.index.levels) - new_levels.append(frame.columns) - new_labels = [lab.repeat(K) for lab in frame.index.labels] - new_labels.append(np.tile(np.arange(K), N).ravel()) + + clev, clab = factorize(frame.columns) + new_levels.append(clev) + new_labels.append(np.tile(clab, N).ravel()) new_names = list(frame.index.names) new_names.append(frame.columns.name) new_index = MultiIndex(levels=new_levels, labels=new_labels, names=new_names, verify_integrity=False) else: - ilabels = np.arange(N).repeat(K) - clabels = np.tile(np.arange(K), N).ravel() - new_index = MultiIndex(levels=[frame.index, frame.columns], - labels=[ilabels, clabels], + levels, (ilab, clab) = \ + zip(*map(factorize, (frame.index, frame.columns))) + labels = ilab.repeat(K), np.tile(clab, N).ravel() + new_index = MultiIndex(levels=levels, + labels=labels, names=[frame.index.name, frame.columns.name], verify_integrity=False) @@ -957,13 +971,15 @@ def get_dummies(data, prefix=None, prefix_sep='_', dummy_na=False, If `columns` is None then all the columns with `object` or `category` dtype will be converted. sparse : bool, default False - Whether the returned DataFrame should be sparse or not. + Whether the dummy columns should be sparse or not. Returns + SparseDataFrame if `data` is a Series or if all columns are included. + Otherwise returns a DataFrame with some SparseBlocks. .. versionadded:: 0.16.1 Returns ------- - dummies : DataFrame + dummies : DataFrame or SparseDataFrame Examples -------- @@ -1042,8 +1058,11 @@ def check_len(item, name): elif isinstance(prefix_sep, dict): prefix_sep = [prefix_sep[col] for col in columns_to_encode] - result = data.drop(columns_to_encode, axis=1) - with_dummies = [result] + if set(columns_to_encode) == set(data.columns): + with_dummies = [] + else: + with_dummies = [data.drop(columns_to_encode, axis=1)] + for (col, pre, sep) in zip(columns_to_encode, prefix, prefix_sep): dummy = _get_dummies_1d(data[col], prefix=pre, prefix_sep=sep, diff --git a/pandas/core/series.py b/pandas/core/series.py index dfbc5dbf84572..87fde996aaa67 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -19,6 +19,7 @@ is_list_like, _values_from_object, _possibly_cast_to_datetime, _possibly_castable, _possibly_convert_platform, _try_sort, + is_int64_dtype, ABCSparseArray, _maybe_match_name, _coerce_to_dtype, SettingWithCopyError, _maybe_box_datetimelike, ABCDataFrame, @@ -45,7 +46,7 @@ import pandas.core.datetools as datetools import pandas.core.format as fmt import pandas.core.nanops as nanops -from pandas.util.decorators import Appender, cache_readonly +from pandas.util.decorators import Appender, cache_readonly, deprecate_kwarg import pandas.lib as lib import pandas.tslib as tslib @@ -188,8 +189,6 @@ def __init__(self, data=None, index=None, dtype=None, name=None, elif isinstance(data, Categorical): if dtype is not None: raise ValueError("cannot specify a dtype with a Categorical") - if name is None: - name = data.name elif (isinstance(data, types.GeneratorType) or (compat.PY3 and isinstance(data, map))): data = list(data) @@ -437,10 +436,6 @@ def imag(self, v): __long__ = _coerce_method(int) __int__ = _coerce_method(int) - # we are preserving name here - def __getstate__(self): - return dict(_data=self._data, name=self.name) - def _unpickle_series_compat(self, state): if isinstance(state, dict): self._data = state['_data'] @@ -786,9 +781,30 @@ def reshape(self, *args, **kwargs): return self.values.reshape(shape, **kwargs) - iget_value = _ixs - iget = _ixs - irow = _ixs + def iget_value(self, i, axis=0): + """ + DEPRECATED. Use ``.iloc[i]`` or ``.iat[i]`` instead + """ + warnings.warn("iget_value(i) is deprecated. Please use .iloc[i] or .iat[i]", + FutureWarning, stacklevel=2) + return self._ixs(i) + + def iget(self, i, axis=0): + """ + DEPRECATED. Use ``.iloc[i]`` or ``.iat[i]`` instead + """ + + warnings.warn("iget(i) is deprecated. Please use .iloc[i]", + FutureWarning, stacklevel=2) + return self._ixs(i) + + def irow(self, i, axis=0): + """ + DEPRECATED. Use ``.iloc[i]`` or ``.iat[i]`` instead + """ + warnings.warn("irow(i) is deprecated. Please use .iloc[i] or iat[i]", + FutureWarning, stacklevel=2) + return self._ixs(i) def get_value(self, label, takeable=False): """ @@ -1139,14 +1155,15 @@ def mode(self): from pandas.core.algorithms import mode return mode(self) + @deprecate_kwarg('take_last', 'keep', mapping={True: 'last', False: 'first'}) @Appender(base._shared_docs['drop_duplicates'] % _shared_doc_kwargs) - def drop_duplicates(self, take_last=False, inplace=False): - return super(Series, self).drop_duplicates(take_last=take_last, - inplace=inplace) + def drop_duplicates(self, keep='first', inplace=False): + return super(Series, self).drop_duplicates(keep=keep, inplace=inplace) + @deprecate_kwarg('take_last', 'keep', mapping={True: 'last', False: 'first'}) @Appender(base._shared_docs['duplicated'] % _shared_doc_kwargs) - def duplicated(self, take_last=False): - return super(Series, self).duplicated(take_last=take_last) + def duplicated(self, keep='first'): + return super(Series, self).duplicated(keep=keep) def idxmin(self, axis=None, out=None, skipna=True): """ @@ -2250,17 +2267,22 @@ def isin(self, values): # may need i8 conversion for proper membership testing comps = _values_from_object(self) + f = lib.ismember if com.is_datetime64_dtype(self): from pandas.tseries.tools import to_datetime values = Series(to_datetime(values)).values.view('i8') comps = comps.view('i8') + f = lib.ismember_int64 elif com.is_timedelta64_dtype(self): from pandas.tseries.timedeltas import to_timedelta values = Series(to_timedelta(values)).values.view('i8') comps = comps.view('i8') + f = lib.ismember_int64 + elif is_int64_dtype(self): + f = lib.ismember_int64 value_set = set(values) - result = lib.ismember(comps, value_set) + result = f(comps, value_set) return self._constructor(result, index=self.index).__finalize__(self) def between(self, left, right, inclusive=True): @@ -2323,8 +2345,10 @@ def from_csv(cls, path, sep=',', parse_dates=True, header=None, sep=sep, parse_dates=parse_dates, encoding=encoding, infer_datetime_format=infer_datetime_format) - result = df.icol(0) - result.index.name = result.name = None + result = df.iloc[:,0] + if header is None: + result.index.name = result.name = None + return result def to_csv(self, path, index=True, sep=",", na_rep='', diff --git a/pandas/core/strings.py b/pandas/core/strings.py index db14e2b487415..7837fb60da9d6 100644 --- a/pandas/core/strings.py +++ b/pandas/core/strings.py @@ -193,7 +193,7 @@ def str_contains(arr, pat, case=True, flags=0, na=np.nan, regex=True): See Also -------- - match : analagous, but stricter, relying on re.match instead of re.search + match : analogous, but stricter, relying on re.match instead of re.search """ if regex: @@ -1270,11 +1270,11 @@ def pad(self, width, side='left', fillchar=' '): def center(self, width, fillchar=' '): return self.pad(width, side='both', fillchar=fillchar) - @Appender(_shared_docs['str_pad'] % dict(side='right', method='right')) + @Appender(_shared_docs['str_pad'] % dict(side='right', method='ljust')) def ljust(self, width, fillchar=' '): return self.pad(width, side='right', fillchar=fillchar) - @Appender(_shared_docs['str_pad'] % dict(side='left', method='left')) + @Appender(_shared_docs['str_pad'] % dict(side='left', method='rjust')) def rjust(self, width, fillchar=' '): return self.pad(width, side='left', fillchar=fillchar) diff --git a/pandas/hashtable.pyx b/pandas/hashtable.pyx index c4cd788216018..dfa7930ada62f 100644 --- a/pandas/hashtable.pyx +++ b/pandas/hashtable.pyx @@ -1,14 +1,19 @@ +# cython: profile=False + from cpython cimport PyObject, Py_INCREF, PyList_Check, PyTuple_Check from khash cimport * from numpy cimport * +from cpython cimport PyMem_Malloc, PyMem_Realloc, PyMem_Free from util cimport _checknan cimport util import numpy as np +nan = np.nan -ONAN = np.nan +cdef extern from "numpy/npy_math.h": + double NAN "NPY_NAN" cimport cython cimport numpy as cnp @@ -28,33 +33,14 @@ PyDateTime_IMPORT cdef extern from "Python.h": int PySlice_Check(object) - -def list_to_object_array(list obj): - ''' - Convert list to object ndarray. Seriously can't believe I had to write this - function - ''' - cdef: - Py_ssize_t i, n - ndarray[object] arr - - n = len(obj) - arr = np.empty(n, dtype=object) - - for i from 0 <= i < n: - arr[i] = obj[i] - - return arr - - cdef size_t _INIT_VEC_CAP = 32 cdef class ObjectVector: cdef: + PyObject **data size_t n, m ndarray ao - PyObject **data def __cinit__(self): self.n = 0 @@ -65,11 +51,6 @@ cdef class ObjectVector: def __len__(self): return self.n - def to_array(self): - self.ao.resize(self.n) - self.m = self.n - return self.ao - cdef inline append(self, object o): if self.n == self.m: self.m = max(self.m * 2, _INIT_VEC_CAP) @@ -80,72 +61,120 @@ cdef class ObjectVector: self.data[self.n] = o self.n += 1 + def to_array(self): + self.ao.resize(self.n) + self.m = self.n + return self.ao + +ctypedef struct Int64VectorData: + int64_t *data + size_t n, m + +ctypedef struct Float64VectorData: + float64_t *data + size_t n, m + +ctypedef fused vector_data: + Int64VectorData + Float64VectorData + +ctypedef fused sixty_four_bit_scalar: + int64_t + float64_t + +cdef bint needs_resize(vector_data *data) nogil: + return data.n == data.m + +cdef void append_data(vector_data *data, sixty_four_bit_scalar x) nogil: + + # compile time specilization of the fused types + # as the cross-product is generated, but we cannot assign float->int + # the types that don't pass are pruned + if (vector_data is Int64VectorData and sixty_four_bit_scalar is int64_t) or ( + vector_data is Float64VectorData and sixty_four_bit_scalar is float64_t): + + data.data[data.n] = x + data.n += 1 cdef class Int64Vector: cdef: - size_t n, m + Int64VectorData *data ndarray ao - int64_t *data def __cinit__(self): - self.n = 0 - self.m = _INIT_VEC_CAP - self.ao = np.empty(_INIT_VEC_CAP, dtype=np.int64) - self.data = self.ao.data + self.data = PyMem_Malloc(sizeof(Int64VectorData)) + if not self.data: + raise MemoryError() + self.data.n = 0 + self.data.m = _INIT_VEC_CAP + self.ao = np.empty(self.data.m, dtype=np.int64) + self.data.data = self.ao.data + + cdef resize(self): + self.data.m = max(self.data.m * 4, _INIT_VEC_CAP) + self.ao.resize(self.data.m) + self.data.data = self.ao.data + + def __dealloc__(self): + PyMem_Free(self.data) def __len__(self): - return self.n + return self.data.n def to_array(self): - self.ao.resize(self.n) - self.m = self.n + self.ao.resize(self.data.n) + self.data.m = self.data.n return self.ao - cdef inline append(self, int64_t x): - if self.n == self.m: - self.m = max(self.m * 2, _INIT_VEC_CAP) - self.ao.resize(self.m) - self.data = self.ao.data + cdef inline void append(self, int64_t x): - self.data[self.n] = x - self.n += 1 + if needs_resize(self.data): + self.resize() + + append_data(self.data, x) cdef class Float64Vector: cdef: - size_t n, m + Float64VectorData *data ndarray ao - float64_t *data def __cinit__(self): - self.n = 0 - self.m = _INIT_VEC_CAP - self.ao = np.empty(_INIT_VEC_CAP, dtype=np.float64) - self.data = self.ao.data + self.data = PyMem_Malloc(sizeof(Float64VectorData)) + if not self.data: + raise MemoryError() + self.data.n = 0 + self.data.m = _INIT_VEC_CAP + self.ao = np.empty(self.data.m, dtype=np.float64) + self.data.data = self.ao.data + + cdef resize(self): + self.data.m = max(self.data.m * 4, _INIT_VEC_CAP) + self.ao.resize(self.data.m) + self.data.data = self.ao.data + + def __dealloc__(self): + PyMem_Free(self.data) def __len__(self): - return self.n + return self.data.n def to_array(self): - self.ao.resize(self.n) - self.m = self.n + self.ao.resize(self.data.n) + self.data.m = self.data.n return self.ao - cdef inline append(self, float64_t x): - if self.n == self.m: - self.m = max(self.m * 2, _INIT_VEC_CAP) - self.ao.resize(self.m) - self.data = self.ao.data + cdef inline void append(self, float64_t x): - self.data[self.n] = x - self.n += 1 + if needs_resize(self.data): + self.resize() + append_data(self.data, x) cdef class HashTable: pass - cdef class StringHashTable(HashTable): cdef kh_str_t *table @@ -157,9 +186,6 @@ cdef class StringHashTable(HashTable): def __dealloc__(self): kh_destroy_str(self.table) - cdef inline int check_type(self, object val): - return util.is_string_object(val) - cpdef get_item(self, object val): cdef khiter_t k k = kh_get_str(self.table, util.get_c_string(val)) @@ -256,111 +282,16 @@ cdef class StringHashTable(HashTable): return reverse, labels -cdef class Int32HashTable(HashTable): - cdef kh_int32_t *table - - def __init__(self, size_hint=1): - if size_hint is not None: - kh_resize_int32(self.table, size_hint) - - def __cinit__(self): - self.table = kh_init_int32() - - def __dealloc__(self): - kh_destroy_int32(self.table) - - cdef inline int check_type(self, object val): - return util.is_string_object(val) - - cpdef get_item(self, int32_t val): - cdef khiter_t k - k = kh_get_int32(self.table, val) - if k != self.table.n_buckets: - return self.table.vals[k] - else: - raise KeyError(val) - - def get_iter_test(self, int32_t key, Py_ssize_t iterations): - cdef Py_ssize_t i, val=0 - for i in range(iterations): - k = kh_get_int32(self.table, val) - if k != self.table.n_buckets: - val = self.table.vals[k] - - cpdef set_item(self, int32_t key, Py_ssize_t val): - cdef: - khiter_t k - int ret = 0 - - k = kh_put_int32(self.table, key, &ret) - self.table.keys[k] = key - if kh_exist_int32(self.table, k): - self.table.vals[k] = val - else: - raise KeyError(key) - - def map_locations(self, ndarray[int32_t] values): - cdef: - Py_ssize_t i, n = len(values) - int ret = 0 - int32_t val - khiter_t k - - for i in range(n): - val = values[i] - k = kh_put_int32(self.table, val, &ret) - self.table.vals[k] = i - - def lookup(self, ndarray[int32_t] values): - cdef: - Py_ssize_t i, n = len(values) - int32_t val - khiter_t k - ndarray[int32_t] locs = np.empty(n, dtype=np.int64) - - for i in range(n): - val = values[i] - k = kh_get_int32(self.table, val) - if k != self.table.n_buckets: - locs[i] = self.table.vals[k] - else: - locs[i] = -1 - - return locs - - def factorize(self, ndarray[int32_t] values): - cdef: - Py_ssize_t i, n = len(values) - ndarray[int64_t] labels = np.empty(n, dtype=np.int64) - dict reverse = {} - Py_ssize_t idx, count = 0 - int ret = 0 - int32_t val - khiter_t k - - for i in range(n): - val = values[i] - k = kh_get_int32(self.table, val) - if k != self.table.n_buckets: - idx = self.table.vals[k] - labels[i] = idx - else: - k = kh_put_int32(self.table, val, &ret) - self.table.vals[k] = count - reverse[count] = val - labels[i] = count - count += 1 - - return reverse, labels - -cdef class Int64HashTable: #(HashTable): - # cdef kh_int64_t *table +cdef class Int64HashTable(HashTable): def __cinit__(self, size_hint=1): self.table = kh_init_int64() if size_hint is not None: kh_resize_int64(self.table, size_hint) + def __len__(self): + return self.table.size + def __dealloc__(self): kh_destroy_int64(self.table) @@ -369,9 +300,6 @@ cdef class Int64HashTable: #(HashTable): k = kh_get_int64(self.table, key) return k != self.table.n_buckets - def __len__(self): - return self.table.size - cpdef get_item(self, int64_t val): cdef khiter_t k k = kh_get_int64(self.table, val) @@ -399,137 +327,166 @@ cdef class Int64HashTable: #(HashTable): else: raise KeyError(key) - def map(self, ndarray[int64_t] keys, ndarray[int64_t] values): + @cython.boundscheck(False) + def map(self, int64_t[:] keys, int64_t[:] values): cdef: Py_ssize_t i, n = len(values) int ret = 0 int64_t key khiter_t k - for i in range(n): - key = keys[i] - k = kh_put_int64(self.table, key, &ret) - self.table.vals[k] = values[i] + with nogil: + for i in range(n): + key = keys[i] + k = kh_put_int64(self.table, key, &ret) + self.table.vals[k] = values[i] - def map_locations(self, ndarray[int64_t] values): + @cython.boundscheck(False) + def map_locations(self, int64_t[:] values): cdef: Py_ssize_t i, n = len(values) int ret = 0 int64_t val khiter_t k - for i in range(n): - val = values[i] - k = kh_put_int64(self.table, val, &ret) - self.table.vals[k] = i + with nogil: + for i in range(n): + val = values[i] + k = kh_put_int64(self.table, val, &ret) + self.table.vals[k] = i - def lookup(self, ndarray[int64_t] values): + @cython.boundscheck(False) + def lookup(self, int64_t[:] values): cdef: Py_ssize_t i, n = len(values) int ret = 0 int64_t val khiter_t k - ndarray[int64_t] locs = np.empty(n, dtype=np.int64) + int64_t[:] locs = np.empty(n, dtype=np.int64) - for i in range(n): - val = values[i] - k = kh_get_int64(self.table, val) - if k != self.table.n_buckets: - locs[i] = self.table.vals[k] - else: - locs[i] = -1 + with nogil: + for i in range(n): + val = values[i] + k = kh_get_int64(self.table, val) + if k != self.table.n_buckets: + locs[i] = self.table.vals[k] + else: + locs[i] = -1 - return locs + return np.asarray(locs) def factorize(self, ndarray[object] values): reverse = {} labels = self.get_labels(values, reverse, 0) return reverse, labels - def get_labels(self, ndarray[int64_t] values, Int64Vector uniques, + @cython.boundscheck(False) + def get_labels(self, int64_t[:] values, Int64Vector uniques, Py_ssize_t count_prior, Py_ssize_t na_sentinel): cdef: Py_ssize_t i, n = len(values) - ndarray[int64_t] labels + int64_t[:] labels Py_ssize_t idx, count = count_prior int ret = 0 int64_t val khiter_t k + Int64VectorData *ud labels = np.empty(n, dtype=np.int64) - - for i in range(n): - val = values[i] - k = kh_get_int64(self.table, val) - if k != self.table.n_buckets: - idx = self.table.vals[k] - labels[i] = idx - else: - k = kh_put_int64(self.table, val, &ret) - self.table.vals[k] = count - uniques.append(val) - labels[i] = count - count += 1 - - return labels - - def get_labels_groupby(self, ndarray[int64_t] values): + ud = uniques.data + + with nogil: + for i in range(n): + val = values[i] + k = kh_get_int64(self.table, val) + if k != self.table.n_buckets: + idx = self.table.vals[k] + labels[i] = idx + else: + k = kh_put_int64(self.table, val, &ret) + self.table.vals[k] = count + + if needs_resize(ud): + with gil: + uniques.resize() + append_data(ud, val) + labels[i] = count + count += 1 + + return np.asarray(labels) + + @cython.boundscheck(False) + def get_labels_groupby(self, int64_t[:] values): cdef: Py_ssize_t i, n = len(values) - ndarray[int64_t] labels + int64_t[:] labels Py_ssize_t idx, count = 0 int ret = 0 int64_t val khiter_t k Int64Vector uniques = Int64Vector() + Int64VectorData *ud labels = np.empty(n, dtype=np.int64) - - for i in range(n): - val = values[i] - - # specific for groupby - if val < 0: - labels[i] = -1 - continue - - k = kh_get_int64(self.table, val) - if k != self.table.n_buckets: - idx = self.table.vals[k] - labels[i] = idx - else: - k = kh_put_int64(self.table, val, &ret) - self.table.vals[k] = count - uniques.append(val) - labels[i] = count - count += 1 + ud = uniques.data + + with nogil: + for i in range(n): + val = values[i] + + # specific for groupby + if val < 0: + labels[i] = -1 + continue + + k = kh_get_int64(self.table, val) + if k != self.table.n_buckets: + idx = self.table.vals[k] + labels[i] = idx + else: + k = kh_put_int64(self.table, val, &ret) + self.table.vals[k] = count + + if needs_resize(ud): + with gil: + uniques.resize() + append_data(ud, val) + labels[i] = count + count += 1 arr_uniques = uniques.to_array() - return labels, arr_uniques + return np.asarray(labels), arr_uniques - def unique(self, ndarray[int64_t] values): + @cython.boundscheck(False) + def unique(self, int64_t[:] values): cdef: Py_ssize_t i, n = len(values) int ret = 0 - ndarray result int64_t val khiter_t k Int64Vector uniques = Int64Vector() + Int64VectorData *ud - for i in range(n): - val = values[i] - k = kh_get_int64(self.table, val) - if k == self.table.n_buckets: - kh_put_int64(self.table, val, &ret) - uniques.append(val) + ud = uniques.data - result = uniques.to_array() + with nogil: + for i in range(n): + val = values[i] + k = kh_get_int64(self.table, val) + if k == self.table.n_buckets: + kh_put_int64(self.table, val, &ret) + + if needs_resize(ud): + with gil: + uniques.resize() + append_data(ud, val) - return result + return uniques.to_array() cdef class Float64HashTable(HashTable): + def __cinit__(self, size_hint=1): self.table = kh_init_float64() if size_hint is not None: @@ -566,99 +523,124 @@ cdef class Float64HashTable(HashTable): k = kh_get_float64(self.table, key) return k != self.table.n_buckets - def factorize(self, ndarray[float64_t] values): + def factorize(self, float64_t[:] values): uniques = Float64Vector() labels = self.get_labels(values, uniques, 0, -1) return uniques.to_array(), labels - def get_labels(self, ndarray[float64_t] values, + @cython.boundscheck(False) + def get_labels(self, float64_t[:] values, Float64Vector uniques, Py_ssize_t count_prior, int64_t na_sentinel): cdef: Py_ssize_t i, n = len(values) - ndarray[int64_t] labels + int64_t[:] labels Py_ssize_t idx, count = count_prior int ret = 0 float64_t val khiter_t k + Float64VectorData *ud labels = np.empty(n, dtype=np.int64) + ud = uniques.data - for i in range(n): - val = values[i] - - if val != val: - labels[i] = na_sentinel - continue - - k = kh_get_float64(self.table, val) - if k != self.table.n_buckets: - idx = self.table.vals[k] - labels[i] = idx - else: - k = kh_put_float64(self.table, val, &ret) - self.table.vals[k] = count - uniques.append(val) - labels[i] = count - count += 1 + with nogil: + for i in range(n): + val = values[i] - return labels + if val != val: + labels[i] = na_sentinel + continue - def map_locations(self, ndarray[float64_t] values): + k = kh_get_float64(self.table, val) + if k != self.table.n_buckets: + idx = self.table.vals[k] + labels[i] = idx + else: + k = kh_put_float64(self.table, val, &ret) + self.table.vals[k] = count + + if needs_resize(ud): + with gil: + uniques.resize() + append_data(ud, val) + labels[i] = count + count += 1 + + return np.asarray(labels) + + @cython.boundscheck(False) + def map_locations(self, float64_t[:] values): cdef: Py_ssize_t i, n = len(values) int ret = 0 khiter_t k - for i in range(n): - k = kh_put_float64(self.table, values[i], &ret) - self.table.vals[k] = i + with nogil: + for i in range(n): + k = kh_put_float64(self.table, values[i], &ret) + self.table.vals[k] = i - def lookup(self, ndarray[float64_t] values): + @cython.boundscheck(False) + def lookup(self, float64_t[:] values): cdef: Py_ssize_t i, n = len(values) int ret = 0 float64_t val khiter_t k - ndarray[int64_t] locs = np.empty(n, dtype=np.int64) + int64_t[:] locs = np.empty(n, dtype=np.int64) - for i in range(n): - val = values[i] - k = kh_get_float64(self.table, val) - if k != self.table.n_buckets: - locs[i] = self.table.vals[k] - else: - locs[i] = -1 + with nogil: + for i in range(n): + val = values[i] + k = kh_get_float64(self.table, val) + if k != self.table.n_buckets: + locs[i] = self.table.vals[k] + else: + locs[i] = -1 - return locs + return np.asarray(locs) - def unique(self, ndarray[float64_t] values): + @cython.boundscheck(False) + def unique(self, float64_t[:] values): cdef: Py_ssize_t i, n = len(values) int ret = 0 float64_t val khiter_t k - Float64Vector uniques = Float64Vector() bint seen_na = 0 + Float64Vector uniques = Float64Vector() + Float64VectorData *ud - for i in range(n): - val = values[i] + ud = uniques.data - if val == val: - k = kh_get_float64(self.table, val) - if k == self.table.n_buckets: - kh_put_float64(self.table, val, &ret) - uniques.append(val) - elif not seen_na: - seen_na = 1 - uniques.append(ONAN) + with nogil: + for i in range(n): + val = values[i] + + if val == val: + k = kh_get_float64(self.table, val) + if k == self.table.n_buckets: + kh_put_float64(self.table, val, &ret) + + if needs_resize(ud): + with gil: + uniques.resize() + append_data(ud, val) + + elif not seen_na: + seen_na = 1 + + if needs_resize(ud): + with gil: + uniques.resize() + append_data(ud, NAN) return uniques.to_array() na_sentinel = object cdef class PyObjectHashTable(HashTable): - # cdef kh_pymap_t *table def __init__(self, size_hint=1): self.table = kh_init_pymap() @@ -740,7 +722,7 @@ cdef class PyObjectHashTable(HashTable): int ret = 0 object val khiter_t k - ndarray[int64_t] locs = np.empty(n, dtype=np.int64) + int64_t[:] locs = np.empty(n, dtype=np.int64) for i in range(n): val = values[i] @@ -754,30 +736,13 @@ cdef class PyObjectHashTable(HashTable): else: locs[i] = -1 - return locs - - def lookup2(self, ndarray[object] values): - cdef: - Py_ssize_t i, n = len(values) - int ret = 0 - object val - khiter_t k - long hval - ndarray[int64_t] locs = np.empty(n, dtype=np.int64) - - # for i in range(n): - # val = values[i] - # hval = PyObject_Hash(val) - # k = kh_get_pymap(self.table, val) - - return locs + return np.asarray(locs) def unique(self, ndarray[object] values): cdef: Py_ssize_t i, n = len(values) int ret = 0 object val - ndarray result khiter_t k ObjectVector uniques = ObjectVector() bint seen_na = 0 @@ -792,17 +757,15 @@ cdef class PyObjectHashTable(HashTable): uniques.append(val) elif not seen_na: seen_na = 1 - uniques.append(ONAN) - - result = uniques.to_array() + uniques.append(nan) - return result + return uniques.to_array() def get_labels(self, ndarray[object] values, ObjectVector uniques, Py_ssize_t count_prior, int64_t na_sentinel): cdef: Py_ssize_t i, n = len(values) - ndarray[int64_t] labels + int64_t[:] labels Py_ssize_t idx, count = count_prior int ret = 0 object val @@ -829,7 +792,7 @@ cdef class PyObjectHashTable(HashTable): labels[i] = count count += 1 - return labels + return np.asarray(labels) cdef class Factorizer: @@ -884,7 +847,7 @@ cdef class Int64Factorizer: def get_count(self): return self.count - def factorize(self, ndarray[int64_t] values, sort=False, + def factorize(self, int64_t[:] values, sort=False, na_sentinel=-1): labels = self.table.get_labels(values, self.uniques, self.count, na_sentinel) @@ -903,45 +866,92 @@ cdef class Int64Factorizer: self.count = len(self.uniques) return labels +ctypedef fused kh_scalar64: + kh_int64_t + kh_float64_t -cdef build_count_table_int64(ndarray[int64_t] values, kh_int64_t *table): +@cython.boundscheck(False) +cdef build_count_table_scalar64(sixty_four_bit_scalar[:] values, + kh_scalar64 *table, bint dropna): cdef: khiter_t k Py_ssize_t i, n = len(values) + sixty_four_bit_scalar val int ret = 0 - kh_resize_int64(table, n) + if sixty_four_bit_scalar is float64_t and kh_scalar64 is kh_float64_t: + with nogil: + kh_resize_float64(table, n) + + for i in range(n): + val = values[i] + if val == val or not dropna: + k = kh_get_float64(table, val) + if k != table.n_buckets: + table.vals[k] += 1 + else: + k = kh_put_float64(table, val, &ret) + table.vals[k] = 1 + elif sixty_four_bit_scalar is int64_t and kh_scalar64 is kh_int64_t: + with nogil: + kh_resize_int64(table, n) + + for i in range(n): + val = values[i] + k = kh_get_int64(table, val) + if k != table.n_buckets: + table.vals[k] += 1 + else: + k = kh_put_int64(table, val, &ret) + table.vals[k] = 1 + else: + raise ValueError("Table type must match scalar type.") - for i in range(n): - val = values[i] - k = kh_get_int64(table, val) - if k != table.n_buckets: - table.vals[k] += 1 - else: - k = kh_put_int64(table, val, &ret) - table.vals[k] = 1 -cpdef value_count_int64(ndarray[int64_t] values): +@cython.boundscheck(False) +cpdef value_count_scalar64(sixty_four_bit_scalar[:] values, bint dropna): cdef: Py_ssize_t i - kh_int64_t *table + kh_float64_t *ftable + kh_int64_t *itable + sixty_four_bit_scalar[:] result_keys + int64_t[:] result_counts int k - table = kh_init_int64() - build_count_table_int64(values, table) - i = 0 - result_keys = np.empty(table.n_occupied, dtype=np.int64) - result_counts = np.zeros(table.n_occupied, dtype=np.int64) - for k in range(table.n_buckets): - if kh_exist_int64(table, k): - result_keys[i] = table.keys[k] - result_counts[i] = table.vals[k] - i += 1 - kh_destroy_int64(table) - return result_keys, result_counts + if sixty_four_bit_scalar is float64_t: + ftable = kh_init_float64() + build_count_table_scalar64(values, ftable, dropna) + + result_keys = np.empty(ftable.n_occupied, dtype=np.float64) + result_counts = np.zeros(ftable.n_occupied, dtype=np.int64) + + with nogil: + for k in range(ftable.n_buckets): + if kh_exist_float64(ftable, k): + result_keys[i] = ftable.keys[k] + result_counts[i] = ftable.vals[k] + i += 1 + kh_destroy_float64(ftable) + + elif sixty_four_bit_scalar is int64_t: + itable = kh_init_int64() + build_count_table_scalar64(values, itable, dropna) + + result_keys = np.empty(itable.n_occupied, dtype=np.int64) + result_counts = np.zeros(itable.n_occupied, dtype=np.int64) + + with nogil: + for k in range(itable.n_buckets): + if kh_exist_int64(itable, k): + result_keys[i] = itable.keys[k] + result_counts[i] = itable.vals[k] + i += 1 + kh_destroy_int64(itable) + + return np.asarray(result_keys), np.asarray(result_counts) cdef build_count_table_object(ndarray[object] values, @@ -968,7 +978,7 @@ cdef build_count_table_object(ndarray[object] values, cpdef value_count_object(ndarray[object] values, - ndarray[uint8_t, cast=True] mask): + ndarray[uint8_t, cast=True] mask): cdef: Py_ssize_t i kh_pymap_t *table @@ -995,6 +1005,7 @@ def mode_object(ndarray[object] values, ndarray[uint8_t, cast=True] mask): int count, max_count = 2 int j = -1 # so you can do += int k + ndarray[object] modes kh_pymap_t *table table = kh_init_pymap() @@ -1019,56 +1030,76 @@ def mode_object(ndarray[object] values, ndarray[uint8_t, cast=True] mask): return modes[:j+1] -def mode_int64(ndarray[int64_t] values): +@cython.boundscheck(False) +def mode_int64(int64_t[:] values): cdef: int count, max_count = 2 int j = -1 # so you can do += int k kh_int64_t *table + ndarray[int64_t] modes table = kh_init_int64() - build_count_table_int64(values, table) + build_count_table_scalar64(values, table, 0) modes = np.empty(table.n_buckets, dtype=np.int64) - for k in range(table.n_buckets): - if kh_exist_int64(table, k): - count = table.vals[k] - if count == max_count: - j += 1 - elif count > max_count: - max_count = count - j = 0 - else: - continue - modes[j] = table.keys[k] + with nogil: + for k in range(table.n_buckets): + if kh_exist_int64(table, k): + count = table.vals[k] + + if count == max_count: + j += 1 + elif count > max_count: + max_count = count + j = 0 + else: + continue + modes[j] = table.keys[k] kh_destroy_int64(table) return modes[:j+1] - @cython.wraparound(False) @cython.boundscheck(False) -def duplicated_int64(ndarray[int64_t, ndim=1] values, int take_last): +def duplicated_int64(ndarray[int64_t, ndim=1] values, object keep='first'): cdef: - int ret = 0 + int ret = 0, value, k Py_ssize_t i, n = len(values) kh_int64_t * table = kh_init_int64() ndarray[uint8_t, ndim=1, cast=True] out = np.empty(n, dtype='bool') kh_resize_int64(table, min(n, _SIZE_HINT_LIMIT)) - if take_last: - for i from n > i >=0: - kh_put_int64(table, values[i], &ret) - out[i] = ret == 0 + if keep not in ('last', 'first', False): + raise ValueError('keep must be either "first", "last" or False') + + if keep == 'last': + with nogil: + for i from n > i >=0: + kh_put_int64(table, values[i], &ret) + out[i] = ret == 0 + elif keep == 'first': + with nogil: + for i from 0 <= i < n: + kh_put_int64(table, values[i], &ret) + out[i] = ret == 0 else: - for i from 0 <= i < n: - kh_put_int64(table, values[i], &ret) - out[i] = ret == 0 - + with nogil: + for i from 0 <= i < n: + value = values[i] + k = kh_get_int64(table, value) + if k != table.n_buckets: + out[table.vals[k]] = 1 + out[i] = 1 + else: + k = kh_put_int64(table, value, &ret) + table.keys[k] = value + table.vals[k] = i + out[i] = 0 kh_destroy_int64(table) return out @@ -1087,13 +1118,18 @@ def unique_label_indices(ndarray[int64_t, ndim=1] labels): kh_int64_t * table = kh_init_int64() Int64Vector idx = Int64Vector() ndarray[int64_t, ndim=1] arr + Int64VectorData *ud = idx.data kh_resize_int64(table, min(n, _SIZE_HINT_LIMIT)) - for i in range(n): - kh_put_int64(table, labels[i], &ret) - if ret != 0: - idx.append(i) + with nogil: + for i in range(n): + kh_put_int64(table, labels[i], &ret) + if ret != 0: + if needs_resize(ud): + with gil: + idx.resize() + append_data(ud, i) kh_destroy_int64(table) diff --git a/pandas/index.pyx b/pandas/index.pyx index 9be7e7404f3fe..1678e3b280ee5 100644 --- a/pandas/index.pyx +++ b/pandas/index.pyx @@ -1,3 +1,5 @@ +# cython: profile=False + from numpy cimport ndarray from numpy cimport (float64_t, int32_t, int64_t, uint8_t, @@ -89,6 +91,7 @@ cdef class IndexEngine: self.monotonic_check = 0 self.unique = 0 + self.unique_check = 0 self.monotonic_inc = 0 self.monotonic_dec = 0 @@ -230,16 +233,12 @@ cdef class IndexEngine: cdef inline _do_monotonic_check(self): try: values = self._get_index_values() - self.monotonic_inc, self.monotonic_dec, unique = \ + self.monotonic_inc, self.monotonic_dec = \ self._call_monotonic(values) - - if unique is not None: - self.unique = unique - self.unique_check = 1 - except TypeError: self.monotonic_inc = 0 self.monotonic_dec = 0 + self.monotonic_check = 1 cdef _get_index_values(self): diff --git a/pandas/io/api.py b/pandas/io/api.py index 5fa8c7ef60074..fedde462c74b7 100644 --- a/pandas/io/api.py +++ b/pandas/io/api.py @@ -9,6 +9,7 @@ from pandas.io.json import read_json from pandas.io.html import read_html from pandas.io.sql import read_sql, read_sql_table, read_sql_query +from pandas.io.sas import read_sas from pandas.io.stata import read_stata from pandas.io.pickle import read_pickle, to_pickle from pandas.io.packers import read_msgpack, to_msgpack diff --git a/pandas/io/common.py b/pandas/io/common.py index 65cfdff1df14b..c6ece61f05a01 100644 --- a/pandas/io/common.py +++ b/pandas/io/common.py @@ -73,7 +73,7 @@ def _is_s3_url(url): return False -def maybe_read_encoded_stream(reader, encoding=None): +def maybe_read_encoded_stream(reader, encoding=None, compression=None): """read an encoded stream from the reader and transform the bytes to unicode if required based on the encoding @@ -94,8 +94,14 @@ def maybe_read_encoded_stream(reader, encoding=None): else: errors = 'replace' encoding = 'utf-8' - reader = StringIO(reader.read().decode(encoding, errors)) + + if compression == 'gzip': + reader = BytesIO(reader.read()) + else: + reader = StringIO(reader.read().decode(encoding, errors)) else: + if compression == 'gzip': + reader = BytesIO(reader.read()) encoding = None return reader, encoding @@ -118,7 +124,8 @@ def _expand_user(filepath_or_buffer): return filepath_or_buffer -def get_filepath_or_buffer(filepath_or_buffer, encoding=None): +def get_filepath_or_buffer(filepath_or_buffer, encoding=None, + compression=None): """ If the filepath_or_buffer is a url, translate and return the buffer passthru otherwise. @@ -130,12 +137,19 @@ def get_filepath_or_buffer(filepath_or_buffer, encoding=None): Returns ------- - a filepath_or_buffer, the encoding + a filepath_or_buffer, the encoding, the compression """ if _is_url(filepath_or_buffer): req = _urlopen(str(filepath_or_buffer)) - return maybe_read_encoded_stream(req, encoding) + if compression == 'infer': + content_encoding = req.headers.get('Content-Encoding', None) + if content_encoding == 'gzip': + compression = 'gzip' + # cat on the compression to the tuple returned by the function + to_return = list(maybe_read_encoded_stream(req, encoding, compression)) + \ + [compression] + return tuple(to_return) if _is_s3_url(filepath_or_buffer): try: @@ -151,15 +165,14 @@ def get_filepath_or_buffer(filepath_or_buffer, encoding=None): except boto.exception.NoAuthHandlerFound: conn = boto.connect_s3(anon=True) - b = conn.get_bucket(parsed_url.netloc) + b = conn.get_bucket(parsed_url.netloc, validate=False) k = boto.s3.key.Key(b) k.key = parsed_url.path filepath_or_buffer = BytesIO(k.get_contents_as_string( encoding=encoding)) - return filepath_or_buffer, None - + return filepath_or_buffer, None, compression - return _expand_user(filepath_or_buffer), None + return _expand_user(filepath_or_buffer), None, compression def file_path_to_url(path): diff --git a/pandas/io/data.py b/pandas/io/data.py index 3e077bf526ab9..1556f6b00e981 100644 --- a/pandas/io/data.py +++ b/pandas/io/data.py @@ -504,7 +504,7 @@ def fetch_data(url, name): def get_data_famafrench(name): # path of zip files - zip_file_path = '{0}/{1}.zip'.format(_FAMAFRENCH_URL, name) + zip_file_path = '{0}/{1}_TXT.zip'.format(_FAMAFRENCH_URL, name) with urlopen(zip_file_path) as url: raw = url.read() diff --git a/pandas/io/excel.py b/pandas/io/excel.py index cab342dc339f4..d58d6590b96c0 100644 --- a/pandas/io/excel.py +++ b/pandas/io/excel.py @@ -9,11 +9,13 @@ import abc import numpy as np +from pandas.core.frame import DataFrame from pandas.io.parsers import TextParser from pandas.io.common import _is_url, _urlopen from pandas.tseries.period import Period from pandas import json -from pandas.compat import map, zip, reduce, range, lrange, u, add_metaclass +from pandas.compat import (map, zip, reduce, range, lrange, u, add_metaclass, + BytesIO, string_types) from pandas.core import config from pandas.core.common import pprint_thing import pandas.compat as compat @@ -417,10 +419,13 @@ def _parse_cell(cell_contents,cell_typ): if parse_cols is None or should_parse[j]: row.append(_parse_cell(value,typ)) data.append(row) - + + if sheet.nrows == 0: + return DataFrame() + if header is not None: data[header] = _trim_excel_header(data[header]) - + parser = TextParser(data, header=header, index_col=index_col, has_index_names=has_index_names, na_values=na_values, @@ -474,6 +479,8 @@ def _conv_value(val): val = bool(val) elif isinstance(val, Period): val = "%s" % val + elif com.is_list_like(val): + val = str(val) return val @@ -497,6 +504,11 @@ class ExcelWriter(object): datetime_format : string, default None Format string for datetime objects written into Excel files (e.g. 'YYYY-MM-DD HH:MM:SS') + + Notes + ----- + For compatibility with CSV writers, ExcelWriter serializes lists + and dicts to strings before writing. """ # Defining an ExcelWriter implementation (see abstract methods for more...) @@ -521,9 +533,13 @@ class ExcelWriter(object): # ExcelWriter. def __new__(cls, path, engine=None, **kwargs): # only switch class if generic(ExcelWriter) - if cls == ExcelWriter: + if issubclass(cls, ExcelWriter): if engine is None: - ext = os.path.splitext(path)[-1][1:] + if isinstance(path, string_types): + ext = os.path.splitext(path)[-1][1:] + else: + ext = 'xlsx' + try: engine = config.get_option('io.excel.%s.writer' % ext) except KeyError: @@ -574,7 +590,11 @@ def save(self): def __init__(self, path, engine=None, date_format=None, datetime_format=None, **engine_kwargs): # validate that this engine can handle the extension - ext = os.path.splitext(path)[-1] + if isinstance(path, string_types): + ext = os.path.splitext(path)[-1] + else: + ext = 'xls' if engine == 'xlwt' else 'xlsx' + self.check_extension(ext) self.path = path @@ -1159,7 +1179,7 @@ class _XlwtWriter(ExcelWriter): def __init__(self, path, engine=None, encoding=None, **engine_kwargs): # Use the xlwt module as the Excel writer. import xlwt - + engine_kwargs['engine'] = engine super(_XlwtWriter, self).__init__(path, **engine_kwargs) if encoding is None: @@ -1311,6 +1331,8 @@ def write_cells(self, cells, sheet_name=None, startrow=0, startcol=0): style_dict = {} for cell in cells: + val = _conv_value(cell.val) + num_format_str = None if isinstance(cell.val, datetime.datetime): num_format_str = self.datetime_format @@ -1336,7 +1358,7 @@ def write_cells(self, cells, sheet_name=None, startrow=0, startcol=0): else: wks.write(startrow + cell.row, startcol + cell.col, - cell.val, style) + val, style) def _convert_to_style(self, style_dict, num_format_str=None): """ diff --git a/pandas/io/gbq.py b/pandas/io/gbq.py index f1fcc822adeaf..06ad8827a5642 100644 --- a/pandas/io/gbq.py +++ b/pandas/io/gbq.py @@ -294,7 +294,7 @@ def _parse_entry(field_value, field_type): return field_value -def read_gbq(query, project_id = None, index_col=None, col_order=None, reauth=False): +def read_gbq(query, project_id=None, index_col=None, col_order=None, reauth=False): """Load data from Google BigQuery. THIS IS AN EXPERIMENTAL LIBRARY diff --git a/pandas/io/json.py b/pandas/io/json.py index 2c1333326b701..81a916e058b3d 100644 --- a/pandas/io/json.py +++ b/pandas/io/json.py @@ -172,7 +172,7 @@ def read_json(path_or_buf=None, orient=None, typ='frame', dtype=True, result : Series or DataFrame """ - filepath_or_buffer, _ = get_filepath_or_buffer(path_or_buf) + filepath_or_buffer, _, _ = get_filepath_or_buffer(path_or_buf) if isinstance(filepath_or_buffer, compat.string_types): try: exists = os.path.exists(filepath_or_buffer) diff --git a/pandas/io/packers.py b/pandas/io/packers.py index 75ca44fd1ef3e..d5c02736a1cf5 100644 --- a/pandas/io/packers.py +++ b/pandas/io/packers.py @@ -60,7 +60,7 @@ from pandas.core.internals import BlockManager, make_block import pandas.core.internals as internals -from pandas.msgpack import Unpacker as _Unpacker, Packer as _Packer +from pandas.msgpack import Unpacker as _Unpacker, Packer as _Packer, ExtType # until we can pass this into our conversion functions, # this is pretty hacky @@ -126,12 +126,12 @@ def read_msgpack(path_or_buf, iterator=False, **kwargs): obj : type of object stored in file """ - path_or_buf, _ = get_filepath_or_buffer(path_or_buf) + path_or_buf, _, _ = get_filepath_or_buffer(path_or_buf) if iterator: return Iterator(path_or_buf) def read(fh): - l = list(unpack(fh)) + l = list(unpack(fh, **kwargs)) if len(l) == 1: return l[0] return l @@ -141,34 +141,44 @@ def read(fh): try: exists = os.path.exists(path_or_buf) - except (TypeError,ValueError): + except (TypeError, ValueError): exists = False if exists: with open(path_or_buf, 'rb') as fh: return read(fh) - # treat as a string-like - if not hasattr(path_or_buf, 'read'): - + # treat as a binary-like + if isinstance(path_or_buf, compat.binary_type): + fh = None try: fh = compat.BytesIO(path_or_buf) return read(fh) finally: - fh.close() + if fh is not None: + fh.close() # a buffer like - return read(path_or_buf) + if hasattr(path_or_buf, 'read') and compat.callable(path_or_buf.read): + return read(path_or_buf) + + raise ValueError('path_or_buf needs to be a string file path or file-like') dtype_dict = {21: np.dtype('M8[ns]'), u('datetime64[ns]'): np.dtype('M8[ns]'), u('datetime64[us]'): np.dtype('M8[us]'), 22: np.dtype('m8[ns]'), u('timedelta64[ns]'): np.dtype('m8[ns]'), - u('timedelta64[us]'): np.dtype('m8[us]')} + u('timedelta64[us]'): np.dtype('m8[us]'), + + # this is platform int, which we need to remap to np.int64 + # for compat on windows platforms + 7: np.dtype('int64'), +} def dtype_for(t): + """ return my dtype mapping, whether number or name """ if t in dtype_dict: return dtype_dict[t] return np.typeDict[t] @@ -212,7 +222,7 @@ def convert(values): # convert to a bytes array v = v.tostring() import zlib - return zlib.compress(v) + return ExtType(0, zlib.compress(v)) elif compressor == 'blosc': @@ -223,18 +233,24 @@ def convert(values): # convert to a bytes array v = v.tostring() import blosc - return blosc.compress(v, typesize=dtype.itemsize) + return ExtType(0, blosc.compress(v, typesize=dtype.itemsize)) # ndarray (on original dtype) - return v.tostring() + return ExtType(0, v.tostring()) def unconvert(values, dtype, compress=None): + as_is_ext = isinstance(values, ExtType) and values.code == 0 + + if as_is_ext: + values = values.data + if dtype == np.object_: return np.array(values, dtype=object) - values = values.encode('latin1') + if not as_is_ext: + values = values.encode('latin1') if compress == 'zlib': import zlib @@ -262,7 +278,7 @@ def encode(obj): 'klass': obj.__class__.__name__, 'name': getattr(obj, 'name', None), 'freq': getattr(obj, 'freqstr', None), - 'dtype': obj.dtype.num, + 'dtype': obj.dtype.name, 'data': convert(obj.asi8), 'compress': compressor} elif isinstance(obj, DatetimeIndex): @@ -275,7 +291,7 @@ def encode(obj): return {'typ': 'datetime_index', 'klass': obj.__class__.__name__, 'name': getattr(obj, 'name', None), - 'dtype': obj.dtype.num, + 'dtype': obj.dtype.name, 'data': convert(obj.asi8), 'freq': getattr(obj, 'freqstr', None), 'tz': tz, @@ -284,14 +300,14 @@ def encode(obj): return {'typ': 'multi_index', 'klass': obj.__class__.__name__, 'names': getattr(obj, 'names', None), - 'dtype': obj.dtype.num, + 'dtype': obj.dtype.name, 'data': convert(obj.values), 'compress': compressor} else: return {'typ': 'index', 'klass': obj.__class__.__name__, 'name': getattr(obj, 'name', None), - 'dtype': obj.dtype.num, + 'dtype': obj.dtype.name, 'data': convert(obj.values), 'compress': compressor} elif isinstance(obj, Series): @@ -301,7 +317,7 @@ def encode(obj): ) #d = {'typ': 'sparse_series', # 'klass': obj.__class__.__name__, - # 'dtype': obj.dtype.num, + # 'dtype': obj.dtype.name, # 'index': obj.index, # 'sp_index': obj.sp_index, # 'sp_values': convert(obj.sp_values), @@ -314,7 +330,7 @@ def encode(obj): 'klass': obj.__class__.__name__, 'name': getattr(obj, 'name', None), 'index': obj.index, - 'dtype': obj.dtype.num, + 'dtype': obj.dtype.name, 'data': convert(obj.values), 'compress': compressor} elif issubclass(tobj, NDFrame): @@ -353,9 +369,10 @@ def encode(obj): 'klass': obj.__class__.__name__, 'axes': data.axes, 'blocks': [{'items': data.items.take(b.mgr_locs), + 'locs': b.mgr_locs.as_array, 'values': convert(b.values), 'shape': b.values.shape, - 'dtype': b.dtype.num, + 'dtype': b.dtype.name, 'klass': b.__class__.__name__, 'compress': compressor } for b in data.blocks]} @@ -408,7 +425,7 @@ def encode(obj): return {'typ': 'ndarray', 'shape': obj.shape, 'ndim': obj.ndim, - 'dtype': obj.dtype.num, + 'dtype': obj.dtype.name, 'data': convert(obj), 'compress': compressor} elif isinstance(obj, np.number): @@ -444,11 +461,12 @@ def decode(obj): return Period(ordinal=obj['ordinal'], freq=obj['freq']) elif typ == 'index': dtype = dtype_for(obj['dtype']) - data = unconvert(obj['data'], np.typeDict[obj['dtype']], + data = unconvert(obj['data'], dtype, obj.get('compress')) return globals()[obj['klass']](data, dtype=dtype, name=obj['name']) elif typ == 'multi_index': - data = unconvert(obj['data'], np.typeDict[obj['dtype']], + dtype = dtype_for(obj['dtype']) + data = unconvert(obj['data'], dtype, obj.get('compress')) data = [tuple(x) for x in data] return globals()[obj['klass']].from_tuples(data, names=obj['names']) @@ -481,9 +499,15 @@ def decode(obj): def create_block(b): values = unconvert(b['values'], dtype_for(b['dtype']), b['compress']).reshape(b['shape']) + + # locs handles duplicate column names, and should be used instead of items; see GH 9618 + if 'locs' in b: + placement = b['locs'] + else: + placement = axes[0].get_indexer(b['items']) return make_block(values=values, klass=getattr(internals, b['klass']), - placement=axes[0].get_indexer(b['items'])) + placement=placement) blocks = [create_block(b) for b in obj['blocks']] return globals()[obj['klass']](BlockManager(blocks, axes)) @@ -540,19 +564,23 @@ def create_block(b): def pack(o, default=encode, - encoding='latin1', unicode_errors='strict', use_single_float=False): + encoding='latin1', unicode_errors='strict', use_single_float=False, + autoreset=1, use_bin_type=1): """ Pack an object and return the packed bytes. """ return Packer(default=default, encoding=encoding, unicode_errors=unicode_errors, - use_single_float=use_single_float).pack(o) + use_single_float=use_single_float, + autoreset=autoreset, + use_bin_type=use_bin_type).pack(o) def unpack(packed, object_hook=decode, list_hook=None, use_list=False, encoding='latin1', - unicode_errors='strict', object_pairs_hook=None): + unicode_errors='strict', object_pairs_hook=None, + max_buffer_size=0, ext_hook=ExtType): """ Unpack a packed object, return an iterator Note: packed lists will be returned as tuples @@ -562,7 +590,9 @@ def unpack(packed, object_hook=decode, list_hook=list_hook, use_list=use_list, encoding=encoding, unicode_errors=unicode_errors, - object_pairs_hook=object_pairs_hook) + object_pairs_hook=object_pairs_hook, + max_buffer_size=max_buffer_size, + ext_hook=ext_hook) class Packer(_Packer): @@ -570,11 +600,15 @@ class Packer(_Packer): def __init__(self, default=encode, encoding='latin1', unicode_errors='strict', - use_single_float=False): + use_single_float=False, + autoreset=1, + use_bin_type=1): super(Packer, self).__init__(default=default, encoding=encoding, unicode_errors=unicode_errors, - use_single_float=use_single_float) + use_single_float=use_single_float, + autoreset=autoreset, + use_bin_type=use_bin_type) class Unpacker(_Unpacker): @@ -582,7 +616,7 @@ class Unpacker(_Unpacker): def __init__(self, file_like=None, read_size=0, use_list=False, object_hook=decode, object_pairs_hook=None, list_hook=None, encoding='latin1', - unicode_errors='strict', max_buffer_size=0): + unicode_errors='strict', max_buffer_size=0, ext_hook=ExtType): super(Unpacker, self).__init__(file_like=file_like, read_size=read_size, use_list=use_list, @@ -591,7 +625,8 @@ def __init__(self, file_like=None, read_size=0, use_list=False, list_hook=list_hook, encoding=encoding, unicode_errors=unicode_errors, - max_buffer_size=max_buffer_size) + max_buffer_size=max_buffer_size, + ext_hook=ext_hook) class Iterator(object): diff --git a/pandas/io/parsers.py b/pandas/io/parsers.py index 508cf1103cee5..9ad992c434984 100755 --- a/pandas/io/parsers.py +++ b/pandas/io/parsers.py @@ -26,6 +26,7 @@ import pandas.tslib as tslib import pandas.parser as _parser + class ParserWarning(Warning): pass @@ -86,7 +87,7 @@ class ParserWarning(Warning): should explicitly pass header=None prefix : string, default None Prefix to add to column numbers when no header, e.g 'X' for X0, X1, ... -na_values : list-like or dict, default None +na_values : str, list-like or dict, default None Additional strings to recognize as NA/NaN. If dict passed, specific per-column NA values true_values : list @@ -234,8 +235,10 @@ def _read(filepath_or_buffer, kwds): if skipfooter is not None: kwds['skip_footer'] = skipfooter - filepath_or_buffer, _ = get_filepath_or_buffer(filepath_or_buffer, - encoding) + filepath_or_buffer, _, compression = get_filepath_or_buffer(filepath_or_buffer, + encoding, + compression=kwds.get('compression', None)) + kwds['compression'] = compression if kwds.get('date_parser', None) is not None: if isinstance(kwds['parse_dates'], bool): @@ -355,7 +358,6 @@ def parser_f(filepath_or_buffer, skipfooter=None, skip_footer=0, na_values=None, - na_fvalues=None, true_values=None, false_values=None, delimiter=None, @@ -403,8 +405,9 @@ def parser_f(filepath_or_buffer, delimiter = sep if delim_whitespace and delimiter is not default_sep: - raise ValueError("Specified a delimiter with both sep and"\ - " delim_whitespace=True; you can only specify one.") + raise ValueError("Specified a delimiter with both sep and" + " delim_whitespace=True; you can only" + " specify one.") if engine is not None: engine_specified = True @@ -431,7 +434,6 @@ def parser_f(filepath_or_buffer, prefix=prefix, skiprows=skiprows, na_values=na_values, - na_fvalues=na_fvalues, true_values=true_values, false_values=false_values, keep_default_na=keep_default_na, @@ -800,6 +802,8 @@ def __init__(self, kwds): self._name_processed = False + self._first_chunk = True + @property def _has_complex_date_col(self): return (isinstance(self.parse_dates, dict) or @@ -997,7 +1001,7 @@ def _convert_to_ndarrays(self, dct, na_values, na_fvalues, verbose=False, try: values = lib.map_infer(values, conv_f) except ValueError: - mask = lib.ismember(values, na_values).view(np.uin8) + mask = lib.ismember(values, na_values).view(np.uint8) values = lib.map_infer_mask(values, conv_f, mask) coerce_type = False @@ -1162,20 +1166,25 @@ def set_error_bad_lines(self, status): self._reader.set_error_bad_lines(int(status)) def read(self, nrows=None): - if self.as_recarray: - # what to do if there are leading columns? - return self._reader.read(nrows) - try: data = self._reader.read(nrows) except StopIteration: - if nrows is None: + if self._first_chunk: + self._first_chunk = False return _get_empty_meta(self.orig_names, self.index_col, - self.index_names) + self.index_names, + dtype=self.kwds.get('dtype')) else: raise + # Done with first read, next time raise StopIteration + self._first_chunk = False + + if self.as_recarray: + # what to do if there are leading columns? + return data + names = self.names if self._reader.leading_cols: @@ -1327,10 +1336,7 @@ def _wrap_compressed(f, compression, encoding=None): import gzip f = gzip.GzipFile(fileobj=f) - if compat.PY3_2: - # 3.2's gzip doesn't support read1 - f = StringIO(f.read().decode(encoding)) - elif compat.PY3: + if compat.PY3: from io import TextIOWrapper f = TextIOWrapper(f) @@ -1454,7 +1460,6 @@ def __init__(self, f, **kwds): self._name_processed = True if self.index_names is None: self.index_names = index_names - self._first_chunk = True if self.parse_dates: self._no_thousands_columns = self._set_no_thousands_columns() @@ -1715,7 +1720,7 @@ def _infer_columns(self): num_original_columns = ncols if not names: if self.prefix: - columns = [['%s%d' % (self.prefix,i) for i in range(ncols)]] + columns = [['%s%d' % (self.prefix, i) for i in range(ncols)]] else: columns = [lrange(ncols)] columns = self._handle_usecols(columns, columns[0]) @@ -2050,12 +2055,14 @@ def _make_date_converter(date_parser=None, dayfirst=False, def converter(*date_cols): if date_parser is None: strs = _concat_date_cols(date_cols) + try: - return tools.to_datetime( + return tools._to_datetime( com._ensure_object(strs), utc=None, box=False, dayfirst=dayfirst, + errors='ignore', infer_datetime_format=infer_datetime_format ) except: @@ -2063,7 +2070,7 @@ def converter(*date_cols): lib.try_parse_dates(strs, dayfirst=dayfirst)) else: try: - result = tools.to_datetime(date_parser(*date_cols)) + result = tools.to_datetime(date_parser(*date_cols), errors='ignore') if isinstance(result, datetime.datetime): raise Exception('scalar parser') return result @@ -2072,7 +2079,8 @@ def converter(*date_cols): return tools.to_datetime( lib.try_parse_dates(_concat_date_cols(date_cols), parser=date_parser, - dayfirst=dayfirst)) + dayfirst=dayfirst), + errors='ignore') except Exception: return generic_parser(date_parser, *date_cols) @@ -2223,18 +2231,30 @@ def _clean_index_names(columns, index_col): return index_names, columns, index_col -def _get_empty_meta(columns, index_col, index_names): +def _get_empty_meta(columns, index_col, index_names, dtype=None): columns = list(columns) - if index_col is not None: - index = MultiIndex.from_arrays([[]] * len(index_col), - names=index_names) - for n in index_col: - columns.pop(n) + if dtype is None: + dtype = {} else: + # Convert column indexes to column names. + dtype = dict((columns[k] if com.is_integer(k) else k, v) + for k, v in compat.iteritems(dtype)) + + if index_col is None or index_col is False: index = Index([]) + else: + index = [np.empty(0, dtype=dtype.get(index_name, np.object)) + for index_name in index_names] + index = MultiIndex.from_arrays(index, names=index_names) + index_col.sort() + for i, n in enumerate(index_col): + columns.pop(n-i) + + col_dict = dict((col_name, np.empty(0, dtype=dtype.get(col_name, np.object))) + for col_name in columns) - return index, columns, {} + return index, columns, col_dict def _floatify_na_values(na_values): diff --git a/pandas/io/pytables.py b/pandas/io/pytables.py index 31f649c498c14..2c9ffe6b74536 100644 --- a/pandas/io/pytables.py +++ b/pandas/io/pytables.py @@ -220,7 +220,7 @@ class DuplicateWarning(Warning): """ with config.config_prefix('io.hdf'): - config.register_option('dropna_table', True, dropna_doc, + config.register_option('dropna_table', False, dropna_doc, validator=config.is_bool) config.register_option( 'default_format', None, format_doc, @@ -271,7 +271,7 @@ def to_hdf(path_or_buf, key, value, mode=None, complevel=None, complib=None, f(path_or_buf) -def read_hdf(path_or_buf, key, **kwargs): +def read_hdf(path_or_buf, key=None, **kwargs): """ read from the store, close it if we opened it Retrieve pandas object stored in file, optionally based on where @@ -280,7 +280,8 @@ def read_hdf(path_or_buf, key, **kwargs): Parameters ---------- path_or_buf : path (string), or buffer to read from - key : group identifier in the store + key : group identifier in the store. Can be omitted a HDF file contains + a single pandas object. where : list of Term (or convertable) objects, optional start : optional, integer (defaults to None), row number to start selection @@ -329,6 +330,12 @@ def read_hdf(path_or_buf, key, **kwargs): 'implemented.') try: + if key is None: + keys = store.keys() + if len(keys) != 1: + raise ValueError('key must be provided when HDF file contains ' + 'multiple datasets.') + key = keys[0] return store.select(key, auto_close=auto_close, **kwargs) except: # if there is an error, close the store @@ -810,7 +817,7 @@ def put(self, key, value, format=None, append=False, **kwargs): This will force Table format, append the input data to the existing. encoding : default None, provide an encoding for strings - dropna : boolean, default True, do not write an ALL nan row to + dropna : boolean, default False, do not write an ALL nan row to the store settable by the option 'io.hdf.dropna_table' """ if format is None: @@ -892,7 +899,7 @@ def append(self, key, value, format=None, append=True, columns=None, chunksize : size to chunk the writing expectedrows : expected TOTAL row size of this table encoding : default None, provide an encoding for strings - dropna : boolean, default True, do not write an ALL nan row to + dropna : boolean, default False, do not write an ALL nan row to the store settable by the option 'io.hdf.dropna_table' Notes ----- @@ -912,7 +919,7 @@ def append(self, key, value, format=None, append=True, columns=None, **kwargs) def append_to_multiple(self, d, value, selector, data_columns=None, - axes=None, dropna=True, **kwargs): + axes=None, dropna=False, **kwargs): """ Append to multiple tables @@ -927,7 +934,7 @@ def append_to_multiple(self, d, value, selector, data_columns=None, data_columns : list of columns to create as data columns, or True to use all columns dropna : if evaluates to True, drop rows from all tables if any single - row in each table has all NaN + row in each table has all NaN. Default False. Notes ----- @@ -1766,6 +1773,8 @@ def set_kind(self): self.kind = 'string' elif dtype.startswith(u('float')): self.kind = 'float' + elif dtype.startswith(u('complex')): + self.kind = 'complex' elif dtype.startswith(u('int')) or dtype.startswith(u('uint')): self.kind = 'integer' elif dtype.startswith(u('date')): @@ -1795,6 +1804,8 @@ def set_atom(self, block, block_items, existing_col, min_itemsize, return self.set_atom_datetime64(block) elif block.is_timedelta: return self.set_atom_timedelta64(block) + elif block.is_complex: + return self.set_atom_complex(block) dtype = block.dtype.name inferred_type = lib.infer_dtype(block.values) @@ -1929,6 +1940,12 @@ def get_atom_coltype(self, kind=None): def get_atom_data(self, block, kind=None): return self.get_atom_coltype(kind=kind)(shape=block.shape[0]) + def set_atom_complex(self, block): + self.kind = block.dtype.name + itemsize = int(self.kind.split('complex')[-1]) // 8 + self.typ = _tables().ComplexCol(itemsize=itemsize, shape=block.shape[0]) + self.set_data(block.values.astype(self.typ.type, copy=False)) + def set_atom_data(self, block): self.kind = block.dtype.name self.typ = self.get_atom_data(block) @@ -3140,8 +3157,8 @@ def f(i, c): def create_index(self, columns=None, optlevel=None, kind=None): """ Create a pytables index on the specified columns - note: cannot index Time64Col() currently; PyTables must be >= 2.3 - + note: cannot index Time64Col() or ComplexCol currently; + PyTables must be >= 3.0 Paramaters ---------- @@ -3196,6 +3213,12 @@ def create_index(self, columns=None, optlevel=None, kind=None): # create the index if not v.is_indexed: + if v.type.startswith('complex'): + raise TypeError('Columns containing complex values can be stored but cannot' + ' be indexed when using table format. Either use fixed ' + 'format, set index=False, or do not include the columns ' + 'containing complex values to data_columns when ' + 'initializing the table.') v.create_index(**kw) def read_axes(self, where, **kwargs): @@ -3608,7 +3631,7 @@ def read_column(self, column, where=None, start=None, stop=None, **kwargs): nan_rep=self.nan_rep, encoding=self.encoding ).take_data(), - a.tz, True)) + a.tz, True), name=column) raise KeyError("column [%s] not found in the table" % column) @@ -3764,7 +3787,7 @@ class AppendableTable(LegacyTable): def write(self, obj, axes=None, append=False, complib=None, complevel=None, fletcher32=None, min_itemsize=None, - chunksize=None, expectedrows=None, dropna=True, **kwargs): + chunksize=None, expectedrows=None, dropna=False, **kwargs): if not append and self.is_exists: self._handle.remove_node(self.group, 'table') @@ -3804,7 +3827,7 @@ def write(self, obj, axes=None, append=False, complib=None, # add the rows self.write_data(chunksize, dropna=dropna) - def write_data(self, chunksize, dropna=True): + def write_data(self, chunksize, dropna=False): """ we form the data into a 2-d including indexes,values,mask write chunk-by-chunk """ diff --git a/pandas/io/sas.py b/pandas/io/sas.py new file mode 100644 index 0000000000000..5f55f861afb72 --- /dev/null +++ b/pandas/io/sas.py @@ -0,0 +1,459 @@ +""" +Tools for reading SAS XPort files into Pandas objects. + +Based on code from Jack Cushman (github.com/jcushman/xport). + +The file format is defined here: + +https://support.sas.com/techsup/technote/ts140.pdf +""" + +from datetime import datetime +import pandas as pd +from pandas.io.common import get_filepath_or_buffer +from pandas import compat +import struct +import numpy as np +from pandas.util.decorators import Appender + +_correct_line1 = "HEADER RECORD*******LIBRARY HEADER RECORD!!!!!!!000000000000000000000000000000 " +_correct_header1 = "HEADER RECORD*******MEMBER HEADER RECORD!!!!!!!000000000000000001600000000" +_correct_header2 = "HEADER RECORD*******DSCRPTR HEADER RECORD!!!!!!!000000000000000000000000000000 " +_correct_obs_header = "HEADER RECORD*******OBS HEADER RECORD!!!!!!!000000000000000000000000000000 " +_fieldkeys = ['ntype', 'nhfun', 'field_length', 'nvar0', 'name', 'label', + 'nform', 'nfl', 'num_decimals', 'nfj', 'nfill', 'niform', + 'nifl', 'nifd', 'npos', '_'] + + +# TODO: Support for 4 byte floats, see https://github.com/jcushman/xport/pull/3 +# Need a test file + + +_base_params_doc = """\ +Parameters +---------- +filepath_or_buffer : string or file-like object + Path to SAS file or object implementing binary read method.""" + +_params2_doc = """\ +index : identifier of index column + Identifier of column that should be used as index of the DataFrame. +encoding : string + Encoding for text data. +chunksize : int + Read file `chunksize` lines at a time, returns iterator.""" + +_format_params_doc = """\ +format : string + File format, only `xport` is currently supported.""" + +_iterator_doc = """\ +iterator : boolean, default False + Return XportReader object for reading file incrementally.""" + + +_read_sas_doc = """Read a SAS file into a DataFrame. + +%(_base_params_doc)s +%(_format_params_doc)s +%(_params2_doc)s +%(_iterator_doc)s + +Returns +------- +DataFrame or XportReader + +Examples +-------- +Read a SAS Xport file: + +>>> df = pandas.read_sas('filename.XPT') + +Read a Xport file in 10,000 line chunks: + +>>> itr = pandas.read_sas('filename.XPT', chunksize=10000) +>>> for chunk in itr: +>>> do_something(chunk) + +.. versionadded:: 0.17.0 +""" % {"_base_params_doc": _base_params_doc, + "_format_params_doc": _format_params_doc, + "_params2_doc": _params2_doc, + "_iterator_doc": _iterator_doc} + + +_xport_reader_doc = """\ +Class for reading SAS Xport files. + +%(_base_params_doc)s +%(_params2_doc)s + +Attributes +---------- +member_info : list + Contains information about the file +fields : list + Contains information about the variables in the file +""" % {"_base_params_doc": _base_params_doc, + "_params2_doc": _params2_doc} + + +_read_method_doc = """\ +Read observations from SAS Xport file, returning as data frame. + +Parameters +---------- +nrows : int + Number of rows to read from data file; if None, read whole + file. + +Returns +------- +A DataFrame. +""" + + +@Appender(_read_sas_doc) +def read_sas(filepath_or_buffer, format='xport', index=None, encoding='ISO-8859-1', + chunksize=None, iterator=False): + + format = format.lower() + + if format == 'xport': + reader = XportReader(filepath_or_buffer, index=index, encoding=encoding, + chunksize=chunksize) + else: + raise ValueError('only xport format is supported') + + if iterator or chunksize: + return reader + + return reader.read() + + +def _parse_date(datestr): + """ Given a date in xport format, return Python date. """ + try: + return datetime.strptime(datestr, "%d%b%y:%H:%M:%S") # e.g. "16FEB11:10:07:55" + except ValueError: + return pd.NaT + + +def _split_line(s, parts): + """ + Parameters + ---------- + s: string + Fixed-length string to split + parts: list of (name, length) pairs + Used to break up string, name '_' will be filtered from output. + + Returns + ------- + Dict of name:contents of string at given location. + """ + out = {} + start = 0 + for name, length in parts: + out[name] = s[start:start+length].strip() + start += length + del out['_'] + return out + + +def _parse_float_vec(vec): + """ + Parse a vector of 8-byte values representing IBM 8 byte floats + into native 8 byte floats. + """ + + dtype = np.dtype('>u4,>u4') + vec1 = vec.view(dtype=dtype) + + xport1 = vec1['f0'] + xport2 = vec1['f1'] + + # Start by setting first half of ieee number to first half of IBM + # number sans exponent + ieee1 = xport1 & 0x00ffffff + + # Get the second half of the ibm number into the second half of + # the ieee number + ieee2 = xport2 + + # The fraction bit to the left of the binary point in the ieee + # format was set and the number was shifted 0, 1, 2, or 3 + # places. This will tell us how to adjust the ibm exponent to be a + # power of 2 ieee exponent and how to shift the fraction bits to + # restore the correct magnitude. + shift = np.zeros(len(vec), dtype=np.uint8) + shift[np.where(xport1 & 0x00200000)] = 1 + shift[np.where(xport1 & 0x00400000)] = 2 + shift[np.where(xport1 & 0x00800000)] = 3 + + # shift the ieee number down the correct number of places then + # set the second half of the ieee number to be the second half + # of the ibm number shifted appropriately, ored with the bits + # from the first half that would have been shifted in if we + # could shift a double. All we are worried about are the low + # order 3 bits of the first half since we're only shifting by + # 1, 2, or 3. + ieee1 >>= shift + ieee2 = (xport2 >> shift) | ((xport1 & 0x00000007) << (29 + (3 - shift))) + + # clear the 1 bit to the left of the binary point + ieee1 &= 0xffefffff + + # set the exponent of the ieee number to be the actual exponent + # plus the shift count + 1023. Or this into the first half of the + # ieee number. The ibm exponent is excess 64 but is adjusted by 65 + # since during conversion to ibm format the exponent is + # incremented by 1 and the fraction bits left 4 positions to the + # right of the radix point. (had to add >> 24 because C treats & + # 0x7f as 0x7f000000 and Python doesn't) + ieee1 |= ((((((xport1 >> 24) & 0x7f) - 65) << 2) + shift + 1023) << 20) | (xport1 & 0x80000000) + + ieee = np.empty((len(ieee1),), dtype='>u4,>u4') + ieee['f0'] = ieee1 + ieee['f1'] = ieee2 + ieee = ieee.view(dtype='>f8') + ieee = ieee.astype('f8') + + return ieee + + + +class XportReader(object): + __doc__ = _xport_reader_doc + + + def __init__(self, filepath_or_buffer, index=None, encoding='ISO-8859-1', + chunksize=None): + + self._encoding = encoding + self._lines_read = 0 + self._index = index + self._chunksize = chunksize + + if isinstance(filepath_or_buffer, str): + filepath_or_buffer, encoding, compression = get_filepath_or_buffer( + filepath_or_buffer, encoding=encoding) + + if isinstance(filepath_or_buffer, (str, compat.text_type, bytes)): + self.filepath_or_buffer = open(filepath_or_buffer, 'rb') + else: + # Copy to BytesIO, and ensure no encoding + contents = filepath_or_buffer.read() + try: + contents = contents.encode(self._encoding) + except: + pass + self.filepath_or_buffer = compat.BytesIO(contents) + + self._read_header() + + + def _get_row(self): + return self.filepath_or_buffer.read(80).decode() + + + def _read_header(self): + self.filepath_or_buffer.seek(0) + + # read file header + line1 = self._get_row() + if line1 != _correct_line1: + raise ValueError("Header record is not an XPORT file.") + + line2 = self._get_row() + file_info = _split_line(line2, [ ['prefix',24], ['version',8], ['OS',8], ['_',24], ['created',16]]) + if file_info['prefix'] != "SAS SAS SASLIB": + raise ValueError("Header record has invalid prefix.") + file_info['created'] = _parse_date(file_info['created']) + self.file_info = file_info + + line3 = self._get_row() + file_info['modified'] = _parse_date(line3[:16]) + + # read member header + header1 = self._get_row() + header2 = self._get_row() + if not header1.startswith(_correct_header1) or not header2 == _correct_header2: + raise ValueError("Member header not found.") + fieldnamelength = int(header1[-5:-2]) # usually 140, could be 135 + + # member info + member_info = _split_line(self._get_row(), [['prefix',8], ['set_name',8], + ['sasdata',8],['version',8], + ['OS',8],['_',24],['created',16]]) + member_info.update( _split_line(self._get_row(), [['modified',16], ['_',16], + ['label',40],['type',8]])) + member_info['modified'] = _parse_date(member_info['modified']) + member_info['created'] = _parse_date(member_info['created']) + self.member_info = member_info + + # read field names + types = {1: 'numeric', 2: 'char'} + fieldcount = int(self._get_row()[54:58]) + datalength = fieldnamelength*fieldcount + if datalength % 80: # round up to nearest 80 + datalength += 80 - datalength%80 + fielddata = self.filepath_or_buffer.read(datalength) + fields = [] + obs_length = 0 + while len(fielddata) >= fieldnamelength: + # pull data for one field + field, fielddata = (fielddata[:fieldnamelength], fielddata[fieldnamelength:]) + + # rest at end gets ignored, so if field is short, pad out + # to match struct pattern below + field = field.ljust(140) + + fieldstruct = struct.unpack('>hhhh8s40s8shhh2s8shhl52s', field) + field = dict(zip(_fieldkeys, fieldstruct)) + del field['_'] + field['ntype'] = types[field['ntype']] + if field['ntype'] == 'numeric' and field['field_length'] != 8: + raise TypeError("Only 8-byte floats are currently implemented. Can't read field %s." % field) + + for k, v in field.items(): + try: + field[k] = v.strip() + except AttributeError: + pass + + obs_length += field['field_length'] + fields += [field] + + header = self._get_row() + if not header == _correct_obs_header: + raise ValueError("Observation header not found.") + + self.fields = fields + self.record_length = obs_length + self.record_start = self.filepath_or_buffer.tell() + + self.nobs = self._record_count() + self.columns = [x['name'].decode() for x in self.fields] + + # Setup the dtype. + dtypel = [] + for i,field in enumerate(self.fields): + ntype = field['ntype'] + if ntype == "numeric": + dtypel.append(('s' + str(i), ">u8")) + elif ntype == "char": + dtypel.append(('s' + str(i), "S" + str(field['field_length']))) + dtype = np.dtype(dtypel) + self._dtype = dtype + + + def __iter__(self): + try: + if self._chunksize: + while True: + yield self.read(self._chunksize) + else: + yield self.read() + except StopIteration: + pass + + + def _record_count(self): + """ + Get number of records in file. + + This is maybe suboptimal because we have to seek to the end of the file. + + Side effect: returns file position to record_start. + """ + + self.filepath_or_buffer.seek(0, 2) + total_records_length = self.filepath_or_buffer.tell() - self.record_start + + if total_records_length % 80 != 0: + warnings.warn("xport file may be corrupted") + + if self.record_length > 80: + self.filepath_or_buffer.seek(self.record_start) + return total_records_length // self.record_length + + self.filepath_or_buffer.seek(-80, 2) + last_card = self.filepath_or_buffer.read(80) + last_card = np.frombuffer(last_card, dtype=np.uint64) + + # 8 byte blank + ix = np.flatnonzero(last_card == 2314885530818453536) + + if len(ix) == 0: + tail_pad = 0 + else: + tail_pad = 8 * len(ix) + + self.filepath_or_buffer.seek(self.record_start) + + return (total_records_length - tail_pad) // self.record_length + + + def get_chunk(self, size=None): + """ + Reads lines from Xport file and returns as dataframe + + Parameters + ---------- + size : int, defaults to None + Number of lines to read. If None, reads whole file. + + Returns + ------- + DataFrame + """ + if size is None: + size = self._chunksize + return self.read(nrows=size) + + + def _missing_double(self, vec): + v = vec.view(dtype='u1,u1,u2,u4') + miss = (v['f1'] == 0) & (v['f2'] == 0) & (v['f3'] == 0) + miss1 = ((v['f0'] >= 0x41) & (v['f0'] <= 0x5a)) |\ + (v['f0'] == 0x5f) | (v['f0'] == 0x2e) + miss &= miss1 + return miss + + + @Appender(_read_method_doc) + def read(self, nrows=None): + + if nrows is None: + nrows = self.nobs + + read_lines = min(nrows, self.nobs - self._lines_read) + read_len = read_lines * self.record_length + if read_len <= 0: + raise StopIteration + raw = self.filepath_or_buffer.read(read_len) + data = np.frombuffer(raw, dtype=self._dtype, count=read_lines) + + df = pd.DataFrame(index=range(read_lines)) + for j,x in enumerate(self.columns): + vec = data['s%d' % j] + ntype = self.fields[j]['ntype'] + if ntype == "numeric": + miss = self._missing_double(vec) + v = _parse_float_vec(vec) + v[miss] = np.nan + elif self.fields[j]['ntype'] == 'char': + v = [y.rstrip() for y in vec] + if compat.PY3: + v = [y.decode(self._encoding) for y in v] + df[x] = v + + if self._index is None: + df.index = range(self._lines_read, self._lines_read + read_lines) + else: + df = df.set_index(self._index) + + self._lines_read += read_lines + + return df diff --git a/pandas/io/sql.py b/pandas/io/sql.py index b4e8c7de2b4e1..b587ec128c016 100644 --- a/pandas/io/sql.py +++ b/pandas/io/sql.py @@ -38,7 +38,7 @@ class DatabaseError(IOError): _SQLALCHEMY_INSTALLED = None -def _is_sqlalchemy_engine(con): +def _is_sqlalchemy_connectable(con): global _SQLALCHEMY_INSTALLED if _SQLALCHEMY_INSTALLED is None: try: @@ -62,7 +62,7 @@ def compile_big_int_sqlite(type_, compiler, **kw): if _SQLALCHEMY_INSTALLED: import sqlalchemy - return isinstance(con, sqlalchemy.engine.Engine) + return isinstance(con, sqlalchemy.engine.Connectable) else: return False @@ -80,17 +80,17 @@ def _convert_params(sql, params): def _handle_date_column(col, format=None): if isinstance(format, dict): - return to_datetime(col, **format) + return to_datetime(col, errors='ignore', **format) else: if format in ['D', 's', 'ms', 'us', 'ns']: - return to_datetime(col, coerce=True, unit=format, utc=True) + return to_datetime(col, errors='coerce', unit=format, utc=True) elif (issubclass(col.dtype.type, np.floating) or issubclass(col.dtype.type, np.integer)): # parse dates as timestamp format = 's' if format is None else format - return to_datetime(col, coerce=True, unit=format, utc=True) + return to_datetime(col, errors='coerce', unit=format, utc=True) else: - return to_datetime(col, coerce=True, format=format, utc=True) + return to_datetime(col, errors='coerce', format=format, utc=True) def _parse_date_columns(data_frame, parse_dates): @@ -139,7 +139,7 @@ def execute(sql, con, cur=None, params=None): ---------- sql : string Query to be executed - con : SQLAlchemy engine or sqlite3 DBAPI2 connection + con : SQLAlchemy connectable(engine/connection) or sqlite3 DBAPI2 connection Using SQLAlchemy makes it possible to use any DB supported by that library. If a DBAPI2 object, only sqlite3 is supported. @@ -282,14 +282,14 @@ def read_sql_table(table_name, con, schema=None, index_col=None, chunksize=None): """Read SQL database table into a DataFrame. - Given a table name and an SQLAlchemy engine, returns a DataFrame. + Given a table name and an SQLAlchemy connectable, returns a DataFrame. This function does not support DBAPI connections. Parameters ---------- table_name : string Name of SQL table in database - con : SQLAlchemy engine + con : SQLAlchemy connectable (or database string URI) Sqlite DBAPI connection mode not supported schema : string, default None Name of SQL schema in database to query (if database flavor @@ -328,14 +328,16 @@ def read_sql_table(table_name, con, schema=None, index_col=None, read_sql """ - if not _is_sqlalchemy_engine(con): + + con = _engine_builder(con) + if not _is_sqlalchemy_connectable(con): raise NotImplementedError("read_sql_table only supported for " - "SQLAlchemy engines.") + "SQLAlchemy connectable.") import sqlalchemy from sqlalchemy.schema import MetaData meta = MetaData(con, schema=schema) try: - meta.reflect(only=[table_name]) + meta.reflect(only=[table_name], views=True) except sqlalchemy.exc.InvalidRequestError: raise ValueError("Table %s not found" % table_name) @@ -362,7 +364,8 @@ def read_sql_query(sql, con, index_col=None, coerce_float=True, params=None, ---------- sql : string SQL query to be executed - con : SQLAlchemy engine or sqlite3 DBAPI2 connection + con : SQLAlchemy connectable(engine/connection) or database string URI + or sqlite3 DBAPI2 connection Using SQLAlchemy makes it possible to use any DB supported by that library. If a DBAPI2 object, only sqlite3 is supported. @@ -420,7 +423,8 @@ def read_sql(sql, con, index_col=None, coerce_float=True, params=None, ---------- sql : string SQL query to be executed or database table name. - con : SQLAlchemy engine or DBAPI2 connection (fallback mode) + con : SQLAlchemy connectable(engine/connection) or database string URI + or DBAPI2 connection (fallback mode) Using SQLAlchemy makes it possible to use any DB supported by that library. If a DBAPI2 object, only sqlite3 is supported. @@ -504,14 +508,15 @@ def to_sql(frame, name, con, flavor='sqlite', schema=None, if_exists='fail', frame : DataFrame name : string Name of SQL table - con : SQLAlchemy engine or sqlite3 DBAPI2 connection + con : SQLAlchemy connectable(engine/connection) or database string URI + or sqlite3 DBAPI2 connection Using SQLAlchemy makes it possible to use any DB supported by that library. If a DBAPI2 object, only sqlite3 is supported. flavor : {'sqlite', 'mysql'}, default 'sqlite' - The flavor of SQL to use. Ignored when using SQLAlchemy engine. + The flavor of SQL to use. Ignored when using SQLAlchemy connectable. 'mysql' is deprecated and will be removed in future versions, but it - will be further supported through SQLAlchemy engines. + will be further supported through SQLAlchemy connectables. schema : string, default None Name of SQL schema in database to write to (if database flavor supports this). If None, use default schema (default). @@ -557,14 +562,14 @@ def has_table(table_name, con, flavor='sqlite', schema=None): ---------- table_name: string Name of SQL table - con: SQLAlchemy engine or sqlite3 DBAPI2 connection + con: SQLAlchemy connectable(engine/connection) or sqlite3 DBAPI2 connection Using SQLAlchemy makes it possible to use any DB supported by that library. If a DBAPI2 object, only sqlite3 is supported. flavor: {'sqlite', 'mysql'}, default 'sqlite' - The flavor of SQL to use. Ignored when using SQLAlchemy engine. + The flavor of SQL to use. Ignored when using SQLAlchemy connectable. 'mysql' is deprecated and will be removed in future versions, but it - will be further supported through SQLAlchemy engines. + will be further supported through SQLAlchemy connectables. schema : string, default None Name of SQL schema in database to write to (if database flavor supports this). If None, use default schema (default). @@ -581,9 +586,25 @@ def has_table(table_name, con, flavor='sqlite', schema=None): _MYSQL_WARNING = ("The 'mysql' flavor with DBAPI connection is deprecated " "and will be removed in future versions. " - "MySQL will be further supported with SQLAlchemy engines.") + "MySQL will be further supported with SQLAlchemy connectables.") +def _engine_builder(con): + """ + Returns a SQLAlchemy engine from a URI (if con is a string) + else it just return con without modifying it + """ + if isinstance(con, string_types): + try: + import sqlalchemy + con = sqlalchemy.create_engine(con) + return con + + except ImportError: + _SQLALCHEMY_INSTALLED = False + + return con + def pandasSQL_builder(con, flavor=None, schema=None, meta=None, is_cursor=False): """ @@ -592,7 +613,8 @@ def pandasSQL_builder(con, flavor=None, schema=None, meta=None, """ # When support for DBAPI connections is removed, # is_cursor should not be necessary. - if _is_sqlalchemy_engine(con): + con = _engine_builder(con) + if _is_sqlalchemy_connectable(con): return SQLDatabase(con, schema=schema, meta=meta) else: if flavor == 'mysql': @@ -637,7 +659,7 @@ def exists(self): def sql_schema(self): from sqlalchemy.schema import CreateTable - return str(CreateTable(self.table).compile(self.pd_sql.engine)) + return str(CreateTable(self.table).compile(self.pd_sql.connectable)) def _execute_create(self): # Inserting table into database, add to MetaData object @@ -834,7 +856,11 @@ def _create_table_setup(self): for name, typ, is_index in column_names_and_types] if self.keys is not None: - pkc = PrimaryKeyConstraint(self.keys, name=self.name + '_pk') + if not com.is_list_like(self.keys): + keys = [self.keys] + else: + keys = self.keys + pkc = PrimaryKeyConstraint(*keys, name=self.name + '_pk') columns.append(pkc) schema = self.schema or self.pd_sql.meta.schema @@ -899,8 +925,8 @@ def _harmonize_columns(self, parse_dates=None): def _get_notnull_col_dtype(self, col): """ - Infer datatype of the Series col. In case the dtype of col is 'object' - and it contains NA values, this infers the datatype of the not-NA + Infer datatype of the Series col. In case the dtype of col is 'object' + and it contains NA values, this infers the datatype of the not-NA values. Needed for inserting typed data containing NULLs, GH8778. """ col_for_inference = col @@ -978,11 +1004,11 @@ class PandasSQL(PandasObject): """ def read_sql(self, *args, **kwargs): - raise ValueError("PandasSQL must be created with an SQLAlchemy engine" + raise ValueError("PandasSQL must be created with an SQLAlchemy connectable" " or connection+sql flavor") def to_sql(self, *args, **kwargs): - raise ValueError("PandasSQL must be created with an SQLAlchemy engine" + raise ValueError("PandasSQL must be created with an SQLAlchemy connectable" " or connection+sql flavor") @@ -993,8 +1019,8 @@ class SQLDatabase(PandasSQL): Parameters ---------- - engine : SQLAlchemy engine - Engine to connect with the database. Using SQLAlchemy makes it + engine : SQLAlchemy connectable + Connectable to connect with the database. Using SQLAlchemy makes it possible to use any DB supported by that library. schema : string, default None Name of SQL schema in database to write to (if database flavor @@ -1007,19 +1033,24 @@ class SQLDatabase(PandasSQL): """ def __init__(self, engine, schema=None, meta=None): - self.engine = engine + self.connectable = engine if not meta: from sqlalchemy.schema import MetaData - meta = MetaData(self.engine, schema=schema) + meta = MetaData(self.connectable, schema=schema) self.meta = meta + @contextmanager def run_transaction(self): - return self.engine.begin() + with self.connectable.begin() as tx: + if hasattr(tx, 'execute'): + yield tx + else: + yield self.connectable def execute(self, *args, **kwargs): - """Simple passthrough to SQLAlchemy engine""" - return self.engine.execute(*args, **kwargs) + """Simple passthrough to SQLAlchemy connectable""" + return self.connectable.execute(*args, **kwargs) def read_table(self, table_name, index_col=None, coerce_float=True, parse_dates=None, columns=None, schema=None, @@ -1187,7 +1218,13 @@ def to_sql(self, frame, name, if_exists='fail', index=True, table.create() table.insert(chunksize) # check for potentially case sensitivity issues (GH7815) - if name not in self.engine.table_names(schema=schema or self.meta.schema): + engine = self.connectable.engine + with self.connectable.connect() as conn: + table_names = engine.table_names( + schema=schema or self.meta.schema, + connection=conn, + ) + if name not in table_names: warnings.warn("The provided table name '{0}' is not found exactly " "as such in the database after writing the table, " "possibly due to case sensitivity issues. Consider " @@ -1198,7 +1235,11 @@ def tables(self): return self.meta.tables def has_table(self, name, schema=None): - return self.engine.has_table(name, schema or self.meta.schema) + return self.connectable.run_callable( + self.connectable.dialect.has_table, + name, + schema or self.meta.schema, + ) def get_table(self, table_name, schema=None): schema = schema or self.meta.schema @@ -1217,7 +1258,7 @@ def get_table(self, table_name, schema=None): def drop_table(self, table_name, schema=None): schema = schema or self.meta.schema - if self.engine.has_table(table_name, schema): + if self.has_table(table_name, schema): self.meta.reflect(only=[table_name], schema=schema) self.get_table(table_name, schema).drop() self.meta.clear() @@ -1272,7 +1313,7 @@ def _get_unicode_name(name): return uname def _get_valid_mysql_name(name): - # Filter for unquoted identifiers + # Filter for unquoted identifiers # See http://dev.mysql.com/doc/refman/5.0/en/identifiers.html uname = _get_unicode_name(name) if not len(uname): @@ -1293,7 +1334,7 @@ def _get_valid_sqlite_name(name): # Ensure the string does not include any NUL characters. # Replace all " with "". # Wrap the entire thing in double quotes. - + uname = _get_unicode_name(name) if not len(uname): raise ValueError("Empty table or column name specified") @@ -1377,7 +1418,11 @@ def _create_table_setup(self): for cname, ctype, _ in column_names_and_types] if self.keys is not None and len(self.keys): - cnames_br = ",".join([escape(c) for c in self.keys]) + if not com.is_list_like(self.keys): + keys = [self.keys] + else: + keys = self.keys + cnames_br = ", ".join([escape(c) for c in keys]) create_tbl_stmts.append( "CONSTRAINT {tbl}_pk PRIMARY KEY ({cnames_br})".format( tbl=self.name, cnames_br=cnames_br)) @@ -1391,7 +1436,7 @@ def _create_table_setup(self): cnames = "_".join(ix_cols) cnames_br = ",".join([escape(c) for c in ix_cols]) create_stmts.append( - "CREATE INDEX " + escape("ix_"+self.name+"_"+cnames) + + "CREATE INDEX " + escape("ix_"+self.name+"_"+cnames) + "ON " + escape(self.name) + " (" + cnames_br + ")") return create_stmts @@ -1416,7 +1461,7 @@ def _sql_type_name(self, col): elif col_type == "complex": raise ValueError('Complex datatypes not supported') - + if col_type not in _SQL_TYPES: col_type = "string" @@ -1602,12 +1647,12 @@ def get_schema(frame, name, flavor='sqlite', keys=None, con=None, dtype=None): name : string name of SQL table flavor : {'sqlite', 'mysql'}, default 'sqlite' - The flavor of SQL to use. Ignored when using SQLAlchemy engine. + The flavor of SQL to use. Ignored when using SQLAlchemy connectable. 'mysql' is deprecated and will be removed in future versions, but it will be further supported through SQLAlchemy engines. keys : string or sequence columns to use a primary key - con: an open SQL database connection object or an SQLAlchemy engine + con: an open SQL database connection object or a SQLAlchemy connectable Using SQLAlchemy makes it possible to use any DB supported by that library. If a DBAPI2 object, only sqlite3 is supported. @@ -1665,8 +1710,8 @@ def write_frame(frame, name, con, flavor='sqlite', if_exists='fail', **kwargs): - With ``to_sql`` the index is written to the sql database by default. To keep the behaviour this function you need to specify ``index=False``. - - The new ``to_sql`` function supports sqlalchemy engines to work with - different sql flavors. + - The new ``to_sql`` function supports sqlalchemy connectables to work + with different sql flavors. See also -------- diff --git a/pandas/io/stata.py b/pandas/io/stata.py index eecc225d06beb..5afbc2671e3a7 100644 --- a/pandas/io/stata.py +++ b/pandas/io/stata.py @@ -4,7 +4,7 @@ The StataReader below was originally written by Joe Presbrey as part of PyDTA. It has been extended and improved by Skipper Seabold from the Statsmodels project who also developed the StataWriter and was finally added to pandas in -an once again improved version. +a once again improved version. You can find more information on http://presbrey.mit.edu/PyDTA and http://statsmodels.sourceforge.net/devel/ @@ -23,11 +23,14 @@ from pandas.compat import lrange, lmap, lzip, text_type, string_types, range, \ zip, BytesIO from pandas.util.decorators import Appender +import pandas as pd import pandas.core.common as com from pandas.io.common import get_filepath_or_buffer from pandas.lib import max_len_string_array, infer_dtype from pandas.tslib import NaT, Timestamp +_version_error = "Version of given Stata file is not 104, 105, 108, 113 (Stata 8/9), 114 (Stata 10/11), 115 (Stata 12), 117 (Stata 13), or 118 (Stata 14)" + _statafile_processing_params1 = """\ convert_dates : boolean, defaults to True Convert date variables to DataFrame time values @@ -291,7 +294,7 @@ def convert_delta_safe(base, deltas, unit): warn("Encountered %tC format. Leaving in Stata Internal Format.") conv_dates = Series(dates, dtype=np.object) if has_bad_values: - conv_dates[bad_locs] = np.nan + conv_dates[bad_locs] = pd.NaT return conv_dates elif fmt in ["%td", "td", "%d", "d"]: # Delta days relative to base base = stata_epoch @@ -826,7 +829,7 @@ def __init__(self, encoding): self.TYPE_MAP_XML = \ dict( [ - (32768, 'L'), + (32768, 'Q'), # Not really a Q, unclear how to handle byteswap (65526, 'd'), (65527, 'f'), (65528, 'l'), @@ -875,7 +878,7 @@ def __init__(self, encoding): 'l': 'i4', 'f': 'f4', 'd': 'f8', - 'L': 'u8' + 'Q': 'u8' } # Reserved words cannot be used as variable names @@ -931,7 +934,7 @@ def __init__(self, path_or_buf, convert_dates=True, self._native_byteorder = _set_endianness(sys.byteorder) if isinstance(path_or_buf, str): - path_or_buf, encoding = get_filepath_or_buffer( + path_or_buf, encoding, _ = get_filepath_or_buffer( path_or_buf, encoding=self._default_encoding ) @@ -948,225 +951,324 @@ def __init__(self, path_or_buf, convert_dates=True, self._read_header() + + def __enter__(self): + """ enter context manager """ + return self + + def __exit__(self, exc_type, exc_value, traceback): + """ exit context manager """ + self.close() + + def close(self): + """ close the handle if its open """ + try: + self.path_or_buf.close() + except IOError: + pass + + def _read_header(self): first_char = self.path_or_buf.read(1) if struct.unpack('c', first_char)[0] == b'<': - # format 117 or higher (XML like) - self.path_or_buf.read(27) # stata_dta>
- self.format_version = int(self.path_or_buf.read(3)) - if self.format_version not in [117]: - raise ValueError("Version of given Stata file is not 104, " - "105, 108, 113 (Stata 8/9), 114 (Stata " - "10/11), 115 (Stata 12) or 117 (Stata 13)") - self.path_or_buf.read(21) # - self.byteorder = self.path_or_buf.read(3) == "MSF" and '>' or '<' - self.path_or_buf.read(15) # - self.nvar = struct.unpack(self.byteorder + 'H', - self.path_or_buf.read(2))[0] - self.path_or_buf.read(7) # - self.nobs = struct.unpack(self.byteorder + 'I', - self.path_or_buf.read(4))[0] - self.path_or_buf.read(11) # + return self._null_terminate(self.path_or_buf.read(strlen)) + elif self.format_version > 105: + return self._null_terminate(self.path_or_buf.read(81)) + else: + return self._null_terminate(self.path_or_buf.read(32)) + + + def _get_time_stamp(self): + if self.format_version == 118: strlen = struct.unpack('b', self.path_or_buf.read(1))[0] - self.time_stamp = self._null_terminate(self.path_or_buf.read(strlen)) - self.path_or_buf.read(26) #
- self.path_or_buf.read(8) # 0x0000000000000000 - self.path_or_buf.read(8) # position of - seek_vartypes = struct.unpack( - self.byteorder + 'q', self.path_or_buf.read(8))[0] + 16 - seek_varnames = struct.unpack( - self.byteorder + 'q', self.path_or_buf.read(8))[0] + 10 - seek_sortlist = struct.unpack( - self.byteorder + 'q', self.path_or_buf.read(8))[0] + 10 - seek_formats = struct.unpack( - self.byteorder + 'q', self.path_or_buf.read(8))[0] + 9 - seek_value_label_names = struct.unpack( - self.byteorder + 'q', self.path_or_buf.read(8))[0] + 19 + return self.path_or_buf.read(strlen).decode("utf-8") + elif self.format_version == 117: + strlen = struct.unpack('b', self.path_or_buf.read(1))[0] + return self._null_terminate(self.path_or_buf.read(strlen)) + elif self.format_version > 104: + return self._null_terminate(self.path_or_buf.read(18)) + else: + raise ValueError() + + + def _get_seek_variable_labels(self): + if self.format_version == 117: + self.path_or_buf.read(8) # , throw away # Stata 117 data files do not follow the described format. This is # a work around that uses the previous label, 33 bytes for each # variable, 20 for the closing tag and 17 for the opening tag - self.path_or_buf.read(8) # , throw away - seek_variable_labels = seek_value_label_names + (33*self.nvar) + 20 + 17 - # Below is the original, correct code (per Stata sta format doc, - # although this is not followed in actual 117 dtas) - #seek_variable_labels = struct.unpack( - # self.byteorder + 'q', self.path_or_buf.read(8))[0] + 17 - self.path_or_buf.read(8) # - self.data_location = struct.unpack( - self.byteorder + 'q', self.path_or_buf.read(8))[0] + 6 - self.seek_strls = struct.unpack( - self.byteorder + 'q', self.path_or_buf.read(8))[0] + 7 - self.seek_value_labels = struct.unpack( - self.byteorder + 'q', self.path_or_buf.read(8))[0] + 14 - #self.path_or_buf.read(8) # - #self.path_or_buf.read(8) # EOF - self.path_or_buf.seek(seek_vartypes) - typlist = [struct.unpack(self.byteorder + 'H', - self.path_or_buf.read(2))[0] - for i in range(self.nvar)] - self.typlist = [None]*self.nvar - try: - i = 0 - for typ in typlist: - if typ <= 2045: - self.typlist[i] = typ - #elif typ == 32768: - # raise ValueError("Long strings are not supported") - else: - self.typlist[i] = self.TYPE_MAP_XML[typ] - i += 1 - except: - raise ValueError("cannot convert stata types [{0}]" - .format(','.join(typlist))) - self.dtyplist = [None]*self.nvar - try: - i = 0 - for typ in typlist: - if typ <= 2045: - self.dtyplist[i] = str(typ) - else: - self.dtyplist[i] = self.DTYPE_MAP_XML[typ] - i += 1 - except: - raise ValueError("cannot convert stata dtypes [{0}]" - .format(','.join(typlist))) + return self._seek_value_label_names + (33*self.nvar) + 20 + 17 + elif self.format_version == 118: + return struct.unpack(self.byteorder + 'q', self.path_or_buf.read(8))[0] + 17 + else: + raise ValueError() - self.path_or_buf.seek(seek_varnames) - self.varlist = [self._null_terminate(self.path_or_buf.read(33)) - for i in range(self.nvar)] - self.path_or_buf.seek(seek_sortlist) - self.srtlist = struct.unpack( - self.byteorder + ('h' * (self.nvar + 1)), - self.path_or_buf.read(2 * (self.nvar + 1)) - )[:-1] + def _read_old_header(self, first_char): + self.format_version = struct.unpack('b', first_char)[0] + if self.format_version not in [104, 105, 108, 113, 114, 115]: + raise ValueError(_version_error) + self.byteorder = struct.unpack('b', self.path_or_buf.read(1))[0] == 0x1 and '>' or '<' + self.filetype = struct.unpack('b', self.path_or_buf.read(1))[0] + self.path_or_buf.read(1) # unused - self.path_or_buf.seek(seek_formats) - self.fmtlist = [self._null_terminate(self.path_or_buf.read(49)) - for i in range(self.nvar)] + self.nvar = struct.unpack(self.byteorder + 'H', + self.path_or_buf.read(2))[0] + self.nobs = self._get_nobs() - self.path_or_buf.seek(seek_value_label_names) - self.lbllist = [self._null_terminate(self.path_or_buf.read(33)) - for i in range(self.nvar)] + self.data_label = self._get_data_label() - self.path_or_buf.seek(seek_variable_labels) - self.vlblist = [self._null_terminate(self.path_or_buf.read(81)) - for i in range(self.nvar)] + self.time_stamp = self._get_time_stamp() + + # descriptors + if self.format_version > 108: + typlist = [ord(self.path_or_buf.read(1)) + for i in range(self.nvar)] else: - # header - self.format_version = struct.unpack('b', first_char)[0] - if self.format_version not in [104, 105, 108, 113, 114, 115]: - raise ValueError("Version of given Stata file is not 104, " - "105, 108, 113 (Stata 8/9), 114 (Stata " - "10/11), 115 (Stata 12) or 117 (Stata 13)") - self.byteorder = struct.unpack('b', self.path_or_buf.read(1))[0] == 0x1 and '>' or '<' - self.filetype = struct.unpack('b', self.path_or_buf.read(1))[0] - self.path_or_buf.read(1) # unused - - self.nvar = struct.unpack(self.byteorder + 'H', - self.path_or_buf.read(2))[0] - self.nobs = struct.unpack(self.byteorder + 'I', - self.path_or_buf.read(4))[0] - if self.format_version > 105: - self.data_label = self._null_terminate(self.path_or_buf.read(81)) - else: - self.data_label = self._null_terminate(self.path_or_buf.read(32)) - if self.format_version > 104: - self.time_stamp = self._null_terminate(self.path_or_buf.read(18)) - - # descriptors - if self.format_version > 108: - typlist = [ord(self.path_or_buf.read(1)) - for i in range(self.nvar)] - else: - typlist = [ - self.OLD_TYPE_MAPPING[ - self._decode_bytes(self.path_or_buf.read(1)) - ] for i in range(self.nvar) - ] + typlist = [ + self.OLD_TYPE_MAPPING[ + self._decode_bytes(self.path_or_buf.read(1)) + ] for i in range(self.nvar) + ] - try: - self.typlist = [self.TYPE_MAP[typ] for typ in typlist] - except: - raise ValueError("cannot convert stata types [{0}]" - .format(','.join(typlist))) - try: - self.dtyplist = [self.DTYPE_MAP[typ] for typ in typlist] - except: - raise ValueError("cannot convert stata dtypes [{0}]" - .format(','.join(typlist))) + try: + self.typlist = [self.TYPE_MAP[typ] for typ in typlist] + except: + raise ValueError("cannot convert stata types [{0}]" + .format(','.join(typlist))) + try: + self.dtyplist = [self.DTYPE_MAP[typ] for typ in typlist] + except: + raise ValueError("cannot convert stata dtypes [{0}]" + .format(','.join(typlist))) - if self.format_version > 108: - self.varlist = [self._null_terminate(self.path_or_buf.read(33)) - for i in range(self.nvar)] - else: - self.varlist = [self._null_terminate(self.path_or_buf.read(9)) - for i in range(self.nvar)] - self.srtlist = struct.unpack( - self.byteorder + ('h' * (self.nvar + 1)), - self.path_or_buf.read(2 * (self.nvar + 1)) - )[:-1] - if self.format_version > 113: - self.fmtlist = [self._null_terminate(self.path_or_buf.read(49)) - for i in range(self.nvar)] - elif self.format_version > 104: - self.fmtlist = [self._null_terminate(self.path_or_buf.read(12)) - for i in range(self.nvar)] - else: - self.fmtlist = [self._null_terminate(self.path_or_buf.read(7)) - for i in range(self.nvar)] - if self.format_version > 108: - self.lbllist = [self._null_terminate(self.path_or_buf.read(33)) - for i in range(self.nvar)] - else: - self.lbllist = [self._null_terminate(self.path_or_buf.read(9)) - for i in range(self.nvar)] - if self.format_version > 105: - self.vlblist = [self._null_terminate(self.path_or_buf.read(81)) - for i in range(self.nvar)] - else: - self.vlblist = [self._null_terminate(self.path_or_buf.read(32)) - for i in range(self.nvar)] + if self.format_version > 108: + self.varlist = [self._null_terminate(self.path_or_buf.read(33)) + for i in range(self.nvar)] + else: + self.varlist = [self._null_terminate(self.path_or_buf.read(9)) + for i in range(self.nvar)] + self.srtlist = struct.unpack( + self.byteorder + ('h' * (self.nvar + 1)), + self.path_or_buf.read(2 * (self.nvar + 1)) + )[:-1] - # ignore expansion fields (Format 105 and later) - # When reading, read five bytes; the last four bytes now tell you - # the size of the next read, which you discard. You then continue - # like this until you read 5 bytes of zeros. + self.fmtlist = self._get_fmtlist() - if self.format_version > 104: - while True: - data_type = struct.unpack(self.byteorder + 'b', - self.path_or_buf.read(1))[0] - if self.format_version > 108: - data_len = struct.unpack(self.byteorder + 'i', - self.path_or_buf.read(4))[0] - else: - data_len = struct.unpack(self.byteorder + 'h', - self.path_or_buf.read(2))[0] - if data_type == 0: - break - self.path_or_buf.read(data_len) + self.lbllist = self._get_lbllist() - # necessary data to continue parsing - self.data_location = self.path_or_buf.tell() + self.vlblist = self._get_vlblist() - self.has_string_data = len([x for x in self.typlist - if type(x) is int]) > 0 + # ignore expansion fields (Format 105 and later) + # When reading, read five bytes; the last four bytes now tell you + # the size of the next read, which you discard. You then continue + # like this until you read 5 bytes of zeros. - # calculate size of a data record - self.col_sizes = lmap(lambda x: self._calcsize(x), self.typlist) + if self.format_version > 104: + while True: + data_type = struct.unpack(self.byteorder + 'b', + self.path_or_buf.read(1))[0] + if self.format_version > 108: + data_len = struct.unpack(self.byteorder + 'i', + self.path_or_buf.read(4))[0] + else: + data_len = struct.unpack(self.byteorder + 'h', + self.path_or_buf.read(2))[0] + if data_type == 0: + break + self.path_or_buf.read(data_len) - # remove format details from %td - self.fmtlist = ["%td" if x.startswith("%td") else x for x in self.fmtlist] + # necessary data to continue parsing + self.data_location = self.path_or_buf.tell() def _calcsize(self, fmt): return (type(fmt) is int and fmt or struct.calcsize(self.byteorder + fmt)) + + def _decode(self, s): + s = s.partition(b"\0")[0] + return s.decode('utf-8') + + def _null_terminate(self, s): if compat.PY3 or self._encoding is not None: # have bytes not strings, # so must decode @@ -1204,7 +1306,10 @@ def _read_value_labels(self): slength = self.path_or_buf.read(4) if not slength: break # end of variable label table (format < 117) - labname = self._null_terminate(self.path_or_buf.read(33)) + if self.format_version <= 117: + labname = self._null_terminate(self.path_or_buf.read(33)) + else: + labname = self._decode(self.path_or_buf.read(129)) self.path_or_buf.read(3) # padding n = struct.unpack(self.byteorder + 'I', @@ -1222,28 +1327,45 @@ def _read_value_labels(self): txt = self.path_or_buf.read(txtlen) self.value_label_dict[labname] = dict() for i in range(n): - self.value_label_dict[labname][val[i]] = ( - self._null_terminate(txt[off[i]:]) - ) - + if self.format_version <= 117: + self.value_label_dict[labname][val[i]] = ( + self._null_terminate(txt[off[i]:]) + ) + else: + self.value_label_dict[labname][val[i]] = ( + self._decode(txt[off[i]:]) + ) if self.format_version >= 117: self.path_or_buf.read(6) # self._value_labels_read = True + def _read_strls(self): self.path_or_buf.seek(self.seek_strls) - self.GSO = dict() + self.GSO = {0 : ''} while True: if self.path_or_buf.read(3) != b'GSO': break - v_o = struct.unpack(self.byteorder + 'Q', self.path_or_buf.read(8))[0] + if self.format_version == 117: + v_o = struct.unpack(self.byteorder + 'Q', self.path_or_buf.read(8))[0] + else: + buf = self.path_or_buf.read(12) + # Only tested on little endian file on little endian machine. + if self.byteorder == '<': + buf = buf[0:2] + buf[4:10] + else: + buf = buf[0:2] + buf[6:] + v_o = struct.unpack('Q', buf)[0] typ = struct.unpack('B', self.path_or_buf.read(1))[0] length = struct.unpack(self.byteorder + 'I', self.path_or_buf.read(4))[0] va = self.path_or_buf.read(length) if typ == 130: - va = va[0:-1].decode(self._encoding or self._default_encoding) + encoding = 'utf-8' + if self.format_version == 117: + encoding = self._encoding or self._default_encoding + va = va[0:-1].decode(encoding) self.GSO[v_o] = va # legacy @@ -1350,6 +1472,7 @@ def read(self, nrows=None, convert_dates=None, read_lines = min(nrows, self.nobs - self._lines_read) data = np.frombuffer(self.path_or_buf.read(read_len), dtype=dtype, count=read_lines) + self._lines_read += read_lines if self._lines_read == self.nobs: self._can_read_value_labels = True @@ -1470,7 +1593,7 @@ def _insert_strls(self, data): if not hasattr(self, 'GSO') or len(self.GSO) == 0: return data for i, typ in enumerate(self.typlist): - if typ != 'L': + if typ != 'Q': continue data.iloc[:, i] = [self.GSO[k] for k in data.iloc[:, i]] return data @@ -1491,14 +1614,12 @@ def _do_select_columns(self, data, columns): typlist = [] fmtlist = [] lbllist = [] - matched = set() - for i, col in enumerate(data.columns): - if col in column_set: - matched.update([col]) - dtyplist.append(self.dtyplist[i]) - typlist.append(self.typlist[i]) - fmtlist.append(self.fmtlist[i]) - lbllist.append(self.lbllist[i]) + for col in columns: + i = data.columns.get_loc(col) + dtyplist.append(self.dtyplist[i]) + typlist.append(self.typlist[i]) + fmtlist.append(self.fmtlist[i]) + lbllist.append(self.lbllist[i]) self.dtyplist = dtyplist self.typlist = typlist @@ -1756,7 +1877,7 @@ def _write(self, to_write): self._file.write(to_write) def _prepare_categoricals(self, data): - """Check for categorigal columns, retain categorical information for + """Check for categorical columns, retain categorical information for Stata file and convert categorical data to int""" is_cat = [com.is_categorical_dtype(data[col]) for col in data] diff --git a/pandas/io/tests/data/DEMO_G.XPT b/pandas/io/tests/data/DEMO_G.XPT new file mode 100644 index 0000000000000000000000000000000000000000..587bc3c4eb64964dff48044fded8e0e2fc3a5a14 GIT binary patch literal 3753760 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�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
  • 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%0DM^AFSX{7*;ypi^5> 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

    (OAwth{TJt+O8qm4*d{kwwB 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 literal 0 HcmV?d00001 diff --git a/pandas/io/tests/data/DEMO_G.csv b/pandas/io/tests/data/DEMO_G.csv new file mode 100644 index 0000000000000..db2158a532100 --- /dev/null +++ b/pandas/io/tests/data/DEMO_G.csv @@ -0,0 +1,9757 @@ +"SEQN","SDDSRVYR","RIDSTATR","RIAGENDR","RIDAGEYR","RIDAGEMN","RIDRETH1","RIDRETH3","RIDEXMON","RIDEXAGY","RIDEXAGM","DMQMILIZ","DMQADFC","DMDBORN4","DMDCITZN","DMDYRSUS","DMDEDUC3","DMDEDUC2","DMDMARTL","RIDEXPRG","SIALANG","SIAPROXY","SIAINTRP","FIALANG","FIAPROXY","FIAINTRP","MIALANG","MIAPROXY","MIAINTRP","AIALANGA","WTINT2YR","WTMEC2YR","SDMVPSU","SDMVSTRA","INDHHIN2","INDFMIN2","INDFMPIR","DMDHHSIZ","DMDFMSIZ","DMDHHSZA","DMDHHSZB","DMDHHSZE","DMDHRGND","DMDHRAGE","DMDHRBR4","DMDHREDU","DMDHRMAR","DMDHSEDU" +62161,7,2,1,22,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,1,2,1,2,2,1,2,2,1,102641.406474,104236.582554,1,91,14,14,3.15,5,5,0,1,0,2,50,1,5,1,5 +62162,7,2,2,3,NA,1,1,1,3,41,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15457.736897,16116.35401,3,92,4,4,0.6,6,6,2,2,0,2,24,1,3,6,NA +62163,7,2,1,14,NA,5,6,2,14,177,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7397.684828,7869.485117,3,90,15,15,4.07,5,5,0,2,1,1,42,1,5,1,4 +62164,7,2,2,44,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,1,2,1,2,2,1,2,2,NA,NA,NA,NA,127351.373299,127965.226204,1,94,8,8,1.67,5,5,1,2,0,1,52,1,4,1,4 +62165,7,2,2,14,NA,4,4,2,14,179,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12209.74498,13384.042162,2,90,4,4,0.57,5,5,1,2,0,2,33,2,2,77,NA +62166,7,2,1,9,NA,3,3,2,10,120,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,60593.636684,64068.123183,1,91,77,77,NA,6,6,0,4,0,1,44,1,5,1,5 +62167,7,2,1,0,11,5,6,1,NA,12,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,5024.464768,5303.683185,2,92,99,77,NA,7,4,3,3,1,1,61,2,1,1,3 +62168,7,2,1,6,NA,5,7,1,6,81,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5897.024603,6245.043868,2,103,14,14,3.48,5,5,0,2,1,1,43,1,4,1,5 +62169,7,2,1,21,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,1,NA,NA,NA,1,2,2,1,14391.77847,14783.600953,1,92,2,2,0.33,5,5,0,1,0,1,51,2,1,4,NA +62170,7,2,1,15,NA,5,7,1,15,181,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7794.52699,8291.636582,3,91,15,15,5,4,4,0,2,0,1,38,2,5,1,5 +62171,7,2,1,14,NA,1,1,1,14,175,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,2,2,2,1,2,2,1,22768.423624,22886.980387,3,92,9,9,2.46,4,4,0,2,0,1,43,2,3,1,4 +62172,7,2,2,43,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,26960.774346,27122.911908,2,96,5,5,2.02,1,1,0,0,0,2,43,1,3,5,NA +62173,7,2,2,2,NA,1,1,1,2,28,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,11401.934012,12203.058423,1,95,13,13,NA,5,5,3,0,0,2,33,2,1,1,2 +62174,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,24912.668432,27335.895242,3,90,10,10,4.3,2,2,0,0,2,2,80,1,4,1,5 +62175,7,2,1,5,NA,3,3,1,6,72,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,26980.605125,30440.534478,1,94,3,3,0.39,6,6,2,2,0,2,25,1,4,1,2 +62176,7,2,2,34,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,53830.599426,54203.155016,1,99,15,15,5,5,5,3,0,0,2,34,1,5,1,5 +62177,7,2,1,51,NA,5,6,1,NA,NA,2,NA,2,2,3,NA,3,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,7879.750437,7851.284287,2,92,99,77,NA,7,4,3,3,1,1,61,2,1,1,3 +62178,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,12291.154515,13189.875012,1,95,1,1,0.05,1,1,0,0,1,1,80,1,3,2,NA +62179,7,2,1,55,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,16590.074977,17115.36835,1,92,15,15,5,4,4,0,2,0,1,55,1,5,1,5 +62180,7,2,1,35,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,20457.614917,22616.494827,1,97,5,5,0.87,4,4,2,0,0,1,35,1,5,1,5 +62181,7,2,1,9,NA,1,1,1,9,118,NA,NA,1,1,NA,3,NA,NA,NA,2,1,2,2,2,2,1,2,2,NA,13822.148996,14860.201344,3,92,4,4,0.55,6,6,0,4,0,1,36,2,1,1,3 +62182,7,1,1,75,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,63069.107216,0,1,90,12,12,NA,2,2,0,0,2,1,75,1,5,1,4 +62183,7,2,1,6,NA,4,4,1,6,81,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10138.00454,10211.52145,1,100,14,14,3.6,4,4,1,1,0,1,41,1,4,1,5 +62184,7,2,1,26,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,15600.678771,15236.26157,2,95,15,15,3.85,7,7,0,3,1,2,62,1,4,2,NA +62185,7,2,1,16,NA,1,1,1,16,201,NA,NA,1,1,NA,10,NA,NA,NA,2,2,2,2,2,2,NA,NA,NA,NA,18635.323223,19040.145288,2,103,77,77,NA,5,5,0,2,0,2,45,2,4,5,NA +62186,7,2,2,17,NA,4,4,1,17,205,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11224.041366,11682.365019,1,96,5,5,0.53,7,7,2,2,0,2,38,1,9,6,NA +62187,7,2,2,9,NA,1,1,1,9,115,NA,NA,1,1,NA,3,NA,NA,NA,2,1,2,1,2,2,1,2,2,2,10118.363218,11093.371216,2,103,77,77,NA,7,7,0,4,0,1,38,2,1,6,NA +62188,7,2,1,2,NA,2,2,1,2,26,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,11793.948458,12167.27893,1,100,5,5,0.78,6,5,1,2,0,2,40,2,1,5,NA +62189,7,2,2,30,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,17983.231494,18657.922524,1,94,10,10,3.04,4,4,2,0,0,2,30,1,4,1,5 +62190,7,2,2,15,NA,1,1,1,15,189,NA,NA,2,2,4,9,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,20419.465237,21192.774678,2,102,6,3,0.54,6,4,0,4,0,2,43,2,1,5,NA +62191,7,2,1,70,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,NA,8661.769277,9105.621464,1,96,14,3,0.9,2,1,0,0,2,2,71,NA,NA,3,NA +62192,7,2,2,11,NA,1,1,2,11,141,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14087.469432,14372.406512,2,97,7,7,2.05,3,3,0,2,0,2,45,1,5,2,NA +62193,7,2,1,17,NA,4,4,2,17,209,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11386.695644,11908.648036,2,99,6,6,1.18,5,5,0,3,0,2,38,1,2,5,NA +62194,7,2,2,9,NA,3,3,2,9,113,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,36778.822436,37956.900598,1,99,15,15,5,5,5,0,3,0,2,43,1,5,1,5 +62195,7,2,1,35,NA,4,4,2,NA,NA,2,NA,2,1,4,NA,4,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,15842.100091,16468.990083,2,90,8,6,2.39,4,1,1,1,0,2,21,1,5,6,NA +62196,7,2,1,1,17,3,3,2,NA,18,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,35830.680775,40425.523018,2,95,9,9,2.22,5,5,1,0,0,1,55,1,4,1,5 +62197,7,2,2,16,NA,4,4,1,16,197,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,20015.720245,20424.69013,2,102,15,15,5,4,4,0,2,0,1,44,1,3,1,1 +62198,7,2,1,7,NA,3,3,2,7,93,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,30754.608672,32212.772113,1,98,3,3,0.61,4,4,0,2,0,2,32,1,3,6,NA +62199,7,2,1,57,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,127000.852889,130891.431194,2,92,15,15,5,2,1,0,0,0,1,57,1,5,6,NA +62200,7,2,1,42,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,19184.316833,20543.822351,1,97,15,15,4.07,5,5,0,3,0,1,42,2,5,1,5 +62201,7,1,2,58,NA,5,6,NA,NA,NA,2,NA,2,2,2,NA,2,2,NA,1,2,1,1,2,2,NA,NA,NA,NA,19442.276314,0,1,95,6,6,1.34,4,4,0,2,0,2,32,2,3,2,NA +62202,7,2,1,36,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,41155.167164,40844.556107,1,102,14,14,2.83,6,6,1,2,0,1,36,1,2,1,3 +62203,7,2,1,8,NA,4,4,2,8,99,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,11324.954668,11525.075349,1,93,12,12,NA,3,3,0,1,0,2,49,2,3,1,3 +62204,7,1,2,9,NA,5,6,NA,NA,NA,NA,NA,2,1,3,3,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5585.02957,0,2,103,15,15,5,4,4,0,2,0,1,48,2,5,1,5 +62205,7,2,1,28,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,103663.693967,105583.964573,1,90,15,15,5,4,4,0,1,0,2,53,1,5,1,5 +62206,7,2,2,35,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,NA,NA,NA,NA,67177.369911,67642.297015,3,92,14,14,2.74,6,6,2,2,0,1,35,1,5,1,4 +62207,7,2,1,0,0,4,4,1,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6988.613752,7730.080563,1,100,5,5,1.05,3,3,1,0,0,2,35,1,4,6,NA +62208,7,2,1,38,NA,2,2,1,NA,NA,2,NA,2,2,3,NA,4,1,NA,2,2,2,1,2,2,1,2,2,2,41241.224595,41216.943466,2,102,7,7,1.53,5,5,1,2,0,2,37,2,4,1,4 +62209,7,2,2,62,NA,1,1,1,NA,NA,2,NA,2,2,3,NA,1,4,NA,2,2,2,2,2,2,2,2,2,2,13473.304889,14578.166065,2,96,6,6,1.11,6,6,0,2,1,1,40,2,2,1,2 +62210,7,2,1,15,NA,3,3,2,15,188,NA,NA,1,1,NA,10,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,100370.520459,102294.664852,1,90,15,15,5,4,4,0,2,1,2,52,1,5,1,NA +62211,7,1,2,63,NA,1,1,NA,NA,NA,2,NA,2,2,77,NA,1,1,NA,2,2,2,1,2,2,NA,NA,NA,NA,16352.915834,0,3,92,9,9,2.22,5,5,1,0,2,1,66,2,1,1,1 +62212,7,1,2,8,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9465.598219,0,2,91,12,12,NA,3,3,0,1,0,1,56,1,4,1,4 +62213,7,2,1,2,NA,4,4,2,2,25,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5422.375171,5488.513785,2,99,4,4,0.94,3,3,1,0,0,1,48,2,3,6,NA +62214,7,2,2,22,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,4,2,1,2,2,1,2,2,1,2,2,1,18723.98095,21433.166124,2,95,7,7,1.41,5,5,2,0,0,2,53,1,3,3,NA +62215,7,2,2,65,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,129999.035519,129559.2554,1,98,13,13,NA,2,2,0,0,2,2,80,1,2,2,NA +62216,7,2,1,0,6,3,3,1,NA,7,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,19442.488468,19106.370101,2,92,15,15,5,3,3,1,0,0,2,31,2,5,1,5 +62217,7,2,2,77,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,1,5,NA,1,2,2,1,2,2,1,2,2,NA,15730.58404,17568.357111,2,98,4,4,0.97,3,3,0,1,1,2,77,1,1,5,NA +62218,7,2,2,38,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,3,1,2,2,1,2,2,1,2,2,1,39534.635218,41046.564195,2,102,14,14,4.05,3,3,0,1,0,1,18,1,2,NA,NA +62219,7,2,2,2,NA,1,1,1,3,36,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11582.174418,11621.723611,2,102,4,4,0.44,7,7,1,3,0,1,48,1,9,1,9 +62220,7,2,2,31,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,33193.038733,33538.564898,1,96,9,9,4.92,1,1,0,0,0,2,31,1,5,5,NA +62221,7,2,2,41,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,25818.768393,25697.012112,1,100,14,14,3.6,4,4,1,1,0,1,41,1,4,1,5 +62222,7,2,1,32,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,89973.129052,97483.088567,1,93,15,15,5,2,2,0,0,0,2,30,1,5,1,5 +62223,7,2,1,54,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,10133.862484,12107.78442,3,90,77,77,NA,3,3,0,1,0,1,54,2,3,1,3 +62224,7,2,2,29,NA,2,2,2,NA,NA,2,NA,2,2,4,NA,1,1,2,2,2,2,1,2,2,2,2,2,2,43986.779369,46449.619953,1,93,9,9,2.46,4,4,0,2,0,1,35,2,1,1,1 +62225,7,2,2,13,NA,1,1,1,13,160,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,24481.187693,25761.611656,1,92,15,15,4.99,4,4,0,2,0,2,43,1,4,1,4 +62226,7,2,1,80,NA,2,2,1,NA,NA,2,NA,2,1,9,NA,4,1,NA,2,2,2,2,2,2,2,2,1,NA,13654.270555,13892.295449,2,93,9,9,3.64,2,2,0,0,2,2,79,2,2,1,4 +62227,7,2,1,19,NA,3,3,2,19,235,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,68701.580401,72973.564721,2,94,15,15,5,5,5,0,2,0,1,53,1,5,1,5 +62228,7,2,1,50,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,144353.133634,144729.952645,1,91,14,14,3.15,5,5,0,1,0,2,50,1,5,1,5 +62229,7,2,2,31,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,72426.980535,75980.145152,1,98,6,6,1.31,3,3,1,0,0,1,30,1,5,1,5 +62230,7,2,1,75,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,3,NA,1,2,2,1,2,2,1,2,2,NA,12946.818038,13703.92145,1,101,5,3,1.07,2,1,0,0,2,2,70,1,4,2,NA +62231,7,2,2,48,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,43535.993088,52686.708499,2,102,15,15,3.92,5,5,0,0,0,1,19,1,4,NA,NA +62232,7,2,2,42,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,115926.402585,118970.086068,1,101,14,14,3.3,4,4,0,2,0,2,42,1,4,1,3 +62233,7,2,2,63,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,4,NA,1,2,2,1,2,2,NA,NA,NA,NA,10999.00871,11900.968385,2,98,6,6,0.78,7,7,1,3,1,2,63,1,2,4,NA +62234,7,2,1,23,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,14860.312419,14555.816778,3,90,15,15,4.89,5,5,0,0,0,2,57,2,3,1,3 +62235,7,2,2,2,NA,3,3,2,2,33,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,49862.013993,55032.245455,2,91,15,15,5,4,4,2,0,0,1,35,1,5,1,5 +62236,7,2,1,61,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,9048.959172,9513.611982,1,93,15,15,5,5,5,1,0,1,1,61,2,4,1,4 +62237,7,2,2,58,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,140431.173819,139253.659476,1,91,7,7,2.64,2,2,0,0,1,2,58,1,5,1,4 +62238,7,2,2,0,4,3,3,1,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,20786.668002,20803.881706,1,101,8,8,1.85,5,5,3,0,0,2,31,1,2,1,2 +62239,7,2,2,22,NA,2,2,2,NA,NA,2,NA,2,2,2,NA,3,6,2,2,2,2,2,2,2,2,2,2,2,39426.061521,39254.343691,2,94,14,1,0.09,5,1,0,0,0,1,24,2,4,5,NA +62240,7,2,2,14,NA,2,2,2,15,180,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,26657.121865,28092.602686,1,97,14,14,3.25,4,4,0,2,0,1,45,1,3,6,NA +62241,7,2,1,2,NA,2,2,2,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9237.934626,9897.780242,2,90,14,14,3.45,4,4,1,1,0,2,34,2,5,6,NA +62242,7,2,1,24,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,129608.716834,132839.525748,1,100,6,6,1.98,2,2,0,0,0,1,50,1,5,4,NA +62243,7,2,2,1,16,3,3,2,NA,16,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,49862.013993,51432.868823,2,91,15,15,5,4,4,2,0,0,1,34,1,5,1,5 +62244,7,2,1,1,17,1,1,1,NA,18,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14505.670599,14525.271178,2,102,15,15,5,4,4,2,0,0,1,32,1,5,1,5 +62245,7,2,1,8,NA,5,6,2,8,97,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,10810.913614,11522.32071,1,97,15,15,5,4,4,1,1,0,1,44,2,5,1,5 +62246,7,2,2,0,1,1,1,1,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,7210.38482,7501.352858,1,100,99,99,NA,7,7,2,3,0,2,35,2,1,1,NA +62247,7,1,2,0,6,4,4,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5158.857524,0,1,97,7,7,1.74,4,4,2,0,0,1,34,1,5,1,5 +62248,7,2,1,65,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,1,1,NA,1,2,1,1,2,1,1,2,1,NA,9048.959172,9881.360452,1,93,8,8,1.2,7,7,1,1,1,1,24,2,2,5,NA +62249,7,2,2,26,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,59001.303336,59528.815212,2,101,4,4,1.38,1,1,0,0,0,2,26,1,5,5,NA +62250,7,2,1,34,NA,1,1,1,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,51543.062078,52965.08671,3,92,15,15,5,3,3,1,0,0,1,34,1,5,1,5 +62251,7,2,2,51,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,16672.82247,17074.238333,1,92,12,12,NA,4,4,0,0,0,1,59,2,3,1,4 +62252,7,2,2,11,NA,1,1,1,11,143,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17053.854294,17379.519997,3,92,15,8,2.62,4,3,1,1,0,1,30,1,2,6,NA +62253,7,2,1,18,NA,3,3,2,19,228,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,68701.580401,72973.564721,2,94,14,14,5,3,3,0,0,0,1,42,1,5,1,5 +62254,7,2,1,14,NA,4,4,2,14,179,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15381.581315,15476.088016,1,93,12,12,NA,5,4,0,2,0,1,32,1,2,5,NA +62255,7,2,1,65,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,29731.886612,29889.869541,1,95,3,3,0.87,2,2,0,0,2,2,65,1,2,1,3 +62256,7,2,1,80,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,7911.357817,9487.389486,2,94,5,5,1.63,2,2,0,0,2,2,79,1,3,1,1 +62257,7,2,2,2,NA,1,1,1,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,NA,NA,NA,NA,NA,NA,NA,9469.751474,10135.116584,1,102,NA,NA,NA,5,5,1,2,0,1,39,NA,NA,1,NA +62258,7,2,1,47,NA,2,2,1,NA,NA,2,NA,2,2,6,NA,1,1,NA,2,2,2,2,2,2,NA,NA,NA,NA,43470.92932,42833.060444,1,92,6,6,0.93,5,5,0,2,0,1,47,2,1,1,1 +62259,7,2,1,61,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,7736.56115,7645.782314,1,99,4,2,0.87,2,1,0,0,1,2,59,1,3,3,NA +62260,7,2,1,10,NA,3,3,2,10,125,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,57305.501166,60591.443404,1,94,15,15,5,5,5,0,3,0,1,46,1,3,1,5 +62261,7,2,1,47,NA,2,2,1,NA,NA,2,NA,2,1,6,NA,4,1,NA,1,2,2,1,2,2,2,2,2,2,33029.272844,33366.323953,2,93,14,14,3.25,4,4,0,2,0,2,46,2,5,1,4 +62262,7,2,2,0,10,2,2,1,NA,10,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,7367.430495,7616.752822,2,91,5,5,0.74,5,5,1,1,0,1,35,2,1,1,2 +62263,7,2,1,2,NA,3,3,2,2,32,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,28617.223132,33531.791823,1,101,3,3,0.61,4,4,1,2,0,1,38,1,2,4,NA +62264,7,2,1,77,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,52448.388619,55291.886181,1,99,7,7,2.72,2,2,0,0,2,1,77,1,2,1,3 +62265,7,2,1,52,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,19478.845078,19591.5023,2,95,7,7,1.13,6,6,0,3,1,1,52,1,4,1,4 +62266,7,2,1,64,NA,3,3,2,NA,NA,2,NA,2,1,6,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,29999.543427,30837.648113,2,91,12,5,1.79,3,1,0,0,1,1,52,1,4,3,NA +62267,7,2,2,27,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,34430.806911,35615.742482,2,95,6,6,1.08,4,4,1,1,0,1,39,1,4,1,4 +62268,7,2,2,15,NA,1,1,1,16,192,NA,NA,1,1,NA,9,NA,NA,NA,2,2,2,1,2,2,1,2,2,1,16734.618372,17498.916137,2,96,5,5,0.78,5,5,0,2,0,1,37,2,1,5,NA +62269,7,2,1,29,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,14718.123234,15404.517346,2,101,1,1,0.1,6,6,1,2,1,2,27,1,2,1,2 +62270,7,2,2,33,NA,2,2,1,NA,NA,2,NA,2,2,2,NA,5,5,2,2,2,2,1,2,2,2,2,2,2,31765.061314,30907.973228,2,93,4,4,0.56,5,5,0,0,0,2,49,2,2,5,NA +62271,7,2,1,7,NA,4,4,2,7,87,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6971.452972,8307.996458,2,99,7,7,1.63,4,4,0,2,0,1,53,1,3,3,NA +62272,7,2,1,9,NA,2,2,1,9,111,NA,NA,1,1,NA,3,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,11102.340512,11169.626274,2,93,6,6,0.64,7,7,2,1,3,2,60,2,3,2,NA +62273,7,2,2,15,NA,5,6,1,15,184,NA,NA,1,1,NA,10,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7588.544207,7881.983727,3,91,14,14,4.03,4,4,0,2,0,1,51,2,4,1,5 +62274,7,2,1,2,NA,4,4,1,2,28,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5103.735747,5455.59,2,95,3,3,0.38,5,5,2,2,0,2,37,1,4,3,NA +62275,7,2,2,41,NA,5,6,2,NA,NA,2,NA,2,1,8,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,14442.406316,14518.77693,2,99,15,15,5,1,1,0,0,0,2,41,2,5,5,NA +62276,7,2,1,9,NA,3,3,2,9,114,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,63059.776443,67841.511058,1,99,15,15,5,4,4,1,1,0,2,42,1,5,1,5 +62277,7,2,2,55,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,139343.551779,140618.30879,2,98,9,9,5,1,1,0,0,0,2,55,1,4,3,NA +62278,7,2,2,72,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,62212.598767,64340.261278,1,94,7,7,2.51,2,2,0,0,2,2,72,1,4,1,1 +62279,7,2,1,80,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,9456.784526,9941.375417,2,99,13,13,NA,3,3,0,0,1,1,80,1,2,2,NA +62280,7,2,2,54,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,16966.723528,16502.38463,2,95,6,6,1.7,2,2,0,0,0,2,54,1,4,2,NA +62281,7,2,2,13,NA,4,4,2,13,162,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11372.489138,11738.962427,1,99,6,6,0.96,5,5,1,2,0,2,35,1,4,1,2 +62282,7,2,2,57,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,21219.116826,20638.40003,1,102,6,6,1.7,2,2,0,0,1,2,80,NA,NA,2,NA +62283,7,2,1,2,NA,1,1,1,2,29,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14457.854197,15490.547336,1,92,10,10,2.93,4,4,1,0,0,2,55,1,4,1,4 +62284,7,2,2,64,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,117778.281347,120111.495123,1,94,8,8,2.41,3,3,0,0,3,1,63,1,4,1,5 +62285,7,2,2,17,NA,3,3,2,17,206,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,103007.696238,104941.393061,1,101,6,6,1.31,3,3,0,1,0,1,51,1,4,1,4 +62286,7,2,1,30,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,12556.207754,12615.022145,2,99,NA,77,NA,7,7,1,0,1,2,51,1,2,1,3 +62287,7,2,2,73,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,12183.823561,12607.778632,2,100,6,6,2.11,2,2,0,0,2,1,79,1,3,1,4 +62288,7,2,1,29,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,22634.531479,23281.741513,1,103,9,6,2.24,3,1,0,0,0,1,27,1,5,5,NA +62289,7,2,1,71,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,NA,13555.672819,15969.746949,1,94,3,3,1.07,1,1,0,0,1,1,71,1,2,3,NA +62290,7,2,2,2,NA,4,4,2,2,29,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7618.827213,7957.141798,2,101,1,1,0,3,3,2,0,0,1,22,1,3,5,NA +62291,7,2,1,56,NA,5,7,1,NA,NA,1,1,2,1,8,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,20111.196953,20038.543847,1,92,14,14,5,2,2,0,0,0,1,56,2,4,1,4 +62292,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,36829.543424,39682.305625,1,93,15,15,5,4,3,0,0,3,1,80,1,5,2,NA +62293,7,2,1,67,NA,3,3,2,NA,NA,1,1,2,1,9,NA,4,3,NA,1,2,2,1,2,2,1,2,2,NA,28478.57859,28745.66908,1,101,3,3,1.16,1,1,0,0,1,1,67,2,4,3,NA +62294,7,2,1,9,NA,2,2,2,9,117,NA,NA,1,1,NA,4,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,9390.522479,10327.334743,2,90,3,3,0.54,4,4,1,2,0,2,33,2,1,4,NA +62295,7,2,2,69,NA,2,2,2,NA,NA,2,NA,2,1,9,NA,2,2,NA,1,2,2,1,2,2,1,2,2,1,9716.805546,12994.252166,2,90,2,2,0.79,1,1,0,0,1,2,69,2,2,2,NA +62296,7,2,1,19,NA,4,4,2,19,232,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13251.602554,13277.802057,1,96,15,15,5,2,2,0,0,0,2,51,1,5,5,NA +62297,7,2,1,43,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,18402.969014,18977.095614,2,95,10,10,3.67,3,3,0,1,0,1,43,1,4,1,4 +62298,7,2,1,15,NA,3,3,2,16,192,NA,NA,1,1,NA,10,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,93665.036597,95017.313859,1,91,14,14,3.8,4,4,0,2,0,1,50,NA,NA,1,5 +62299,7,2,1,8,NA,5,6,2,9,108,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6631.058951,7488.793181,2,92,12,12,NA,7,7,2,4,0,1,54,2,2,1,5 +62300,7,2,2,6,NA,4,4,2,6,83,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6929.51414,7399.559927,2,99,14,14,4.09,3,3,0,2,0,2,37,1,5,5,NA +62301,7,2,1,23,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,16995.648055,16907.09145,1,96,12,12,NA,7,7,1,0,1,2,59,1,3,1,1 +62302,7,2,2,51,NA,2,2,1,NA,NA,2,NA,2,2,6,NA,1,5,NA,2,2,2,1,2,2,2,2,2,2,19676.781212,20033.616894,2,103,77,77,NA,4,4,0,0,0,2,46,2,1,4,NA +62303,7,2,2,76,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,61501.13451,65355.920739,2,101,6,6,1.62,3,3,0,0,2,1,80,1,3,1,3 +62304,7,2,2,6,NA,1,1,2,6,77,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,9872.244853,10573.701398,2,90,6,6,0.96,5,5,1,1,0,1,39,2,2,1,NA +62305,7,2,1,10,NA,1,1,2,10,131,NA,NA,1,1,NA,5,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,13285.093011,14158.005149,2,94,9,9,2.37,5,5,0,1,0,1,48,2,4,1,2 +62306,7,2,1,0,9,2,2,2,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4884.343512,4884.433539,3,90,12,12,NA,3,3,1,0,0,1,40,2,5,1,4 +62307,7,2,1,61,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,7828.117773,8460.915547,2,90,4,4,1.2,2,2,0,0,2,2,80,1,3,2,NA +62308,7,2,2,78,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,83112.549416,87237.362828,1,97,7,7,2.64,2,2,0,0,2,1,79,1,4,1,3 +62309,7,2,2,47,NA,1,1,1,NA,NA,2,NA,2,2,3,NA,2,2,NA,2,2,2,2,2,2,2,2,2,2,40337.933888,40548.292782,3,92,4,4,0.46,7,7,1,2,0,2,31,2,2,1,1 +62310,7,2,2,8,NA,4,4,2,8,97,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7632.404654,7765.546414,2,101,1,1,0.1,6,6,1,2,1,2,27,1,2,1,2 +62311,7,2,1,18,NA,3,3,2,19,228,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,68148.957861,67253.324127,1,93,15,15,3.92,5,5,0,1,0,2,54,1,5,1,5 +62312,7,2,2,63,NA,1,1,1,NA,NA,2,NA,2,2,7,NA,1,1,NA,2,2,1,1,2,2,1,2,2,2,16352.915834,17178.789759,3,92,8,8,1.85,5,5,1,0,2,1,66,2,1,1,1 +62313,7,2,1,7,NA,1,1,1,7,93,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12577.115885,12876.06354,2,96,5,5,0.76,5,5,1,2,0,1,44,2,1,1,3 +62314,7,2,1,61,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,7611.107768,7639.752345,2,97,3,3,1.33,1,1,0,0,1,1,61,1,3,5,NA +62315,7,2,2,80,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,12842.559946,13803.13967,2,95,99,99,NA,2,2,0,1,1,2,80,1,2,2,NA +62316,7,2,1,39,NA,2,2,1,NA,NA,2,NA,2,1,7,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,31674.692905,34832.561132,2,100,4,4,0.81,4,4,0,2,0,2,37,1,2,1,2 +62317,7,2,1,46,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,18872.772727,18824.29246,1,94,7,7,0.94,7,7,1,4,0,2,46,2,5,1,5 +62318,7,2,2,0,10,3,3,1,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8114.787453,8336.925581,1,91,2,2,0.27,5,5,2,2,0,2,42,1,4,3,NA +62319,7,2,2,4,NA,4,4,1,4,58,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10437.988787,11231.392369,2,100,1,1,0.08,5,5,1,2,0,2,19,1,3,NA,NA +62320,7,2,2,64,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,122483.259869,124909.680309,3,91,7,7,2.89,2,2,0,0,2,2,64,1,4,1,4 +62321,7,2,2,8,NA,5,6,1,8,100,NA,NA,2,1,3,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6412.057856,6847.117735,3,91,14,14,4.03,4,4,0,2,0,1,50,1,5,1,5 +62322,7,2,2,4,NA,4,4,1,4,59,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10295.166918,11223.20055,2,96,4,4,0.4,7,7,3,2,0,2,25,1,2,5,NA +62323,7,2,2,2,NA,4,4,2,2,29,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7618.827213,7957.141798,2,101,1,1,0,3,3,2,0,0,1,22,1,3,5,NA +62324,7,2,2,60,NA,1,1,2,NA,NA,2,NA,2,2,77,NA,4,4,NA,2,2,2,1,2,2,1,2,2,2,11469.456138,12167.81965,1,90,3,3,0.23,7,7,3,1,1,2,35,2,2,5,NA +62325,7,2,2,43,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,6,2,1,2,2,1,2,2,1,2,2,1,30932.175051,32888.281888,2,101,1,1,0.1,2,2,0,0,0,1,56,1,3,6,NA +62326,7,2,1,69,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,153565.050575,157855.235487,1,97,10,10,4.3,2,2,0,0,1,2,56,1,5,1,5 +62327,7,2,2,19,NA,4,4,2,19,238,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12209.74498,12386.615954,2,90,6,6,1.12,4,4,0,1,1,1,63,2,1,1,1 +62328,7,2,2,9,NA,4,4,1,9,119,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7899.813226,8111.155436,2,97,15,15,5,4,4,0,2,0,1,47,NA,NA,6,NA +62329,7,2,1,2,NA,2,2,1,2,26,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,11793.948458,12167.27893,1,100,3,3,0.39,5,5,1,2,0,1,32,2,1,6,NA +62330,7,2,2,33,NA,5,6,1,NA,NA,2,NA,2,2,3,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,21097.664283,22267.583876,2,96,14,14,5,2,2,0,0,0,2,33,2,5,1,5 +62331,7,2,1,9,NA,5,7,2,9,111,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8246.426933,8701.859504,1,99,14,14,3.94,4,4,1,1,0,1,43,1,4,1,5 +62332,7,2,1,22,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,31962.323978,33458.586112,1,100,4,4,1.06,3,2,0,0,0,1,22,1,4,6,NA +62333,7,2,2,45,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,3,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,13046.228603,13115.21631,2,92,12,77,NA,7,2,0,0,2,1,53,2,3,1,3 +62334,7,2,1,9,NA,3,3,1,9,108,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,19590.665143,20475.022602,3,91,5,5,0.87,4,4,0,2,0,2,38,1,2,3,NA +62335,7,2,1,14,NA,2,2,2,14,171,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13921.972975,14228.387356,3,90,14,14,3.69,4,4,0,2,0,2,49,1,4,1,4 +62336,7,2,1,55,NA,2,2,1,NA,NA,2,NA,2,1,7,NA,4,6,NA,2,2,2,2,2,2,2,2,2,2,24211.824535,24947.165851,2,93,10,10,3.67,3,3,0,0,0,2,56,2,4,6,NA +62337,7,2,2,10,NA,1,1,2,10,123,NA,NA,2,2,3,5,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,15166.167659,15537.272247,2,94,7,7,1.04,7,7,0,3,0,1,37,2,1,1,3 +62338,7,1,2,2,NA,1,1,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12260.86913,0,3,92,5,5,0.68,6,6,3,0,0,2,19,1,4,NA,NA +62339,7,2,1,29,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,71402.235366,74200.659205,2,100,15,15,5,4,4,1,1,0,1,29,1,4,1,4 +62340,7,2,1,44,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,126789.52929,130826.463813,1,101,6,6,1.28,4,4,2,0,0,1,44,1,4,1,4 +62341,7,2,1,8,NA,1,1,2,8,104,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13285.093011,13365.60735,2,94,7,7,2.16,3,3,0,1,0,2,28,1,2,1,1 +62342,7,2,2,38,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,77778.949308,78565.115731,1,101,8,8,1.85,5,5,0,3,0,1,41,1,3,1,4 +62343,7,2,1,28,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,17420.978407,17615.311737,2,97,5,5,0.76,5,5,0,0,0,2,50,1,4,5,NA +62344,7,1,2,32,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,5,5,3,1,2,2,NA,NA,NA,NA,NA,NA,NA,26426.249254,0,1,99,NA,NA,NA,1,1,0,0,0,2,32,1,5,5,NA +62345,7,2,2,38,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,64324.554311,66806.652381,2,103,15,15,5,4,4,2,0,0,1,36,2,4,1,5 +62346,7,2,1,19,NA,5,7,1,19,239,2,NA,2,2,4,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,6558.308393,6849.983523,2,92,99,1,0.22,4,1,0,0,0,1,19,1,4,NA,NA +62347,7,2,2,71,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,25812.913537,27430.822937,2,95,3,3,1.21,1,1,0,0,1,2,71,1,3,2,NA +62348,7,2,2,19,NA,4,4,2,19,236,2,NA,1,1,NA,12,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11419.859653,11886.179371,2,99,7,7,1.19,6,6,1,3,0,2,38,1,3,5,NA +62349,7,2,2,23,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,122473.120523,125156.324631,3,91,8,5,1.5,3,2,0,0,0,1,23,1,4,1,4 +62350,7,2,2,43,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,2,1,2,2,1,2,2,1,2,2,1,96255.674553,99423.043377,2,94,7,7,2.72,2,2,0,1,0,2,43,1,3,3,NA +62351,7,2,1,7,NA,3,3,2,7,89,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,25604.034863,26336.174292,1,95,5,5,0.92,5,5,1,2,0,2,30,1,4,1,4 +62352,7,2,2,3,NA,4,4,1,3,46,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10437.988787,10601.396934,2,100,8,8,1.1,7,7,3,3,0,2,58,1,3,5,NA +62353,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,39587.338944,43437.954199,2,91,15,15,5,2,2,0,0,2,2,79,1,5,1,5 +62354,7,2,2,11,NA,3,3,2,11,140,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,80369.555824,79030.006233,1,97,8,8,2.72,3,3,0,2,0,2,43,1,1,3,NA +62355,7,2,2,16,NA,5,6,1,16,197,NA,NA,2,1,3,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,7176.749123,7692.153155,3,91,7,7,1.79,4,4,0,1,0,2,45,2,2,1,3 +62356,7,2,2,14,NA,1,1,1,14,179,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,26325.414456,27702.295836,3,92,12,12,NA,6,6,1,3,0,2,33,1,5,1,4 +62357,7,2,1,36,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,94433.586146,101591.315487,1,91,15,15,5,3,3,1,0,0,1,36,1,4,1,5 +62358,7,2,2,0,3,1,1,1,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9767.083234,9561.595244,3,92,7,7,1.99,3,3,1,0,0,1,40,1,4,1,4 +62359,7,2,2,54,NA,1,1,2,NA,NA,2,NA,2,2,3,NA,1,1,NA,2,2,2,2,2,2,2,2,2,2,22224.73066,23825.197607,2,94,7,7,1.04,7,7,0,3,0,1,37,2,1,1,3 +62360,7,2,1,17,NA,4,4,1,17,210,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11429.628358,11541.555232,2,96,7,7,1.04,7,7,0,4,0,2,37,1,3,3,NA +62361,7,2,1,7,NA,4,4,1,7,94,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13423.881856,14179.490667,2,101,1,1,0.21,4,4,1,2,0,2,26,1,3,5,NA +62362,7,2,2,11,NA,4,4,2,11,137,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8579.490652,8919.477637,2,97,6,6,1,6,6,1,2,2,2,60,1,2,2,NA +62363,7,2,2,44,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,3,2,1,2,2,1,2,2,1,2,2,1,134897.594057,143557.343892,2,102,6,6,1.43,4,4,0,1,1,1,67,NA,NA,1,NA +62364,7,2,2,4,NA,1,1,1,5,60,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14899.363418,16449.297045,1,100,8,8,2.17,4,4,1,1,0,2,40,2,2,1,2 +62365,7,2,2,37,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,4,1,2,1,2,2,1,2,2,NA,NA,NA,NA,21097.664283,21336.137518,2,96,8,8,3.4,2,2,0,0,0,1,46,2,4,1,4 +62366,7,2,1,80,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,37318.801462,40047.525745,1,98,6,6,1.65,2,2,0,0,2,1,80,1,3,1,3 +62367,7,2,1,50,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,2,1,NA,1,2,1,1,2,1,1,2,1,3,10133.862484,10097.253197,3,90,15,15,3.23,6,6,0,2,0,1,50,2,2,1,2 +62368,7,2,2,80,NA,2,2,1,NA,NA,2,NA,2,1,9,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,23176.790531,24820.797478,1,98,3,3,0.81,2,2,0,0,1,2,80,2,1,2,NA +62369,7,2,2,8,NA,2,2,1,8,100,NA,NA,2,2,3,2,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,15352.601806,15663.127806,2,102,7,7,1.53,5,5,1,2,0,2,37,2,4,1,4 +62370,7,2,1,21,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,13843.66558,14262.333267,1,90,15,15,3.7,5,5,0,0,0,1,54,NA,NA,1,NA +62371,7,2,1,32,NA,5,6,1,NA,NA,2,NA,2,2,3,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,22403.911395,23863.238542,2,96,14,14,5,2,2,0,0,0,2,33,2,5,1,5 +62372,7,2,2,55,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,4,1,NA,1,2,1,1,2,2,1,2,2,NA,17991.883465,18643.986017,2,102,8,8,2.01,4,4,0,0,0,1,59,2,4,1,4 +62373,7,2,1,46,NA,1,1,1,NA,NA,2,NA,2,2,7,NA,1,1,NA,2,2,2,1,2,2,1,2,2,NA,37324.655911,36776.974122,1,102,6,6,1.34,4,4,0,1,0,2,48,2,3,1,1 +62374,7,2,2,31,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,2,1,2,2,1,2,2,NA,NA,NA,NA,31335.13799,33530.36206,1,101,4,4,0.78,4,4,1,2,0,2,31,1,4,3,NA +62375,7,2,1,24,NA,1,1,1,NA,NA,2,NA,2,2,99,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,52698.05363,59566.360508,3,92,4,4,0.65,4,4,2,0,0,2,20,1,3,5,NA +62376,7,2,1,6,NA,4,4,2,6,73,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7730.47951,9212.541007,1,99,5,5,0.84,5,5,2,1,0,1,35,1,3,1,2 +62377,7,2,2,78,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,35965.834545,38220.111719,1,95,3,3,1.24,1,1,0,0,1,2,78,1,2,2,NA +62378,7,2,2,68,NA,2,2,2,NA,NA,2,NA,2,1,8,NA,1,3,NA,2,2,2,1,2,2,2,2,2,2,10979.149658,11879.480817,1,96,15,8,4.66,2,1,0,0,2,2,68,2,1,3,NA +62379,7,2,1,40,NA,5,7,1,NA,NA,2,NA,2,1,5,NA,5,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,24837.95225,25237.159887,1,102,10,10,3.22,4,4,0,0,2,2,29,2,5,5,NA +62380,7,2,1,16,NA,1,1,1,17,204,NA,NA,1,1,NA,10,NA,NA,NA,2,2,2,1,2,2,1,2,2,1,15506.325263,15592.022118,1,103,8,8,2,5,5,0,1,0,2,45,2,3,1,2 +62381,7,2,1,21,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,1,2,1,2,2,1,2,2,NA,15408.94893,15514.368855,1,99,7,2,0.74,3,1,0,0,2,1,70,1,2,1,4 +62382,7,2,2,1,21,4,4,2,NA,22,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5743.559235,6261.298887,2,99,2,2,0.2,7,7,1,2,1,1,63,1,1,2,NA +62383,7,2,1,23,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,91704.59836,93129.802737,1,93,15,4,1.38,6,1,0,0,0,1,23,1,5,5,NA +62384,7,2,1,40,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,4,NA,1,2,2,1,2,2,1,2,2,1,27444.308565,27682.940425,1,101,7,7,2.31,2,2,0,0,1,2,69,1,4,2,NA +62385,7,2,1,0,10,4,4,1,NA,10,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6699.703488,6998.255943,2,96,6,6,1.32,5,5,1,3,0,2,30,1,4,3,NA +62386,7,2,1,35,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,21163.049914,22845.160537,1,97,8,8,2.51,3,3,0,1,0,1,35,1,3,1,4 +62387,7,2,1,23,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,17420.978407,17597.975048,2,97,3,3,1.29,1,1,0,0,0,1,23,1,3,5,NA +62388,7,2,2,69,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,49644.076348,54110.530387,1,97,3,3,1.12,1,1,0,0,1,2,69,1,3,2,NA +62389,7,2,2,16,NA,5,7,2,16,194,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11975.458482,12291.118947,1,97,15,15,5,6,6,0,3,0,1,47,1,5,1,5 +62390,7,2,2,25,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,14095.963218,14697.88566,2,92,15,8,4.59,2,1,0,0,0,2,25,2,5,5,NA +62391,7,2,2,40,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,34954.173075,36222.975959,2,98,15,15,5,3,3,0,1,0,1,38,1,4,1,3 +62392,7,2,2,1,12,1,1,1,NA,13,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,1,1,2,1,NA,NA,NA,NA,12260.86913,12783.275371,3,92,6,6,0.96,5,5,2,1,0,2,26,2,1,1,1 +62393,7,2,1,20,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,39915.513053,48709.670361,2,98,7,7,1.53,5,5,0,0,0,2,48,1,3,5,NA +62394,7,2,1,1,14,1,1,1,NA,14,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12493.910388,13386.323284,2,98,1,1,0.13,4,4,2,0,0,2,52,1,2,4,NA +62395,7,2,2,1,16,1,1,1,NA,18,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,12871.484115,13281.030392,2,102,8,8,2.24,4,4,1,1,0,1,35,2,3,1,1 +62396,7,2,1,10,NA,1,1,1,10,123,NA,NA,1,1,NA,4,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,10658.399025,10827.062436,1,102,5,5,0.62,7,7,1,3,0,1,49,2,2,1,1 +62397,7,2,2,70,NA,1,1,1,NA,NA,2,NA,2,1,7,NA,1,2,NA,2,2,2,1,2,2,2,2,2,NA,17077.396628,18362.705174,2,96,13,13,NA,6,6,0,2,1,1,43,2,4,1,3 +62398,7,2,1,9,NA,3,3,2,9,117,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,19926.440922,21167.339982,1,94,7,7,0.94,7,7,1,4,0,2,46,2,5,1,5 +62399,7,2,2,53,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,1,1,NA,2,2,2,2,2,2,2,2,2,2,24870.513993,25871.320138,2,98,5,5,1.63,2,2,0,0,0,2,53,2,1,1,1 +62400,7,2,2,31,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,27463.558155,27680.636989,2,100,4,4,1.22,2,2,0,1,0,2,31,1,4,5,NA +62401,7,2,2,15,NA,3,3,1,15,187,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,93740.540203,99321.165816,1,100,8,8,1.95,4,4,0,2,1,2,49,1,5,6,NA +62402,7,2,1,48,NA,5,6,2,NA,NA,2,NA,2,2,4,NA,1,4,NA,1,2,2,1,2,2,1,2,2,NA,14259.601244,14208.087437,1,93,6,6,1.15,5,5,1,0,2,2,70,NA,NA,1,NA +62403,7,2,2,3,NA,4,4,2,3,46,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8192.75936,8404.22838,2,99,77,77,NA,3,3,1,0,0,1,38,2,5,1,5 +62404,7,2,1,44,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,22009.438408,22692.209281,2,99,6,6,2.95,1,1,0,0,0,1,44,1,3,5,NA +62405,7,2,1,5,NA,2,2,1,5,63,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,14716.463544,14890.443704,2,96,2,2,0.27,6,6,1,3,0,1,34,NA,NA,1,NA +62406,7,2,2,10,NA,2,2,2,10,129,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,19936.606751,20692.800636,1,94,7,7,1.74,4,4,0,2,0,1,44,1,5,1,5 +62407,7,2,1,49,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,28680.660607,29290.218786,1,94,3,3,1.1,1,1,0,0,0,1,49,1,4,3,NA +62408,7,1,1,58,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,174520.785302,0,1,95,7,7,2.86,2,2,0,0,1,1,58,1,4,1,3 +62409,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,22419.63376,27869.657009,1,94,3,3,1.16,1,1,0,0,1,2,80,1,3,2,NA +62410,7,2,1,5,NA,4,4,2,5,63,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8158.702829,8662.344233,2,99,5,5,0.65,6,6,2,1,0,2,53,1,4,3,NA +62411,7,2,2,51,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,15790.702799,17527.166432,2,90,7,7,3.21,1,1,0,0,0,2,51,1,4,5,NA +62412,7,2,1,16,NA,1,1,2,16,199,NA,NA,2,2,4,10,NA,NA,NA,2,2,2,2,2,2,1,2,2,1,21718.29328,22050.264992,2,94,6,6,1.5,4,4,0,2,0,1,44,2,2,1,2 +62413,7,2,1,65,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,131445.986898,130104.237054,1,101,5,5,1.6,2,2,0,0,1,1,65,1,4,6,NA +62414,7,2,1,58,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,1,2,1,2,2,1,1,2,NA,17206.320427,17681.811932,1,96,2,2,0.4,3,3,0,0,0,2,56,1,3,3,NA +62415,7,2,2,27,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,1,1,2,2,1,2,2,1,2,2,1,129336.409693,136474.939567,1,95,15,15,5,3,3,1,0,0,1,26,1,3,1,4 +62416,7,2,2,19,NA,2,2,2,19,235,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13824.001771,14551.102227,2,90,10,10,2.91,4,4,0,1,0,2,51,2,4,1,1 +62417,7,2,2,26,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,45207.136555,46085.238422,1,94,14,8,4.66,2,1,0,0,0,2,26,1,4,5,NA +62418,7,2,1,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,46965.818538,52174.805072,1,101,6,6,1.98,2,2,0,0,1,1,80,1,1,2,NA +62419,7,2,1,80,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,42993.150248,46481.579201,1,95,5,5,0.65,6,6,1,0,2,1,80,1,3,1,4 +62420,7,1,1,24,NA,1,1,NA,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,59682.963348,0,2,102,77,77,NA,4,4,0,1,0,1,47,1,2,1,3 +62421,7,2,1,23,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,14313.345971,15171.949804,3,91,6,1,0,2,1,0,0,0,1,24,1,5,5,NA +62422,7,2,2,72,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,63504.762752,64182.95787,1,91,15,15,5,1,1,0,0,1,2,72,1,4,2,NA +62423,7,1,2,8,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13192.206605,0,2,102,14,14,3.8,4,4,0,2,0,1,47,1,4,1,4 +62424,7,2,1,20,NA,2,2,2,NA,NA,2,NA,2,2,3,NA,2,5,NA,2,2,2,2,2,2,2,2,2,2,41713.173502,43905.698512,1,90,99,3,0.9,3,1,0,0,0,1,41,NA,NA,99,NA +62425,7,2,2,30,NA,3,3,2,NA,NA,2,NA,2,2,1,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,81658.419251,86275.41601,2,99,15,15,5,2,2,0,0,0,1,30,NA,NA,1,5 +62426,7,2,1,9,NA,1,1,1,10,120,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8828.580268,8822.70874,2,103,10,10,1.63,7,7,1,4,0,1,31,NA,NA,1,4 +62427,7,2,1,15,NA,4,4,2,15,185,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11462.850569,11753.30805,2,100,4,4,0.69,5,5,0,3,0,1,38,1,3,6,NA +62428,7,2,2,12,NA,4,4,1,12,145,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,16598.888685,16325.283055,2,102,15,15,4.2,5,5,1,2,0,2,29,NA,NA,1,NA +62429,7,2,1,47,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,25964.952645,26121.35248,2,96,14,14,5,2,2,0,1,0,1,47,1,5,5,NA +62430,7,2,1,27,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,49006.291777,50482.76018,1,92,9,9,2.93,3,3,0,1,0,2,30,1,5,1,5 +62431,7,2,1,54,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,25969.864445,29542.265764,1,97,2,2,0.81,1,1,0,0,0,1,54,1,2,5,NA +62432,7,2,2,38,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,75294.690128,81171.633513,1,90,15,15,5,4,4,0,2,0,1,37,1,5,1,5 +62433,7,2,1,10,NA,4,4,2,10,131,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,NA,NA,NA,NA,NA,NA,NA,8579.422451,10224.240431,1,99,NA,NA,NA,4,4,1,1,0,1,42,NA,NA,1,NA +62434,7,2,2,61,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,9113.905743,10210.592308,3,90,14,14,5,2,2,0,0,2,1,60,NA,NA,1,3 +62435,7,2,2,0,7,3,3,2,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16547.193167,16560.896108,1,97,12,12,NA,5,5,3,0,0,2,33,1,5,1,5 +62436,7,2,1,4,NA,1,1,2,4,52,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,11776.305841,11467.607256,1,90,4,4,0.47,7,7,1,1,0,2,50,2,1,1,1 +62437,7,2,1,39,NA,1,1,2,NA,NA,2,NA,2,2,4,NA,2,6,NA,2,2,2,1,2,2,1,2,2,2,33948.23667,35734.088319,2,97,4,4,0.67,4,4,0,2,0,1,39,2,2,6,NA +62438,7,2,1,0,0,4,4,2,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6339.587912,6622.092882,1,91,7,7,1.49,5,5,3,0,0,2,38,2,4,1,4 +62439,7,2,1,75,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,60942.568495,64726.722108,1,94,15,15,5,2,2,0,0,2,1,75,1,4,1,3 +62440,7,2,1,22,NA,1,1,2,NA,NA,2,NA,2,1,4,NA,4,1,NA,1,2,2,2,2,2,1,2,2,2,35669.2076,36294.041819,2,94,7,7,1.33,6,6,0,1,0,1,55,2,2,1,1 +62441,7,2,1,68,NA,2,2,2,NA,NA,2,NA,2,2,5,NA,1,1,NA,2,2,2,1,2,2,1,2,2,2,8609.250304,11228.904188,2,90,2,2,0.31,4,4,0,0,2,1,68,2,1,1,NA +62442,7,2,1,0,8,4,4,2,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6981.458608,7088.61417,2,92,9,9,2.71,4,4,1,0,0,1,43,1,2,1,4 +62443,7,2,2,4,NA,4,4,1,4,52,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8464.796876,9108.215863,2,93,8,8,1.67,5,5,1,1,0,2,31,1,4,5,NA +62444,7,2,2,23,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,21503.272394,20634.528185,2,100,1,1,0,2,2,0,0,0,2,55,1,5,3,NA +62445,7,2,2,42,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,4,2,1,2,2,1,2,2,1,2,2,1,19866.025076,19772.340772,2,95,6,6,1.08,4,4,1,0,0,2,42,1,4,4,NA +62446,7,2,2,4,NA,2,2,1,4,56,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15457.736897,17065.756351,2,98,1,1,0,3,1,2,0,0,2,27,1,3,6,NA +62447,7,2,2,19,NA,1,1,1,19,237,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,17490.464019,17826.708822,1,102,6,6,1.43,3,3,0,1,0,2,39,1,4,3,NA +62448,7,2,1,13,NA,1,1,1,13,162,NA,NA,2,2,4,7,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,18583.729819,18727.0393,2,96,6,6,1.11,5,5,0,3,0,2,32,2,3,1,2 +62449,7,2,2,38,NA,2,2,1,NA,NA,2,NA,2,1,6,NA,2,1,2,1,2,2,1,2,2,1,2,2,1,32097.38481,34606.180038,2,100,14,14,3.36,4,4,1,1,0,1,45,2,5,1,2 +62450,7,2,1,57,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,19282.792088,20545.343351,2,97,7,7,1.92,3,3,0,1,0,1,57,1,4,1,4 +62451,7,2,2,0,4,3,3,1,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,NA,2,1,2,2,NA,NA,NA,NA,9142.358181,9688.944551,2,98,1,1,0.23,2,2,1,0,0,2,20,1,3,6,NA +62452,7,2,1,39,NA,2,2,2,NA,NA,2,NA,2,2,4,NA,3,5,NA,2,2,2,2,2,2,2,2,2,2,34564.442715,35621.093093,2,90,4,4,0.81,3,3,0,0,0,1,39,2,3,5,NA +62453,7,2,2,2,NA,4,4,1,2,35,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7329.363701,7518.547014,1,103,6,6,1.57,3,3,1,0,0,2,25,1,4,5,NA +62454,7,2,2,64,NA,2,2,1,NA,NA,2,NA,2,1,8,NA,4,1,NA,2,2,2,1,2,2,2,2,2,2,7278.790659,7582.574348,2,93,5,5,1.32,2,2,0,0,1,1,49,2,2,1,4 +62455,7,2,1,18,NA,4,4,2,19,228,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,7946.436474,8100.311671,3,90,15,15,5,5,5,1,0,1,1,38,2,3,1,4 +62456,7,2,1,17,NA,4,4,1,17,214,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13731.625553,14242.275028,1,100,14,14,3.93,3,3,0,1,0,2,47,1,5,4,NA +62457,7,2,1,69,NA,4,4,2,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,7736.56115,7645.782314,1,99,15,15,5,2,2,0,0,2,2,63,2,5,1,5 +62458,7,2,1,13,NA,5,6,2,13,162,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6666.045669,7317.485505,3,90,77,77,NA,3,3,0,1,0,1,54,2,3,1,3 +62459,7,2,1,4,NA,3,3,2,4,51,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,76935.850725,86801.923297,1,95,12,12,NA,6,6,2,0,0,2,42,1,2,1,5 +62460,7,2,1,41,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,105141.812429,109679.354704,1,98,15,15,4.34,4,4,1,1,0,1,41,1,5,1,5 +62461,7,2,2,29,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,19362.260448,24981.28051,1,96,6,6,1.98,2,2,0,1,0,2,29,1,3,5,NA +62462,7,2,2,11,NA,3,3,1,11,137,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,79732.314338,79120.693768,1,100,15,15,5,4,4,0,2,0,1,46,1,5,1,5 +62463,7,2,1,7,NA,1,1,1,7,92,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,19774.151841,21259.203461,2,94,5,5,0.65,6,6,0,3,0,1,44,2,1,1,1 +62464,7,2,1,32,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,22188.836739,22824.336433,1,95,10,7,3.21,5,1,1,2,0,1,32,1,3,6,NA +62465,7,2,2,44,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,20084.755052,20430.629009,1,99,14,14,4.21,4,4,0,2,0,2,44,1,5,1,5 +62466,7,2,1,4,NA,4,4,2,4,49,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7629.74403,8207.121237,1,99,7,7,1.06,7,7,3,1,0,1,38,1,4,6,NA +62467,7,2,1,65,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,117075.881463,118577.582598,1,94,5,5,2.15,1,1,0,0,1,1,65,1,5,1,NA +62468,7,2,2,0,8,2,2,2,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,6787.112205,6644.319314,2,94,5,5,0.89,4,4,2,0,0,2,35,2,4,1,2 +62469,7,2,1,9,NA,4,4,1,9,110,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13423.881856,13521.226684,2,101,4,4,0.76,4,4,1,1,0,1,28,1,2,1,4 +62470,7,2,1,4,NA,1,1,1,4,48,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,12870.245769,12532.871153,1,102,6,6,0.8,7,7,3,3,0,2,34,2,3,1,1 +62471,7,2,2,76,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,45482.078305,46877.423634,2,96,99,99,NA,4,4,0,1,1,2,51,1,2,1,4 +62472,7,2,1,31,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,27988.858556,28110.553782,1,97,6,6,2.69,2,1,0,0,0,1,31,1,5,6,NA +62473,7,2,2,17,NA,4,4,1,17,209,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,18163.985724,18749.311901,2,101,6,6,1.9,2,2,0,1,0,2,42,1,5,5,NA +62474,7,2,2,71,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,31347.021791,31681.790338,1,98,6,3,1.13,2,1,0,0,2,1,69,1,4,6,NA +62475,7,2,1,22,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,36750.682715,37321.834378,2,97,6,1,0.05,2,1,0,0,0,1,22,1,3,6,NA +62476,7,2,1,40,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,28680.660607,28606.985896,3,91,6,3,1.29,2,1,0,0,0,1,40,1,3,5,NA +62477,7,2,1,11,NA,3,3,1,11,139,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,21839.599095,22875.076583,1,98,7,7,1.03,7,7,0,4,0,2,20,1,3,5,NA +62478,7,2,1,5,NA,4,4,1,5,62,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8275.349856,8376.287205,2,95,1,1,0.03,2,2,1,0,0,1,24,1,3,5,NA +62479,7,2,2,36,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,11608.998717,11632.703325,3,90,10,10,2.41,5,5,1,2,0,1,44,2,4,1,5 +62480,7,2,1,43,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,105141.812429,110055.244549,1,98,14,14,4.12,4,4,0,2,0,2,36,1,5,1,3 +62481,7,2,2,39,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,5,4,2,2,2,2,1,2,2,1,2,2,1,27127.983961,27837.333201,2,90,10,10,3.13,4,4,1,2,0,2,39,1,5,4,NA +62482,7,2,2,32,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,NA,NA,NA,NA,31335.13799,31552.004994,1,95,10,6,1.34,5,4,1,2,0,1,32,1,3,6,NA +62483,7,2,1,11,NA,3,3,2,12,144,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,25604.034863,26336.174292,1,95,4,4,0.65,6,6,2,2,0,2,36,1,4,6,NA +62484,7,2,2,42,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,27585.470618,26830.521849,2,102,6,6,1.22,5,5,0,2,0,2,42,1,4,1,4 +62485,7,2,1,21,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,25815.880139,26556.735732,2,101,99,1,0.28,2,1,0,0,0,1,21,1,4,5,NA +62486,7,1,2,14,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,117872.104347,0,2,101,8,8,1.72,5,5,0,3,0,1,37,1,3,1,3 +62487,7,2,1,65,NA,2,2,2,NA,NA,1,1,2,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,10655.434864,11610.446696,1,90,14,14,5,2,2,0,0,2,1,65,2,2,1,3 +62488,7,1,1,9,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,41165.805324,0,2,100,15,15,5,4,4,1,1,0,1,29,1,4,1,4 +62489,7,2,2,1,22,4,4,1,NA,23,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7281.670423,7938.059494,2,96,4,4,0.4,7,7,3,2,0,2,25,1,2,5,NA +62490,7,2,1,0,6,3,3,1,NA,7,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15379.505002,15960.887694,1,102,14,14,3,6,6,1,2,0,1,44,1,4,1,5 +62491,7,2,2,61,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,3,1,NA,1,2,1,1,2,2,1,2,1,3,18695.172864,19350.637044,2,102,15,15,5,5,5,1,0,2,1,30,1,4,1,5 +62492,7,2,1,6,NA,5,7,1,6,74,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8227.856305,8510.505183,3,91,10,10,2.48,5,5,2,1,0,2,27,1,2,1,4 +62493,7,2,2,0,7,5,7,1,NA,8,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6570.947402,7236.391986,2,102,7,7,2.65,2,2,1,0,0,2,42,1,4,5,NA +62494,7,2,1,28,NA,2,2,1,NA,NA,2,NA,2,2,3,NA,4,1,NA,1,2,2,1,2,2,2,2,2,2,37970.860743,39407.668593,2,92,15,7,3.67,2,1,0,0,0,1,28,2,4,1,NA +62495,7,2,1,44,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,86361.036512,88802.863313,2,93,10,10,3.61,3,3,0,0,2,1,75,1,4,1,4 +62496,7,2,1,4,NA,1,1,1,4,50,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,18754.85406,18780.196288,2,102,5,5,0.89,4,4,2,0,0,1,33,2,9,1,2 +62497,7,2,1,12,NA,3,3,2,12,145,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,61479.689958,61628.148021,2,100,15,15,4.5,6,6,0,4,0,1,45,1,5,1,5 +62498,7,2,2,13,NA,1,1,1,13,159,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,20347.899985,21072.708732,3,92,15,15,3.15,7,7,0,4,0,2,35,2,3,3,NA +62499,7,2,2,1,14,5,7,2,NA,15,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9679.976914,10817.322533,1,95,4,4,0.97,3,3,2,0,0,2,22,1,4,5,NA +62500,7,2,2,52,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,18441.731082,18102.807884,1,96,12,12,NA,2,2,0,0,0,1,46,1,4,1,5 +62501,7,2,2,30,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,77778.949308,78018.093799,1,101,14,14,3.15,5,5,2,1,0,1,35,1,4,1,5 +62502,7,2,1,35,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,14739.896059,14808.93904,2,99,3,3,0.42,6,6,1,2,0,2,43,1,4,6,NA +62503,7,2,1,5,NA,3,3,2,5,65,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,22669.354731,25576.419472,2,95,6,6,0.9,6,6,1,1,0,1,49,1,1,1,1 +62504,7,2,2,30,NA,2,2,1,NA,NA,2,NA,2,2,4,NA,1,6,2,2,2,2,2,2,2,2,2,1,2,38161.026403,37131.361742,1,100,3,3,0.39,5,5,1,2,0,1,32,2,1,6,NA +62505,7,2,2,3,NA,1,1,1,3,47,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,13196.707564,13241.769839,2,96,77,77,NA,7,7,3,2,0,2,33,2,2,6,NA +62506,7,2,2,46,NA,2,2,1,NA,NA,2,NA,2,1,6,NA,3,1,NA,2,2,2,1,2,2,NA,NA,NA,NA,29105.053716,30161.539189,2,93,4,4,0.84,3,3,0,1,0,2,46,2,3,1,2 +62507,7,2,2,17,NA,1,1,1,17,207,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,18581.167701,19284.858627,2,96,3,3,0.24,7,7,2,3,1,2,40,1,3,3,NA +62508,7,2,1,3,NA,3,3,2,3,39,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,58332.578536,68350.303275,1,91,15,15,5,3,3,1,0,0,1,36,1,4,1,5 +62509,7,2,2,60,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,30131.691064,30623.993423,2,95,6,6,1.36,3,3,0,0,2,2,60,1,5,1,4 +62510,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,62763.524469,78020.806152,1,92,7,7,2.64,2,2,0,0,2,1,80,1,3,1,3 +62511,7,2,1,9,NA,3,3,2,9,109,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,25019.74954,25881.463934,1,101,3,3,0.44,5,5,0,3,0,1,35,1,3,1,4 +62512,7,2,1,39,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,17605.619977,18470.699991,3,91,15,15,5,4,4,1,1,0,1,39,2,5,1,5 +62513,7,2,2,46,NA,2,2,2,NA,NA,2,NA,2,2,6,NA,1,1,NA,2,2,2,2,2,2,2,2,2,2,29470.67209,35523.062266,1,90,5,5,1,4,4,0,2,0,1,40,2,2,1,1 +62514,7,2,1,44,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,19633.637051,20188.770976,2,95,6,6,1.19,4,4,0,1,0,1,44,1,3,1,2 +62515,7,2,2,42,NA,2,2,2,NA,NA,2,NA,2,2,4,NA,1,5,2,2,2,2,2,2,2,2,2,2,2,31235.666551,33485.036978,2,94,1,1,0.01,7,7,1,3,0,1,41,2,1,1,1 +62516,7,2,1,10,NA,2,2,2,10,127,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18107.947773,18538.358733,1,97,14,14,3.25,4,4,0,2,0,1,45,1,3,6,NA +62517,7,2,1,80,NA,3,3,2,NA,NA,2,NA,2,1,8,NA,1,1,NA,1,2,1,1,2,1,1,2,1,NA,11483.380372,15883.29652,1,90,77,77,NA,2,2,0,0,2,1,80,2,1,1,1 +62518,7,1,1,47,NA,5,6,NA,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,16651.742047,0,1,100,15,15,5,3,3,0,0,0,1,47,2,5,1,5 +62519,7,2,1,56,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,NA,17801.655316,19397.911862,2,95,7,2,0.72,3,1,0,0,0,2,56,1,3,2,NA +62520,7,2,1,0,0,3,3,2,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11017.136221,10826.673882,1,91,3,3,0.89,2,2,1,0,0,2,23,1,3,3,NA +62521,7,2,2,59,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,178239.535384,176744.998212,1,102,14,14,5,2,2,0,0,1,2,59,1,5,3,NA +62522,7,2,1,54,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,24930.322327,25494.618871,2,94,9,9,5,1,1,0,0,0,1,54,1,4,3,NA +62523,7,2,1,33,NA,4,4,2,NA,NA,2,NA,2,2,3,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,23872.904125,23622.849234,1,91,6,6,0.99,5,5,3,0,0,2,33,2,3,1,4 +62524,7,2,1,23,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,91704.59836,93129.802737,1,93,15,7,3.67,6,1,0,0,0,1,23,1,5,5,NA +62525,7,2,1,15,NA,5,6,2,15,189,NA,NA,2,2,3,10,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10725.405063,11099.246363,2,94,3,3,0.68,3,2,0,1,0,2,45,2,4,3,NA +62526,7,2,2,62,NA,2,2,2,NA,NA,2,NA,2,2,6,NA,3,1,NA,2,2,2,2,2,2,1,2,2,2,8811.978874,9348.531299,3,90,12,12,NA,3,3,0,0,1,2,62,2,3,1,5 +62527,7,2,1,79,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,NA,9541.516696,10104.465045,1,100,77,77,NA,1,1,0,0,1,1,79,1,2,5,NA +62528,7,2,1,40,NA,2,2,2,NA,NA,2,NA,2,2,6,NA,1,6,NA,2,2,2,2,2,2,2,2,1,NA,25035.846455,24668.484001,2,99,99,99,NA,5,3,0,1,0,1,40,2,1,6,NA +62529,7,2,1,59,NA,4,4,2,NA,NA,2,NA,2,1,7,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,15760.921402,16568.510632,3,90,12,12,NA,3,3,0,0,0,1,59,2,4,1,4 +62530,7,2,2,51,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,141316.739364,156265.607046,2,94,5,5,0.89,4,4,0,2,0,2,51,1,2,3,NA +62531,7,2,2,52,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,20149.292081,21423.504707,2,99,2,2,0.4,2,2,0,0,0,2,52,1,3,1,3 +62532,7,2,2,64,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,77,NA,1,2,2,1,2,2,1,2,2,1,11523.037911,11989.050618,2,97,13,13,NA,1,1,0,0,1,2,64,1,3,77,NA +62533,7,2,2,1,17,1,1,2,NA,18,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9955.153132,10089.038145,2,94,8,8,2.7,3,3,1,0,0,2,23,2,4,1,3 +62534,7,2,1,13,NA,5,7,1,13,159,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11068.745625,11332.552011,1,103,3,3,0.37,5,5,1,2,0,2,30,1,4,5,NA +62535,7,2,2,5,NA,3,3,1,5,69,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,69665.012606,74034.381659,3,92,14,14,2.74,6,6,2,2,0,1,35,1,5,1,4 +62536,7,2,1,46,NA,5,6,1,NA,NA,2,NA,2,2,5,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,14238.597316,14347.374047,2,92,15,9,5,2,1,0,0,0,1,40,NA,NA,77,NA +62537,7,2,2,10,NA,3,3,2,11,133,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15442.305642,15459.941839,2,94,7,7,1.62,5,5,0,3,0,1,30,1,2,1,9 +62538,7,2,2,1,16,4,4,2,NA,16,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6802.424856,6978.006983,2,99,15,15,5,4,4,2,0,0,1,34,1,5,1,5 +62539,7,2,1,60,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,1,10717.375231,11218.730451,2,101,2,2,0.92,1,1,0,0,1,1,60,1,2,2,NA +62540,7,2,2,0,3,3,3,1,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,22478.08837,21867.533571,3,91,10,10,3,4,4,2,0,0,1,32,1,4,1,5 +62541,7,2,2,13,NA,3,3,1,13,163,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,68399.970058,69290.143431,1,102,14,14,4.05,3,3,0,2,0,2,34,1,4,3,NA +62542,7,2,2,11,NA,2,2,1,11,137,NA,NA,1,1,NA,3,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,14414.529053,14932.182215,2,96,2,2,0.27,6,6,1,3,0,1,34,NA,NA,1,NA +62543,7,2,2,1,12,2,2,2,NA,12,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,11981.824297,12142.965635,2,91,2,2,0.26,4,4,1,1,0,2,42,2,4,3,NA +62544,7,2,1,42,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,18533.049642,19320.837782,1,99,14,14,4.86,3,3,0,1,0,1,42,1,5,1,5 +62545,7,2,1,8,NA,2,2,2,8,107,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15673.230419,15680.173615,1,97,15,15,4.52,6,6,0,4,0,2,41,1,5,1,5 +62546,7,2,1,64,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,13473.930124,13736.530204,1,92,6,6,2.69,1,1,0,0,1,1,64,1,4,2,NA +62547,7,2,1,9,NA,1,1,2,9,113,NA,NA,1,1,NA,2,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,13484.595524,13562.00827,1,97,3,3,0.5,5,5,0,2,0,1,56,2,2,6,NA +62548,7,2,1,57,NA,2,2,1,NA,NA,1,2,2,1,8,NA,3,5,NA,1,2,2,1,2,2,2,2,2,1,25422.415762,25922.20279,2,100,7,7,2.64,2,2,0,0,1,1,57,2,3,5,NA +62549,7,2,1,53,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,3,1,NA,1,2,1,1,2,2,NA,NA,NA,NA,10579.097347,10866.833801,2,92,8,8,2.01,4,4,0,0,0,1,53,2,3,1,3 +62550,7,2,2,9,NA,5,7,1,9,112,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8292.876947,8466.609309,1,102,15,15,5,4,4,0,2,0,2,40,2,5,1,4 +62551,7,2,2,37,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,86578.861495,89840.962333,2,101,15,15,5,3,3,1,0,0,1,37,1,5,1,5 +62552,7,2,2,41,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,139800.409559,140918.856987,1,100,15,15,4.07,5,5,0,2,0,2,41,1,5,1,4 +62553,7,2,1,8,NA,5,6,2,8,100,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,4945.578914,5359.127104,3,91,14,14,2.5,6,6,1,1,1,2,37,2,2,1,5 +62554,7,2,2,15,NA,5,6,1,15,188,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12546.119668,12876.82216,2,102,14,14,4.86,3,3,0,1,0,1,55,NA,NA,1,5 +62555,7,2,1,35,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,23471.353577,23548.945779,1,100,7,7,1.83,3,3,0,1,0,2,40,1,4,6,NA +62556,7,2,2,31,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,17978.142628,18308.053591,1,91,10,10,3.78,3,3,1,0,0,1,35,2,5,1,5 +62557,7,2,1,10,NA,1,1,2,10,122,NA,NA,1,1,NA,3,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,10591.186197,11647.778431,1,90,4,4,0.46,7,7,2,3,0,2,34,2,1,6,NA +62558,7,2,2,49,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,20084.755052,20500.648257,1,99,14,14,3.67,4,4,1,0,0,2,49,1,3,1,3 +62559,7,2,2,9,NA,1,1,2,9,109,NA,NA,1,1,NA,4,NA,NA,NA,2,1,2,1,2,2,2,2,2,1,18668.602894,22428.786321,1,101,5,5,0.51,7,7,0,3,2,1,75,2,1,1,1 +62560,7,2,2,56,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,12435.659176,12095.32474,1,96,77,77,NA,7,7,1,3,0,1,56,1,3,1,4 +62561,7,2,2,10,NA,3,3,1,10,122,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,50248.753555,51858.292831,2,100,8,8,2.91,3,3,0,2,0,2,48,1,5,1,NA +62562,7,2,1,4,NA,1,1,1,4,59,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,17865.135763,18076.339981,3,92,1,1,0,5,5,3,0,0,1,26,1,2,1,2 +62563,7,2,2,72,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,7,77,NA,1,2,2,1,2,2,1,2,2,NA,13638.730054,13839.452317,1,99,12,12,NA,1,1,0,0,1,2,72,1,7,77,NA +62564,7,2,2,13,NA,4,4,2,13,162,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11711.384457,11743.959438,2,95,1,1,0.17,2,2,0,1,0,2,49,1,3,99,NA +62565,7,2,1,23,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,5,NA,1,2,2,1,2,2,1,2,2,3,14385.653726,15533.829525,2,101,7,5,1.84,2,1,0,0,0,1,27,2,5,5,NA +62566,7,2,2,2,NA,4,4,1,2,27,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7734.994032,8078.467013,2,95,1,1,0.18,4,4,2,1,0,2,38,1,2,5,NA +62567,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,1,3,NA,1,2,2,1,2,2,1,2,2,NA,22991.276372,25575.167764,1,99,99,99,NA,1,1,0,0,1,2,80,1,1,3,NA +62568,7,2,2,1,13,1,1,1,NA,14,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,10867.770426,11631.363355,1,100,4,4,0.56,5,5,2,0,0,2,25,2,2,1,2 +62569,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,45973.010529,51521.910389,1,94,8,8,3.47,2,2,0,0,1,2,80,1,1,2,NA +62570,7,2,1,6,NA,4,4,2,6,72,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8655.162127,8675.53524,2,101,2,2,0.22,4,4,1,1,0,2,41,1,2,4,NA +62571,7,2,2,32,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,85420.170155,86011.35365,1,91,14,14,3.06,5,5,2,0,0,2,30,1,5,1,5 +62572,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,NA,47566.45715,54102.989916,1,90,7,7,3.22,1,1,0,0,1,2,80,1,5,3,NA +62573,7,2,2,48,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,30442.30641,30472.199404,1,95,6,3,1.1,2,1,0,0,0,2,48,1,4,3,NA +62574,7,2,2,13,NA,3,3,2,13,166,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,132630.209478,136814.3405,1,97,9,9,2.88,3,3,0,1,0,2,33,1,3,5,NA +62575,7,2,2,24,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,129336.409693,130993.13082,1,95,12,12,NA,6,6,2,0,0,2,42,1,2,1,5 +62576,7,2,1,66,NA,1,1,1,NA,NA,2,NA,2,1,77,NA,1,1,NA,2,2,2,1,2,2,1,2,2,NA,14488.953694,14771.336069,3,92,9,9,2.22,5,5,1,0,2,1,66,2,1,1,1 +62577,7,2,2,71,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,72551.269339,73326.076054,1,92,6,6,2.04,2,2,0,0,2,2,71,1,4,1,1 +62578,7,2,2,6,NA,3,3,1,6,76,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,48532.852397,48387.04619,1,101,7,7,1.55,5,5,1,2,0,2,31,1,4,1,2 +62579,7,2,1,78,NA,1,1,1,NA,NA,1,2,2,1,9,NA,4,1,NA,2,2,2,1,2,2,1,2,2,NA,12782.642018,13005.47245,2,96,5,5,1.08,3,3,0,0,2,1,53,2,4,3,NA +62580,7,2,2,14,NA,3,3,2,14,172,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,38400.791741,38900.548719,1,92,4,4,0.5,6,6,0,3,0,2,41,1,4,1,NA +62581,7,2,2,10,NA,3,3,1,10,128,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,53370.126656,53491.559571,2,98,15,15,5,3,3,0,1,0,1,48,1,4,1,5 +62582,7,1,2,10,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,23170.920553,0,1,94,4,4,1.26,2,2,0,1,0,1,40,1,4,3,NA +62583,7,2,2,17,NA,3,3,1,17,212,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,93740.540203,99321.165816,1,100,8,8,1.95,4,4,0,2,1,2,49,1,5,6,NA +62584,7,2,1,22,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,29738.952706,31253.462984,2,94,8,8,3.4,2,2,0,0,0,1,22,1,3,5,NA +62585,7,2,2,80,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,14859.685983,15314.825218,1,95,3,3,0.98,1,1,0,0,1,2,80,1,3,2,NA +62586,7,2,1,70,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,NA,68266.732554,71967.824097,1,95,5,5,2.02,1,1,0,0,1,1,70,1,3,5,NA +62587,7,2,1,73,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,NA,15565.766387,16476.020536,1,101,3,3,1.07,2,1,0,0,1,1,73,1,4,6,NA +62588,7,2,1,21,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,137038.746155,146293.19093,2,101,3,1,0.18,2,1,0,0,0,1,21,1,4,5,NA +62589,7,2,2,75,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,NA,61388.874846,64435.558603,1,90,7,7,1.89,3,3,0,0,1,2,75,1,4,3,NA +62590,7,2,1,11,NA,4,4,2,11,133,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8483.005475,8584.70346,1,96,7,7,1.69,4,4,0,1,0,2,19,2,4,NA,NA +62591,7,2,1,10,NA,3,3,1,10,131,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,54897.892683,57357.850008,2,98,14,14,3.58,4,4,0,2,0,1,36,1,3,1,4 +62592,7,2,1,0,5,3,3,2,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9665.908305,9498.805759,1,95,5,5,1.08,3,3,1,0,0,2,22,1,3,6,NA +62593,7,2,2,72,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,64463.340883,65151.773075,1,91,7,7,2.92,2,2,0,0,1,2,47,1,5,5,NA +62594,7,2,1,0,10,4,4,2,NA,10,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5707.173345,5961.496632,1,90,4,4,0.67,5,5,3,0,0,2,32,2,3,3,NA +62595,7,2,2,28,NA,5,7,1,NA,NA,2,NA,2,1,5,NA,4,1,3,1,2,2,1,2,2,1,2,2,1,13851.686232,14954.517784,3,91,14,14,4.32,3,3,1,0,0,1,31,2,3,1,4 +62596,7,2,2,52,NA,5,6,1,NA,NA,2,NA,2,2,4,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,11428.6913,11489.125563,1,103,5,5,0.65,6,6,0,0,1,2,26,2,4,5,NA +62597,7,2,2,60,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,1,11696.973403,12170.020379,2,97,6,6,1,6,6,1,2,2,2,60,1,2,2,NA +62598,7,2,1,18,NA,4,4,1,18,223,2,NA,1,1,NA,12,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11666.009872,12200.765691,2,100,14,4,0.43,7,7,1,3,1,2,62,1,3,5,NA +62599,7,2,2,50,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,17521.481386,17644.217766,2,97,5,5,0.76,5,5,0,0,0,2,50,1,4,5,NA +62600,7,2,1,10,NA,2,2,1,10,125,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,10738.959181,10632.988891,2,93,14,14,3.25,4,4,0,2,0,2,46,2,5,1,4 +62601,7,2,1,65,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,9636.209947,9711.587411,2,97,14,14,5,2,2,0,0,1,2,52,1,5,1,3 +62602,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,60071.993203,65791.533402,1,95,8,8,4.59,1,1,0,0,1,2,80,1,4,2,NA +62603,7,2,2,38,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,6,2,1,2,2,1,2,2,1,2,2,1,39561.667842,42653.886229,2,98,6,6,1.25,4,4,1,0,1,1,46,1,2,6,NA +62604,7,2,2,73,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,NA,69886.968852,80170.534309,1,102,4,4,1.42,1,1,0,0,1,2,73,1,3,5,NA +62605,7,1,1,1,22,5,6,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7025.964374,0,2,91,4,4,0.65,5,5,1,3,0,1,43,2,3,5,NA +62606,7,2,1,2,NA,4,4,1,2,25,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5930.749873,6003.089312,2,93,6,6,1.98,2,2,1,0,0,2,51,1,2,3,NA +62607,7,2,1,4,NA,4,4,1,4,52,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10040.033098,11070.778245,1,100,1,1,0.04,4,4,1,1,0,2,51,1,3,3,NA +62608,7,1,2,67,NA,2,2,NA,NA,NA,2,NA,2,1,NA,NA,2,1,NA,1,2,2,NA,NA,NA,NA,NA,NA,NA,7278.790659,0,2,93,NA,NA,NA,2,2,0,0,2,1,68,NA,NA,1,2 +62609,7,2,1,9,NA,3,3,2,9,112,NA,NA,1,1,NA,3,NA,NA,NA,1,NA,2,1,2,2,1,2,2,1,25604.034863,26336.174292,1,95,5,5,0.92,5,5,1,2,0,2,30,1,4,1,4 +62610,7,2,2,12,NA,2,2,1,12,146,NA,NA,2,2,1,4,NA,NA,NA,2,1,2,2,2,2,2,2,1,2,18006.855255,21837.57166,1,100,3,3,0.39,5,5,1,2,0,1,32,2,1,6,NA +62611,7,2,1,45,NA,5,6,2,NA,NA,2,NA,2,2,6,NA,2,4,NA,1,2,2,1,2,2,1,2,2,1,11725.7448,11815.324423,2,95,3,3,1.16,1,1,0,0,0,1,45,2,2,4,NA +62612,7,2,2,38,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,21619.283038,22049.338941,2,102,9,9,2.68,4,4,1,1,0,2,38,2,5,1,2 +62613,7,2,2,29,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,28394.357741,26997.683446,1,100,3,3,0.66,2,2,0,1,0,2,29,1,4,1,NA +62614,7,2,1,12,NA,3,3,2,12,154,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,58479.782556,60361.370686,1,99,15,15,4.47,4,4,0,2,0,2,43,1,5,1,5 +62615,7,2,2,0,11,4,4,2,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,3774.069255,3925.050204,2,99,5,5,0.78,5,5,2,2,0,2,30,1,3,5,NA +62616,7,2,2,37,NA,5,6,2,NA,NA,2,NA,2,2,2,NA,1,1,2,1,2,1,1,2,2,1,2,1,NA,15542.93857,16609.63545,3,91,4,4,0.69,5,5,0,2,0,1,45,2,4,1,1 +62617,7,2,1,8,NA,5,7,1,8,104,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8439.403196,8726.876152,2,103,6,6,1.11,5,5,1,2,0,2,36,1,4,5,NA +62618,7,2,1,10,NA,5,7,2,10,129,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7923.925927,8546.646915,1,91,15,15,5,5,5,0,3,0,1,40,1,5,1,5 +62619,7,2,1,80,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,NA,24023.719783,25884.561742,2,96,7,7,3.21,2,1,0,0,1,1,80,1,5,5,NA +62620,7,2,2,7,NA,2,2,1,7,92,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,18660.103977,19985.967776,2,91,6,6,0.93,5,5,1,2,0,1,34,1,2,1,3 +62621,7,2,1,41,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,23242.990557,23753.836506,1,100,8,8,1.95,4,4,0,2,0,2,42,1,4,1,4 +62622,7,2,2,15,NA,5,6,2,16,192,NA,NA,2,1,4,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,10963.340882,11440.408955,2,91,15,15,5,4,4,0,2,1,2,56,1,5,1,5 +62623,7,2,2,78,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,39653.38014,40869.906755,2,95,6,6,1.57,3,3,0,0,2,1,80,1,2,1,4 +62624,7,2,2,40,NA,5,6,2,NA,NA,2,NA,2,1,5,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,18255.735511,19354.37213,2,91,14,14,3.47,4,4,1,1,0,2,40,2,5,1,NA +62625,7,2,2,60,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,15207.312407,15896.113669,1,92,15,15,5,3,3,0,0,1,1,57,1,3,1,4 +62626,7,2,1,13,NA,1,1,2,13,157,NA,NA,1,1,NA,6,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,17314.330266,19031.527568,1,90,4,4,0.46,7,7,2,3,0,2,34,2,1,6,NA +62627,7,2,2,2,NA,1,1,2,2,26,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,9955.153132,10379.318342,2,94,9,9,2.29,5,5,2,1,0,2,33,2,3,1,1 +62628,7,2,2,1,19,3,3,2,NA,19,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16717.071084,17765.560854,2,94,8,8,1.6,6,6,3,1,0,2,32,1,4,1,4 +62629,7,2,1,11,NA,5,6,2,11,138,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6262.834446,6755.01452,3,90,12,12,NA,5,5,1,2,0,1,37,2,5,1,5 +62630,7,2,2,68,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,1,149153.684635,157450.342804,1,101,3,3,1.25,1,1,0,0,1,2,68,1,2,2,NA +62631,7,2,2,37,NA,3,3,2,NA,NA,2,NA,2,1,4,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,77778.949308,79987.938327,1,101,6,6,1.28,4,4,2,0,0,1,44,1,4,1,4 +62632,7,2,1,29,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,14424.961621,14817.68753,2,102,5,5,1.08,3,3,0,1,0,2,46,2,1,5,NA +62633,7,2,2,61,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,12176.672371,12646.648452,2,92,15,15,5,2,2,0,0,2,1,61,1,5,1,5 +62634,7,2,1,68,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,114174.703171,113009.251918,2,97,8,8,3.06,2,2,0,0,2,1,68,1,2,1,4 +62635,7,2,2,27,NA,5,6,2,NA,NA,2,NA,2,2,1,NA,5,1,2,1,2,1,1,2,2,NA,NA,NA,NA,13851.686232,14678.247845,3,91,5,5,1.08,3,3,1,0,0,1,29,2,5,1,5 +62636,7,2,1,17,NA,4,4,1,17,215,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12147.046136,12703.852077,2,100,4,4,0.86,3,3,0,2,0,2,36,1,3,5,NA +62637,7,2,2,3,NA,4,4,1,3,47,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13130.790087,13857.266639,2,102,15,15,4.2,5,5,1,2,0,2,29,NA,NA,1,NA +62638,7,2,2,9,NA,4,4,2,9,111,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12120.418061,13050.526646,2,101,13,3,0.64,5,4,0,3,1,2,62,1,1,2,NA +62639,7,2,2,26,NA,2,2,2,NA,NA,2,NA,2,2,3,NA,1,6,2,2,2,2,1,2,2,2,2,2,2,43708.837271,43518.466069,1,96,9,9,3.97,2,2,0,0,0,1,28,2,2,6,NA +62640,7,2,2,31,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,6,2,1,2,2,1,2,2,1,2,2,1,26546.087356,29693.438127,1,102,6,6,1.12,4,4,2,0,0,2,31,1,3,6,NA +62641,7,2,1,2,NA,1,1,1,3,36,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10276.786905,10602.092524,1,102,14,14,2.83,6,6,1,2,0,1,36,1,2,1,3 +62642,7,2,1,30,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,22188.836739,23607.684366,1,95,1,1,0.11,1,1,0,0,0,1,30,1,3,5,NA +62643,7,2,2,2,24,4,4,2,2,24,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5687.793894,6161.690011,2,90,99,99,NA,5,5,1,0,0,1,20,1,3,5,NA +62644,7,2,1,61,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,11761.359913,11893.852645,1,95,5,5,1.79,1,1,0,0,1,1,61,1,4,2,NA +62645,7,2,2,12,NA,5,6,1,12,153,NA,NA,2,2,2,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6391.016092,6494.382638,1,100,99,99,NA,6,6,0,1,0,1,53,2,2,1,3 +62646,7,2,2,57,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,17164.211773,16694.46809,2,99,8,8,3.57,2,2,0,0,1,1,67,1,2,1,2 +62647,7,2,1,0,0,2,2,1,NA,0,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8143.831412,8143.981517,2,102,5,5,0.89,4,4,2,0,0,1,45,1,3,1,4 +62648,7,2,2,80,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,1,2,NA,1,2,1,1,2,2,1,2,1,NA,19516.411172,20124.53654,2,102,10,10,4.76,2,2,0,0,1,2,49,2,5,5,NA +62649,7,2,1,76,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,9334.084938,9516.918553,2,96,8,8,2.59,3,3,0,0,2,1,76,1,3,1,4 +62650,7,2,1,71,NA,4,4,1,NA,NA,2,NA,2,1,7,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,7110.382011,7529.893703,2,93,6,6,1.85,2,2,0,0,2,1,71,2,1,1,2 +62651,7,2,1,55,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,NA,152467.08796,155918.172532,1,94,6,6,2.69,1,1,0,0,0,1,55,1,3,3,NA +62652,7,2,1,46,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,4,NA,1,2,2,1,2,2,1,2,2,1,34205.013302,40575.476948,2,102,14,14,2.44,7,7,0,2,1,2,71,1,3,3,NA +62653,7,1,1,49,NA,5,6,NA,NA,NA,2,NA,2,2,4,NA,3,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,13323.689579,0,2,92,6,6,1.3,4,4,0,1,0,2,48,2,3,1,3 +62654,7,1,1,4,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,30553.632981,0,1,98,5,2,0.42,4,3,2,0,0,1,24,1,3,6,NA +62655,7,2,1,1,23,4,4,1,NA,23,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5930.749873,6003.089312,2,93,9,9,2.6,4,4,1,1,0,1,37,1,4,1,4 +62656,7,2,2,0,9,1,1,2,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,6787.112205,6969.467907,2,94,4,4,0.73,5,5,2,1,0,1,35,2,1,6,NA +62657,7,2,2,2,NA,1,1,1,3,36,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,11401.934012,11887.743086,1,95,13,13,NA,5,5,1,2,0,2,34,2,1,1,1 +62658,7,2,1,68,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,28559.076421,28710.827523,1,92,6,6,2.3,1,1,0,0,1,1,68,1,3,3,NA +62659,7,2,1,18,NA,5,6,1,18,219,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,5526.901806,5811.556543,2,103,7,7,1.65,4,4,0,1,1,2,55,2,3,1,NA +62660,7,2,2,7,NA,5,6,1,7,88,NA,NA,2,1,2,1,NA,NA,NA,1,1,2,1,2,1,NA,NA,NA,NA,7932.110938,8947.143287,3,92,77,77,NA,7,7,2,4,1,1,62,NA,NA,1,NA +62661,7,2,1,35,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,84910.063417,90031.493834,2,96,14,7,3.67,3,1,0,0,0,1,30,2,5,5,NA +62662,7,2,2,11,NA,1,1,1,11,138,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15962.145468,16664.698857,2,98,7,7,1.97,4,4,0,1,0,1,40,1,3,1,3 +62663,7,1,2,3,NA,2,2,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12984.581505,0,2,93,15,15,5,4,4,2,0,0,1,34,1,5,1,5 +62664,7,2,1,64,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,25436.904729,25763.177128,1,94,8,8,3.3,2,2,0,0,2,1,64,1,5,1,3 +62665,7,2,2,67,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,13504.560081,14155.716256,1,102,7,7,1.8,5,4,1,0,2,1,47,1,3,5,NA +62666,7,2,1,3,NA,5,6,1,3,41,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8838.066777,9670.229845,3,92,8,8,0.91,7,7,3,3,1,1,61,NA,NA,1,4 +62667,7,2,1,6,NA,3,3,2,6,73,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,53915.042746,57006.573447,1,91,14,14,2.44,7,7,2,4,0,1,33,1,5,1,5 +62668,7,2,1,33,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,25120.174741,24762.106831,2,102,6,6,1.22,5,5,0,2,0,2,42,1,4,1,4 +62669,7,2,1,33,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,20891.980831,22249.799905,2,97,6,6,1.35,3,3,0,0,0,2,54,1,3,6,NA +62670,7,2,1,13,NA,3,3,2,14,169,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,107087.58296,107224.801212,1,95,8,8,1.28,7,7,1,4,0,1,32,1,3,1,3 +62671,7,2,1,69,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,7973.883342,8036.257566,1,100,77,77,NA,1,1,0,0,1,1,69,1,4,3,NA +62672,7,2,2,13,NA,4,4,1,13,156,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11078.202838,10933.134393,1,102,12,12,NA,7,7,3,2,0,2,52,1,4,5,NA +62673,7,2,1,34,NA,1,1,2,NA,NA,2,NA,2,2,4,NA,1,1,NA,2,2,2,2,2,2,NA,NA,NA,NA,34959.343013,34695.493801,1,97,8,8,1.45,6,6,2,2,0,2,36,2,2,1,1 +62674,7,2,2,33,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,NA,28989.076324,29596.20575,1,93,6,6,1.16,4,4,2,0,0,2,33,1,5,1,4 +62675,7,2,1,0,9,3,3,2,NA,10,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16921.794985,16629.253929,1,99,15,15,5,4,4,1,1,0,2,27,1,5,1,5 +62676,7,2,2,17,NA,3,3,2,17,214,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,111142.989658,114235.009147,1,95,8,8,1.28,7,7,1,4,0,1,32,1,3,1,3 +62677,7,2,2,30,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,56677.205755,57971.218225,2,102,10,10,4.76,2,2,0,0,0,1,27,1,4,1,4 +62678,7,2,1,68,NA,2,2,1,NA,NA,2,NA,2,2,6,NA,1,1,NA,2,2,2,1,2,1,2,2,2,2,9235.951997,9462.879133,2,103,5,5,1.79,2,1,0,0,2,1,68,2,1,1,NA +62679,7,2,2,7,NA,1,1,1,7,90,NA,NA,2,2,2,0,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,15897.166957,16345.216522,2,102,6,3,0.54,6,4,0,4,0,2,43,2,1,5,NA +62680,7,2,1,68,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,7581.139559,8116.967146,3,90,14,14,4.96,2,2,0,0,2,1,68,1,3,1,5 +62681,7,2,2,5,NA,1,1,1,5,65,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,15457.736897,15510.51982,2,98,3,3,0.33,7,7,2,3,0,1,40,2,1,1,1 +62682,7,2,2,62,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,1,44636.780791,48652.73082,2,91,3,3,0.86,2,2,0,0,1,2,62,1,3,2,NA +62683,7,2,2,55,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,16829.599526,17568.396647,1,90,99,99,NA,3,3,0,1,1,1,60,1,5,1,5 +62684,7,2,2,29,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,82612.6713,83351.284903,1,92,10,10,2.1,6,6,1,1,0,2,29,1,4,1,2 +62685,7,2,1,36,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,3,5,NA,1,2,1,1,2,1,1,2,1,1,12869.386353,13443.315161,2,92,7,7,1.89,3,3,0,0,1,1,36,2,3,5,NA +62686,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,38007.846215,47247.232001,1,94,7,7,2.31,2,2,0,0,1,2,80,1,3,2,NA +62687,7,2,1,10,NA,4,4,2,10,131,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8483.005475,8584.70346,1,96,8,8,2,4,4,1,2,0,2,40,1,4,5,NA +62688,7,2,1,24,NA,5,6,2,NA,NA,2,NA,2,1,5,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,10141.381563,13212.383706,3,90,6,6,1.98,2,2,0,0,0,2,47,2,5,2,NA +62689,7,2,1,44,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,116464.874823,116611.129855,2,94,15,15,5,5,5,0,3,0,1,44,1,5,1,4 +62690,7,2,2,26,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,17568.277926,19062.73336,1,90,99,99,NA,2,2,0,1,0,2,26,1,4,5,NA +62691,7,2,1,31,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,18544.003944,19387.603198,2,100,7,7,1.79,4,4,0,1,0,2,51,1,3,3,NA +62692,7,1,2,50,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,17521.481386,0,2,97,7,7,3.49,1,1,0,0,0,2,50,1,4,5,NA +62693,7,2,2,69,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,9570.416297,10279.373686,2,98,5,5,2.2,1,1,0,0,1,2,69,1,2,2,NA +62694,7,2,1,37,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,21219.562726,22239.20882,2,91,3,3,0.86,2,2,0,0,1,2,62,1,3,2,NA +62695,7,2,2,41,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,4,2,1,2,2,1,2,2,1,2,2,1,19130.246369,19734.446951,2,101,2,2,0.22,4,4,1,1,0,2,41,1,2,4,NA +62696,7,2,1,13,NA,4,4,2,13,159,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11351.725436,12116.15399,2,95,6,6,1.3,4,4,1,1,0,1,38,1,4,1,4 +62697,7,2,1,9,NA,2,2,2,9,119,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12477.812875,12553.43469,2,94,6,6,1.43,5,4,2,1,0,2,23,2,3,6,NA +62698,7,1,1,80,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,38666.703155,0,2,94,77,77,NA,2,2,0,0,2,2,80,1,5,1,5 +62699,7,2,1,1,23,4,4,2,NA,23,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4912.962876,5115.96715,2,90,8,8,1.67,6,6,2,2,0,2,35,2,5,3,NA +62700,7,2,1,9,NA,4,4,1,9,119,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9022.8939,9530.778148,2,100,3,3,0.31,7,7,3,2,0,2,28,1,3,1,3 +62701,7,2,2,29,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,30253.427014,31766.413225,2,90,8,8,2.24,4,4,1,1,0,2,29,1,4,6,NA +62702,7,1,2,12,NA,2,2,NA,NA,NA,NA,NA,1,1,NA,55,NA,NA,NA,1,1,2,2,2,2,NA,NA,NA,NA,20322.312754,0,2,91,6,6,1.3,4,4,1,1,0,2,27,1,4,6,NA +62703,7,2,2,2,NA,4,4,2,2,25,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7785.57328,8700.336584,1,96,8,8,2.17,4,4,1,1,0,2,41,1,3,1,3 +62704,7,2,1,80,NA,5,7,1,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,9071.406562,10878.533019,1,94,5,5,1.59,2,2,0,0,2,2,73,1,3,1,3 +62705,7,2,2,30,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,35353.005268,34399.106917,2,91,15,15,5,2,2,0,0,0,2,30,1,4,1,4 +62706,7,2,2,39,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,42150.923371,53077.558906,1,97,9,9,3.7,2,2,0,0,0,1,25,NA,NA,5,NA +62707,7,2,2,49,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,25511.973394,26011.568993,1,98,6,6,0.97,7,7,1,2,0,1,49,1,2,1,2 +62708,7,2,1,52,NA,5,6,2,NA,NA,2,NA,2,1,5,NA,3,1,NA,1,2,1,1,2,1,1,2,1,3,13567.923118,14187.110343,3,91,6,6,1.34,4,4,0,2,0,1,52,2,3,1,1 +62709,7,2,2,10,NA,3,3,2,10,122,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,24070.467912,25563.654853,1,95,6,6,1.09,5,5,0,3,0,1,31,1,4,1,4 +62710,7,2,1,41,NA,2,2,1,NA,NA,2,NA,2,1,4,NA,5,1,NA,2,2,2,2,2,2,NA,NA,NA,NA,36225.654087,36329.951191,2,93,5,5,0.87,4,4,1,1,0,1,41,2,5,1,3 +62711,7,2,1,1,21,3,3,2,NA,23,NA,NA,2,1,2,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,18848.609643,22085.568952,1,91,6,6,2.04,2,2,1,0,0,2,31,1,5,4,NA +62712,7,2,2,4,NA,2,2,1,4,54,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16087.525226,17761.059567,2,91,4,4,0.69,4,4,2,0,0,2,21,1,3,6,NA +62713,7,2,1,15,NA,3,3,2,15,183,NA,NA,1,1,NA,10,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17395.533107,17264.495057,1,99,13,13,NA,4,4,0,2,0,1,55,NA,NA,1,4 +62714,7,2,1,75,NA,1,1,1,NA,NA,1,1,1,1,NA,NA,1,1,NA,2,2,2,2,2,2,1,2,2,NA,14200.083364,15006.095575,3,92,3,3,0.68,2,2,0,0,2,1,75,1,1,1,1 +62715,7,2,1,10,NA,3,3,2,11,132,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,47596.305609,49235.587472,1,99,15,15,3.82,5,5,0,3,0,1,57,1,5,1,5 +62716,7,2,2,42,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,11762.034222,12708.069605,3,90,12,12,NA,5,5,1,2,0,1,37,2,5,1,5 +62717,7,2,2,50,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,32252.129527,31981.695662,1,99,6,4,1.38,2,1,0,0,0,2,50,1,3,6,NA +62718,7,2,1,63,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,6038.685119,6085.921613,1,96,6,6,2.51,1,1,0,0,1,1,63,1,4,5,NA +62719,7,2,1,74,NA,2,2,2,NA,NA,2,NA,2,1,8,NA,1,4,NA,2,2,2,1,2,2,2,2,2,NA,14646.929358,15478.305035,1,96,15,8,4.66,2,1,0,0,2,2,68,2,1,3,NA +62720,7,2,1,58,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,151766.599459,151581.541662,3,91,15,15,5,2,2,0,0,0,2,57,1,5,1,5 +62721,7,2,2,2,NA,3,3,2,2,33,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,33127.913744,33563.225688,1,99,15,15,5,4,4,2,0,0,1,33,1,5,1,5 +62722,7,2,1,1,20,1,1,1,NA,21,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,12493.910388,13386.323284,2,98,6,6,1.21,4,4,1,0,0,2,49,2,2,6,NA +62723,7,2,2,31,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,95214.22557,102645.939709,1,97,15,15,5,3,3,1,0,0,2,31,1,5,1,5 +62724,7,2,2,57,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,187291.098551,189225.431861,2,91,15,15,5,2,2,0,0,1,2,57,1,5,1,5 +62725,7,2,2,3,NA,5,6,2,3,46,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,1,1,2,2,NA,NA,NA,NA,5060.292252,5371.954509,1,90,8,8,1.43,7,7,2,0,0,1,23,2,4,1,3 +62726,7,1,2,1,18,3,3,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,39493.444219,0,2,103,15,15,5,4,4,2,0,0,1,36,2,4,1,5 +62727,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,43807.995099,48928.4376,1,95,6,6,1.65,2,2,0,0,2,2,80,1,4,1,4 +62728,7,2,2,32,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,32569.109434,37398.26507,1,96,77,77,NA,1,1,0,0,0,2,32,1,5,5,NA +62729,7,2,2,1,14,2,2,2,NA,15,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,6962.449638,7451.646327,3,90,12,12,NA,5,5,1,1,0,1,35,2,5,3,NA +62730,7,2,1,0,3,3,3,2,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7493.544598,7825.810309,1,98,6,6,0.97,7,7,1,2,0,1,49,1,2,1,2 +62731,7,2,1,19,NA,1,1,2,19,238,2,NA,2,2,2,12,NA,NA,NA,2,2,2,2,2,2,2,2,2,2,21718.29328,21806.698186,2,94,NA,13,NA,3,2,0,0,0,1,44,2,2,6,NA +62732,7,2,2,71,NA,1,1,2,NA,NA,2,NA,2,2,4,NA,2,1,NA,2,2,2,2,2,2,2,2,2,NA,18067.031882,19590.328656,2,94,2,2,0.56,2,2,0,0,2,2,71,2,2,1,1 +62733,7,1,1,5,NA,5,6,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8253.750998,0,1,90,15,15,5,4,4,2,0,0,1,36,1,5,1,5 +62734,7,2,1,52,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,18783.626894,19376.125899,2,99,2,2,0.53,2,2,0,0,1,2,69,1,4,2,NA +62735,7,2,1,39,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,105261.096488,129835.348564,1,97,15,15,5,4,4,1,1,0,2,33,1,5,1,3 +62736,7,2,2,40,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,17036.134307,17206.306314,2,90,6,6,1.4,3,3,0,1,0,2,40,1,4,5,NA +62737,7,2,1,58,NA,5,6,1,NA,NA,2,NA,2,2,3,NA,1,1,NA,1,2,1,1,2,1,1,2,1,3,10579.097347,10676.360686,2,92,3,3,0.7,3,3,0,0,0,1,58,2,1,1,1 +62738,7,2,1,6,NA,3,3,1,6,80,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,20333.209695,22709.426802,1,103,6,6,1.11,5,5,1,1,1,1,29,1,3,1,3 +62739,7,2,1,74,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,60135.660369,64822.591837,1,90,8,8,2.49,3,3,0,0,2,1,74,1,5,1,2 +62740,7,2,2,19,NA,4,4,2,19,232,2,NA,1,1,NA,12,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12857.456314,12921.235691,2,97,8,8,2.7,3,3,0,0,1,2,72,1,2,3,NA +62741,7,2,2,0,3,4,4,2,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,3861.876549,4122.902052,1,96,14,14,2.91,6,6,1,2,1,2,32,1,5,1,4 +62742,7,2,1,70,NA,2,2,2,NA,NA,2,NA,2,1,8,NA,1,1,NA,2,2,2,2,2,2,1,2,2,NA,12962.876803,13431.341497,2,90,6,6,1.7,2,2,0,0,2,1,70,2,1,1,4 +62743,7,2,1,0,5,3,3,1,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7467.727239,7549.772257,3,91,4,4,0.65,5,5,2,2,0,2,27,2,2,3,NA +62744,7,2,1,37,NA,2,2,2,NA,NA,2,NA,2,1,5,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,43108.74283,45119.517495,2,91,9,9,2.6,4,4,1,1,0,2,31,2,4,1,5 +62745,7,2,2,71,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,12183.823561,13095.132048,2,100,5,5,1.63,2,2,0,0,2,1,71,NA,NA,1,2 +62746,7,2,2,38,NA,2,2,2,NA,NA,2,NA,2,1,4,NA,4,1,2,2,2,2,2,2,2,NA,NA,NA,NA,26897.674477,26781.441446,2,99,77,77,NA,4,4,1,1,1,2,38,2,4,1,4 +62747,7,2,1,52,NA,4,4,1,NA,NA,2,NA,2,1,6,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,19064.767778,19872.734197,2,93,14,14,2.78,5,5,0,0,0,1,52,2,4,1,2 +62748,7,2,1,13,NA,2,2,1,13,164,NA,NA,2,2,1,7,NA,NA,NA,2,1,2,2,2,2,2,2,2,2,15674.964193,15512.049412,2,93,9,9,1.49,7,7,0,3,0,2,41,2,5,1,5 +62749,7,2,1,48,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,22039.963414,22735.178265,1,96,15,15,5,2,2,0,0,0,1,48,1,2,1,3 +62750,7,2,2,45,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,4,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,15890.289377,17041.022437,2,94,3,3,0.68,3,2,0,1,0,2,45,2,4,3,NA +62751,7,2,1,8,NA,3,3,1,8,97,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,21839.599095,22875.076583,1,98,7,7,1.03,7,7,0,4,0,2,20,1,3,5,NA +62752,7,2,1,35,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,59510.728426,61449.871516,1,99,15,15,5,5,5,3,0,0,2,34,1,5,1,5 +62753,7,2,2,16,NA,4,4,1,16,203,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,18421.460617,19740.37466,1,92,6,6,1.3,4,4,0,1,1,1,25,1,1,1,3 +62754,7,2,2,0,7,3,3,2,NA,8,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,25216.508684,24531.572308,1,101,14,14,3.38,4,4,2,0,0,1,32,1,4,1,5 +62755,7,2,2,19,NA,4,4,2,19,235,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12857.456314,12921.235691,2,97,3,3,0.66,3,3,2,0,0,2,19,1,3,NA,NA +62756,7,2,1,7,NA,3,3,2,7,92,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,25604.034863,28346.339599,1,95,7,7,1.66,5,5,0,3,0,1,34,1,2,1,4 +62757,7,2,1,54,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,105571.343095,105442.613847,1,92,10,10,2.1,6,6,1,1,0,2,29,1,4,1,2 +62758,7,1,2,9,NA,5,7,NA,NA,NA,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7722.982971,0,1,93,15,15,5,3,3,0,2,0,2,40,2,5,4,NA +62759,7,2,2,22,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,NA,NA,NA,NA,18395.989535,18290.733411,2,93,9,9,2.07,5,5,0,1,0,1,55,NA,NA,5,NA +62760,7,2,2,10,NA,2,2,2,10,122,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9872.244853,10573.701398,2,90,7,7,0.89,7,7,1,3,3,1,60,2,3,1,3 +62761,7,2,1,68,NA,1,1,1,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,11992.012141,12562.386395,2,102,6,6,1.97,2,2,0,0,2,2,67,1,3,1,3 +62762,7,2,2,1,13,1,1,1,NA,14,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12260.86913,13122.344171,3,92,10,10,2.26,6,6,1,3,0,1,34,1,4,1,1 +62763,7,2,1,29,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,110931.964733,116248.869259,1,94,15,15,5,2,2,0,0,0,1,29,1,4,1,5 +62764,7,2,2,51,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,22969.116046,23881.325913,2,93,1,1,0.36,1,1,0,0,0,2,51,1,3,5,NA +62765,7,2,2,29,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,16844.740449,17564.040518,3,91,7,7,2.45,2,2,0,0,0,2,29,2,5,1,5 +62766,7,2,1,1,22,5,6,2,NA,24,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5891.941477,6363.138629,1,90,6,6,0.92,6,6,2,0,2,2,30,2,5,1,5 +62767,7,1,2,40,NA,2,2,NA,NA,NA,2,NA,1,1,NA,NA,4,5,3,1,2,2,NA,NA,NA,NA,NA,NA,NA,29650.79971,0,2,90,NA,NA,NA,1,1,0,0,0,2,40,1,4,5,NA +62768,7,2,2,38,NA,1,1,1,NA,NA,2,NA,2,2,6,NA,3,4,2,2,2,2,1,2,2,2,2,2,2,42456.72357,41311.151976,1,95,4,4,0.68,5,5,0,1,0,2,38,2,3,4,NA +62769,7,2,2,13,NA,3,3,2,13,162,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,74165.041171,76338.869017,2,94,5,5,0.89,4,4,0,2,0,2,51,1,2,3,NA +62770,7,2,1,1,15,3,3,2,NA,16,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,51373.484735,55257.405076,3,91,14,14,4.32,3,3,1,0,0,1,28,1,5,1,5 +62771,7,2,1,30,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,21863.450986,22291.478781,2,99,2,2,0.75,1,1,0,0,0,1,30,1,2,5,NA +62772,7,2,2,46,NA,1,1,2,NA,NA,2,NA,2,2,1,NA,5,5,NA,2,2,2,1,2,2,2,2,2,2,29995.384937,31080.287607,1,93,15,15,5,3,2,0,1,0,2,46,2,5,5,NA +62773,7,2,2,50,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,27693.650341,27908.388498,3,91,1,1,0.19,3,3,0,2,0,2,50,1,4,3,NA +62774,7,1,1,80,NA,3,3,NA,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,11524.806252,0,1,94,3,3,0.39,6,6,1,0,2,1,80,1,4,1,3 +62775,7,1,2,69,NA,2,2,NA,NA,NA,2,NA,2,1,6,NA,1,3,NA,2,2,2,2,2,2,NA,NA,NA,NA,13676.984152,0,2,91,6,6,1.36,3,3,0,0,1,2,48,2,1,5,NA +62776,7,2,1,9,NA,4,4,1,10,120,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10410.106675,10617.081899,2,96,6,6,1.62,3,3,0,2,0,2,31,1,3,5,NA +62777,7,2,1,28,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,18927.052732,18722.519921,2,92,15,5,1.93,4,1,0,0,0,1,28,1,5,5,NA +62778,7,2,2,4,NA,3,3,2,4,49,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,78365.406271,80834.23308,2,91,14,14,4.12,4,4,2,0,0,1,35,1,5,1,5 +62779,7,2,1,32,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,81291.35274,86533.223356,2,95,12,99,NA,2,1,0,0,0,2,40,1,4,6,NA +62780,7,2,2,5,NA,3,3,1,5,71,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,83950.915901,92655.852423,1,100,15,15,5,4,4,1,1,0,1,40,1,5,1,5 +62781,7,2,2,3,NA,1,1,1,3,44,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10493.785765,10940.90082,1,103,5,5,0.71,6,6,2,2,0,2,31,2,2,1,2 +62782,7,2,2,0,3,5,6,1,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7997.590655,8653.844084,3,91,15,15,5,4,4,2,0,0,1,36,2,5,1,5 +62783,7,2,2,6,NA,2,2,1,6,79,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,2,2,2,NA,NA,NA,NA,15897.166957,16345.216522,2,102,4,4,0.57,6,6,2,3,0,2,26,2,3,1,NA +62784,7,2,1,31,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,39040.678458,46646.692487,3,92,7,7,1.49,5,5,0,2,1,2,62,1,4,2,NA +62785,7,2,1,4,NA,4,4,2,4,58,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8005.528865,8827.404644,1,99,14,14,3.8,4,4,1,1,0,1,48,2,5,1,5 +62786,7,2,1,7,NA,1,1,1,8,96,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,16605.106492,16594.063114,1,92,4,4,0.74,4,4,1,1,0,1,42,2,3,1,4 +62787,7,2,2,21,NA,5,6,2,NA,NA,2,NA,2,1,5,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,11739.283384,12800.154398,1,96,15,15,5,5,5,0,0,0,1,58,2,5,1,5 +62788,7,2,1,35,NA,1,1,2,NA,NA,2,NA,2,2,3,NA,1,6,NA,2,2,2,1,2,2,2,2,2,2,34887.439952,36924.956604,2,94,4,4,0.73,5,5,2,1,0,1,35,2,1,6,NA +62789,7,2,2,26,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,16929.836231,18556.498474,2,101,6,5,2.2,2,1,0,0,0,2,26,2,4,6,NA +62790,7,2,2,11,NA,4,4,2,11,139,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7631.175557,7797.231767,1,93,1,1,0.02,5,5,0,4,0,2,36,NA,NA,5,NA +62791,7,2,1,14,NA,3,3,1,14,173,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,24231.355333,25219.610889,2,100,5,5,1.3,3,3,0,1,0,2,46,1,3,2,NA +62792,7,2,2,52,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,23128.736624,26524.976891,1,98,3,3,1.09,1,1,0,0,0,2,52,1,4,3,NA +62793,7,2,1,72,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,87347.444626,90661.31559,1,95,15,15,5,2,2,0,0,2,1,72,1,3,1,4 +62794,7,2,2,45,NA,4,4,2,NA,NA,2,NA,2,2,4,NA,5,4,NA,1,2,2,1,2,2,1,2,2,1,19757.142379,19558.756904,1,96,8,8,2.17,4,4,0,2,0,2,45,2,5,4,NA +62795,7,2,1,20,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,35522.958395,36075.029683,1,102,13,13,NA,2,1,0,0,0,1,22,1,4,5,NA +62796,7,2,2,17,NA,5,6,2,17,211,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,NA,NA,NA,1,2,2,1,6937.463063,7785.963668,3,90,NA,NA,NA,4,4,0,1,0,1,56,NA,NA,1,NA +62797,7,2,2,24,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,16929.836231,20416.10433,2,101,7,5,1.84,2,1,0,0,0,2,21,NA,NA,5,NA +62798,7,2,1,50,NA,2,2,2,NA,NA,2,NA,2,1,6,NA,2,1,NA,1,2,2,1,2,2,2,2,2,2,27240.276328,27670.554468,1,90,6,6,1.57,3,3,0,0,0,1,50,2,2,1,2 +62799,7,2,2,0,2,4,4,1,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,3800.155777,4057.009552,2,93,3,3,0.36,6,6,1,1,2,2,69,2,3,1,3 +62800,7,2,2,15,NA,3,3,2,15,183,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,103298.858809,106172.653059,1,95,9,9,2.66,4,4,0,2,0,1,45,1,3,1,3 +62801,7,2,2,19,NA,3,3,2,19,229,2,NA,1,1,NA,66,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,23572.289725,23898.02545,2,95,3,3,0.63,3,3,0,0,0,2,44,1,2,4,NA +62802,7,2,1,6,NA,3,3,1,6,78,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,64054.596883,66498.597232,1,92,6,6,1.57,3,3,0,1,0,1,29,1,4,6,NA +62803,7,2,2,34,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,71034.153987,71525.773464,1,98,14,14,3.15,5,5,0,3,0,1,34,1,4,1,4 +62804,7,2,1,69,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,97936.972803,98855.488943,2,95,14,14,5,2,2,0,0,2,2,66,1,5,1,5 +62805,7,2,2,41,NA,4,4,2,NA,NA,2,NA,2,2,4,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,17059.906216,21044.744151,3,90,9,9,4.1,2,2,0,1,0,2,41,2,5,5,NA +62806,7,2,1,53,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,23775.734331,24513.29876,2,96,4,2,0.76,2,1,0,0,0,1,53,1,2,6,NA +62807,7,2,1,67,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,121588.761604,120347.630506,1,91,9,9,4.15,2,2,0,0,2,2,64,1,4,1,5 +62808,7,2,2,44,NA,1,1,1,NA,NA,2,NA,2,2,6,NA,1,1,2,2,2,2,1,2,2,1,2,2,2,31334.47528,32083.194015,2,96,5,5,0.78,5,5,0,2,0,1,37,2,1,5,NA +62809,7,2,2,51,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,1,27004.065356,27080.034561,1,96,1,1,0.23,1,1,0,0,0,2,51,1,3,2,NA +62810,7,2,2,15,NA,3,3,1,15,190,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,105891.533689,107879.366927,1,101,6,6,0.97,7,7,2,1,0,1,43,1,2,1,NA +62811,7,2,2,40,NA,4,4,2,NA,NA,2,NA,2,1,7,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,19258.69251,18731.627868,2,99,12,6,2.69,6,1,0,0,0,2,57,1,5,2,NA +62812,7,2,1,50,NA,1,1,1,NA,NA,2,NA,2,2,6,NA,1,6,NA,2,2,2,2,2,2,NA,NA,NA,NA,37557.946192,37006.841228,2,102,NA,2,0.46,2,1,0,0,1,1,50,2,1,6,NA +62813,7,2,1,71,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,NA,13555.672819,14397.395601,1,94,3,3,1.16,1,1,0,0,1,1,71,1,4,5,NA +62814,7,2,1,72,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,8601.453077,8734.617022,2,101,5,5,1.7,2,2,0,0,1,1,72,1,2,2,NA +62815,7,2,1,4,NA,2,2,1,4,53,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13504.027725,13522.274849,2,93,8,8,2.17,4,4,2,0,0,2,30,1,4,1,4 +62816,7,2,1,23,NA,5,6,1,NA,NA,2,NA,2,2,1,NA,4,5,NA,1,2,1,1,2,1,1,2,1,3,14385.653726,15564.966804,2,101,7,4,1.38,2,1,0,0,0,1,23,2,4,5,NA +62817,7,2,1,41,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,19692.655418,21458.476044,2,99,6,3,0.94,3,2,0,0,0,1,41,1,3,6,NA +62818,7,2,2,52,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,4,NA,1,2,2,1,2,2,1,2,2,1,15521.115746,15096.339697,2,100,7,7,1.34,5,5,0,2,0,2,53,1,4,4,NA +62819,7,2,2,59,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,140431.173819,141856.211353,1,91,8,8,2.17,4,4,0,0,0,1,59,1,4,1,5 +62820,7,2,2,53,NA,5,6,1,NA,NA,2,NA,2,2,6,NA,1,1,NA,1,2,1,1,2,2,1,2,1,NA,21760.356138,22156.586691,1,92,4,4,0.76,4,4,0,0,0,2,53,2,1,1,1 +62821,7,2,2,56,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,1,16058.142925,17073.637087,2,95,7,6,1.88,3,2,0,0,0,2,56,1,3,2,NA +62822,7,2,1,33,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,114838.671743,118127.710351,1,91,8,4,1.38,2,1,0,0,0,1,33,1,5,6,NA +62823,7,2,1,46,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,4,NA,1,2,2,1,2,2,1,2,2,1,20393.886544,21026.540202,2,97,1,1,0.18,1,1,0,0,0,1,46,1,2,4,NA +62824,7,2,2,40,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,29670.405171,29084.152013,2,101,14,14,4.03,4,4,0,1,0,2,40,1,5,1,5 +62825,7,2,2,3,NA,1,1,1,3,47,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9468.006743,10197.085534,1,103,7,7,0.51,7,7,3,4,0,1,54,2,1,1,1 +62826,7,1,2,80,NA,5,7,NA,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,36240.721121,0,1,101,3,3,1.12,1,1,0,0,1,2,80,1,1,2,NA +62827,7,2,2,0,6,5,7,2,NA,7,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,25216.508684,26724.106581,1,101,6,6,1.28,4,4,2,0,0,1,44,1,4,1,4 +62828,7,2,2,21,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,3,1,2,2,1,2,2,NA,NA,NA,NA,60324.348827,61156.73477,1,95,7,2,0.78,2,1,0,0,0,1,26,1,3,6,NA +62829,7,2,1,0,3,1,1,1,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8429.177912,8429.333277,1,95,15,15,5,3,3,1,0,0,1,41,1,5,1,5 +62830,7,2,1,14,NA,3,3,2,14,173,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,88448.252445,87285.839384,1,101,14,14,5,3,3,0,1,0,2,36,1,5,1,5 +62831,7,2,2,4,NA,1,1,1,4,53,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,10024.946819,10059.178608,2,93,77,77,NA,7,7,3,1,0,2,43,2,1,1,9 +62832,7,2,2,15,NA,1,1,1,15,189,NA,NA,1,1,NA,9,NA,NA,NA,2,1,2,1,2,2,1,2,2,2,16427.640886,17012.806816,1,102,3,3,0.54,3,3,0,2,0,2,42,2,2,3,NA +62833,7,2,2,18,NA,3,3,2,18,219,2,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,31627.471241,33789.841724,1,95,1,1,0.21,4,4,1,0,1,2,75,1,1,2,NA +62834,7,2,1,6,NA,1,1,1,7,84,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,11159.151566,11226.781631,1,102,6,6,0.8,7,7,3,3,0,2,34,2,3,1,1 +62835,7,2,2,66,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,12139.361543,12607.897559,2,103,14,14,3.48,5,5,0,2,1,1,43,1,4,1,5 +62836,7,2,1,25,NA,2,2,1,NA,NA,2,NA,2,2,2,NA,3,5,NA,2,2,2,2,2,2,NA,NA,NA,NA,39899.764102,44211.181291,2,93,4,4,0.82,4,4,0,0,0,1,51,2,3,1,3 +62837,7,2,2,18,NA,3,3,2,18,221,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,31716.869763,32646.512808,1,95,77,77,NA,3,3,0,0,0,2,41,1,2,5,NA +62838,7,2,2,44,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,19258.69251,19091.502506,2,99,12,3,1.16,6,1,0,0,0,2,57,1,5,2,NA +62839,7,2,2,3,NA,4,4,2,3,37,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8833.042831,9629.276723,1,99,4,4,0.41,7,7,2,4,0,2,43,1,4,4,NA +62840,7,2,1,60,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,1,2,1,116001.539479,120724.7298,2,101,5,5,1.27,3,3,0,0,1,2,55,1,3,1,1 +62841,7,2,1,52,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,26135.885159,28867.753408,2,101,8,8,2.43,3,3,0,1,0,1,52,1,2,1,5 +62842,7,2,1,4,NA,4,4,2,4,56,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9885.965005,10900.89298,2,97,3,3,0.82,2,2,1,0,0,2,22,1,4,5,NA +62843,7,1,1,14,NA,2,2,NA,NA,NA,NA,NA,2,1,77,8,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,26616.794908,0,2,91,1,1,0.17,4,4,0,1,0,1,49,2,1,6,NA +62844,7,2,1,7,NA,5,6,2,7,91,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4852.395137,5120.382571,1,99,14,14,2.66,7,7,3,1,0,1,35,1,5,1,5 +62845,7,2,1,27,NA,4,4,1,NA,NA,2,NA,2,2,6,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,18831.340773,22141.643614,2,93,14,14,2.78,5,5,0,0,0,1,52,2,4,1,2 +62846,7,1,2,80,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,12535.973802,0,2,100,5,2,0.41,3,2,0,0,2,2,80,1,1,2,NA +62847,7,2,1,44,NA,2,2,2,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,33514.643153,35491.262929,1,90,15,15,5,4,4,0,2,0,2,43,1,5,1,5 +62848,7,2,1,38,NA,4,4,1,NA,NA,2,NA,2,1,7,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,22185.88687,25293.081507,1,98,7,4,1.61,2,1,0,0,0,1,38,2,5,5,NA +62849,7,2,2,40,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,19075.861607,19193.852226,1,96,15,15,5,4,4,0,1,0,1,42,2,4,1,4 +62850,7,2,2,1,14,5,7,1,NA,16,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6257.554806,6809.629993,2,92,15,15,5,3,3,1,0,0,2,37,1,5,1,5 +62851,7,2,1,27,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,94547.245282,99362.23578,2,91,5,5,1.39,2,2,0,0,0,1,58,1,4,3,NA +62852,7,2,2,4,NA,4,4,2,4,53,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8602.397328,9613.133098,2,99,13,13,NA,3,3,1,1,0,2,36,NA,NA,5,NA +62853,7,2,1,16,NA,5,6,1,16,196,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,5526.901806,5811.556543,2,103,7,7,1.65,4,4,0,1,1,2,55,2,3,1,NA +62854,7,2,1,8,NA,4,4,1,8,105,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13239.363106,13690.337986,3,92,6,6,0.93,5,5,2,1,0,2,37,1,5,1,3 +62855,7,2,2,47,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,147198.558516,148052.525251,2,91,14,14,5,1,1,0,0,0,2,47,1,4,3,NA +62856,7,2,2,2,NA,1,1,1,2,25,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,10575.997988,11390.397051,1,100,99,99,NA,7,7,2,3,0,2,35,2,1,1,NA +62857,7,2,2,0,5,4,4,2,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,3659.311381,3880.295282,1,99,8,8,1.99,5,5,1,0,0,1,55,1,5,1,2 +62858,7,2,1,17,NA,4,4,2,17,208,2,NA,1,1,NA,12,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11763.86086,12201.333419,1,99,14,14,4.86,3,3,0,1,1,2,56,1,5,1,5 +62859,7,2,2,53,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,16058.142925,18803.458224,2,95,7,7,1.41,5,5,2,0,0,2,53,1,3,3,NA +62860,7,2,1,55,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,3,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,16499.662173,16948.4296,3,91,6,6,1.81,3,3,0,1,0,2,47,2,3,1,3 +62861,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,60071.993203,66823.228048,1,95,5,5,1.88,1,1,0,0,1,2,80,1,3,1,NA +62862,7,2,1,0,2,3,3,1,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9661.66953,9494.640263,2,95,4,4,0.78,4,4,2,0,0,1,27,1,4,1,4 +62863,7,2,2,1,13,1,1,1,NA,13,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14326.094268,14781.923489,3,92,5,5,0.87,4,4,2,0,0,2,28,1,3,1,3 +62864,7,2,2,57,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,32041.645327,32334.772002,1,94,1,1,0.32,1,1,0,0,0,2,57,1,4,5,NA +62865,7,1,1,17,NA,5,6,NA,NA,NA,2,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,NA,NA,NA,NA,10346.302718,0,2,91,4,4,0.65,5,5,1,3,0,1,43,2,3,5,NA +62866,7,2,2,5,NA,3,3,2,5,68,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,31376.988784,34630.493438,1,101,1,1,0.1,4,4,1,1,0,2,52,1,4,3,NA +62867,7,2,1,12,NA,3,3,2,12,152,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,21603.199906,21630.881484,2,95,5,5,1.05,3,3,0,1,0,1,43,1,3,1,2 +62868,7,2,1,27,NA,3,3,2,NA,NA,2,NA,2,1,2,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,23002.111021,24919.46038,2,97,6,6,1.16,4,4,1,1,0,1,27,2,4,1,3 +62869,7,2,1,2,NA,4,4,2,2,26,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6936.347746,7364.53247,1,98,15,15,5,6,6,3,0,0,1,37,2,5,1,4 +62870,7,2,1,13,NA,1,1,1,13,163,NA,NA,2,2,4,7,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,24228.858782,24791.594558,2,102,4,4,0.57,5,5,0,3,0,1,41,2,1,1,2 +62871,7,2,1,48,NA,5,7,1,NA,NA,2,NA,2,1,8,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,12490.95898,12886.461592,2,92,15,15,4.59,4,4,0,2,0,2,45,2,5,1,5 +62872,7,2,2,17,NA,3,3,1,17,213,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,78268.283998,80112.547303,2,98,15,15,5,4,4,0,2,0,2,46,1,4,1,NA +62873,7,1,1,15,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10879.348751,0,2,100,10,10,2.33,6,6,0,2,2,2,35,1,2,5,NA +62874,7,2,2,33,NA,1,1,2,NA,NA,2,NA,2,2,4,NA,3,6,2,2,2,2,1,2,2,NA,NA,NA,NA,33355.357535,33078.896803,1,90,6,6,1.11,5,5,1,2,0,1,30,2,1,6,NA +62875,7,2,2,46,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,98217.832546,101788.674762,1,99,8,8,2.81,3,3,0,1,0,1,19,1,4,NA,NA +62876,7,2,2,74,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,63504.762752,64182.95787,1,91,7,7,3.67,1,1,0,0,1,2,74,1,4,2,NA +62877,7,2,1,8,NA,4,4,1,8,105,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13423.881856,14179.490667,2,101,1,1,0.15,3,3,0,2,0,2,58,1,3,5,NA +62878,7,2,1,15,NA,4,4,1,15,187,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,16463.950838,16583.858395,2,96,5,5,0.67,6,6,1,2,1,1,34,1,4,1,4 +62879,7,2,2,14,NA,4,4,2,14,171,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18163.985724,18028.02401,2,101,8,8,2.43,3,3,0,1,0,1,52,1,2,1,5 +62880,7,2,2,64,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,117778.281347,120111.495123,1,94,7,7,1.52,4,4,0,2,2,1,61,2,1,1,5 +62881,7,2,2,57,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,134213.669088,137679.44344,1,93,15,15,4.59,4,4,0,1,0,1,57,1,5,1,5 +62882,7,2,1,59,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,2,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,11690.444016,12008.407525,3,90,77,77,NA,4,4,0,0,0,1,59,2,2,1,2 +62883,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,43807.995099,48928.4376,1,101,7,7,2.31,2,2,0,0,2,2,80,1,4,1,2 +62884,7,2,2,36,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,5,3,1,2,2,1,2,2,1,2,2,1,23725.035562,23797.982183,1,94,3,1,0.13,2,1,0,0,0,2,36,1,3,5,NA +62885,7,2,1,60,NA,4,4,2,NA,NA,2,NA,2,1,6,NA,4,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,9392.289727,9639.798184,1,90,15,15,5,3,3,0,0,1,1,60,2,4,2,NA +62886,7,2,1,21,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,15576.264148,16963.869897,1,103,8,8,1.95,4,4,0,1,0,2,48,1,5,1,5 +62887,7,2,2,62,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,4,NA,1,2,2,1,2,2,1,2,2,1,11696.973403,11982.125462,2,101,1,1,0.2,2,2,0,0,1,2,55,1,4,4,NA +62888,7,2,1,6,NA,4,4,1,6,75,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10410.106675,10390.534388,2,96,4,4,0.57,5,5,0,3,0,2,26,1,2,5,NA +62889,7,2,1,2,NA,2,2,2,2,30,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8914.157023,9196.329398,1,99,8,8,1.91,5,5,2,0,1,2,38,2,4,1,4 +62890,7,2,2,16,NA,5,6,1,16,193,NA,NA,2,1,5,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,8210.014908,8564.874659,2,92,15,15,5,4,4,0,2,1,2,59,1,5,1,5 +62891,7,2,2,74,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,NA,13141.36586,14124.295248,1,96,12,12,NA,1,1,0,0,1,2,74,1,2,3,NA +62892,7,2,1,50,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,18225.504252,18491.00599,2,95,4,4,0.79,3,3,1,0,0,1,50,1,4,6,NA +62893,7,2,2,21,NA,1,1,1,NA,NA,2,NA,2,2,2,NA,2,4,2,2,2,2,2,2,2,NA,NA,NA,NA,44119.608456,46238.164206,2,98,6,6,1.21,4,4,1,0,0,2,49,2,2,6,NA +62894,7,2,2,9,NA,4,4,2,9,112,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7620.214819,8204.982373,2,99,7,7,1.19,6,6,1,3,0,2,38,1,3,5,NA +62895,7,2,1,33,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,78240.016337,81914.532146,1,93,15,15,5,3,3,1,0,0,1,33,1,5,1,3 +62896,7,2,2,5,NA,3,3,1,5,69,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,53166.229434,56500.79967,1,98,10,10,2.2,6,6,1,3,0,2,31,1,4,6,NA +62897,7,2,1,5,NA,2,2,2,5,63,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,17458.543556,17482.134163,2,91,10,10,3.04,4,4,1,1,0,2,31,2,5,1,5 +62898,7,2,2,24,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,2,1,2,2,1,2,2,1,2,2,1,22473.275629,22284.590536,2,97,7,7,2.38,2,2,0,0,0,1,25,1,2,1,2 +62899,7,2,2,45,NA,2,2,2,NA,NA,2,NA,2,2,77,NA,3,6,NA,2,2,2,2,2,2,NA,NA,NA,NA,23377.708086,24402.18571,3,90,77,77,NA,4,1,0,0,0,1,45,2,3,3,NA +62900,7,2,2,68,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,1,8308.628726,8949.073879,2,95,6,6,2.69,1,1,0,0,1,2,68,1,3,2,NA +62901,7,2,2,64,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,11704.708696,12115.082932,1,101,15,15,5,3,3,0,0,1,1,58,2,4,1,5 +62902,7,2,2,48,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,35126.205635,36772.568368,1,95,5,5,1.08,3,3,0,1,0,1,53,1,4,1,4 +62903,7,2,1,7,NA,5,6,2,7,86,NA,NA,1,1,NA,0,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,9720.482616,10818.978947,2,91,12,12,NA,7,6,0,4,2,2,72,2,1,2,NA +62904,7,2,1,2,NA,4,4,1,2,26,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6376.965739,6390.839385,2,100,8,8,1.1,7,7,3,3,0,2,58,1,3,5,NA +62905,7,2,2,1,20,5,6,2,NA,20,NA,NA,2,2,1,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4735.146545,4730.145135,3,90,77,77,NA,3,3,1,0,0,1,35,2,3,1,5 +62906,7,2,2,0,0,1,1,1,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6885.817041,7118.841014,2,96,2,2,0.27,5,5,1,2,0,2,26,1,2,1,2 +62907,7,2,2,16,NA,2,2,2,16,200,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,14437.97544,15197.369043,2,90,5,5,0.8,5,5,0,3,0,2,40,2,1,5,NA +62908,7,2,1,21,NA,2,2,2,NA,NA,2,NA,2,2,3,NA,1,5,NA,2,2,2,1,2,2,2,2,2,2,30581.409928,30998.258142,3,90,7,7,1.48,5,5,0,1,0,1,43,2,1,6,NA +62909,7,2,2,31,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,NA,NA,NA,NA,24598.096547,23934.388227,2,99,13,13,NA,6,6,2,1,0,2,31,1,4,6,NA +62910,7,2,2,7,NA,4,4,1,7,93,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12120.418061,13050.526646,2,101,10,10,2.91,4,4,0,1,0,2,51,1,2,5,NA +62911,7,2,1,16,NA,1,1,1,16,198,NA,NA,1,1,NA,10,NA,NA,NA,1,1,1,1,2,1,1,2,2,1,24902.864049,25283.513039,1,94,8,8,1.85,5,5,0,2,0,1,44,2,1,6,NA +62912,7,2,1,59,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,100742.761147,101756.213818,2,100,8,8,4.59,1,1,0,0,0,1,59,1,3,3,NA +62913,7,2,2,40,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,3,2,1,2,2,1,2,2,NA,NA,NA,NA,19463.737283,25688.523518,3,91,4,4,1.09,2,2,0,1,0,2,40,1,5,3,NA +62914,7,2,2,4,NA,3,3,2,4,53,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,27528.66901,27890.404993,1,95,1,1,0.31,2,2,1,0,0,2,23,1,3,3,NA +62915,7,1,1,35,NA,1,1,NA,NA,NA,2,NA,2,2,3,NA,4,1,NA,2,2,2,2,2,2,NA,NA,NA,NA,39073.76885,0,2,99,99,3,0.66,4,2,0,0,0,1,35,2,4,1,2 +62916,7,2,1,22,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,37911.437415,38922.114085,2,103,4,4,0.79,3,3,0,0,0,2,42,2,2,5,NA +62917,7,2,1,13,NA,3,3,2,13,159,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,69216.263169,70543.167563,1,91,14,14,3.15,5,5,0,1,0,2,50,1,5,1,5 +62918,7,2,1,25,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,4,4,NA,1,2,2,1,2,2,1,2,2,1,18259.989639,18151.137608,2,95,6,6,1.08,4,4,1,0,0,2,42,1,4,4,NA +62919,7,2,2,34,NA,3,3,2,NA,NA,2,NA,2,2,99,NA,1,1,2,1,2,1,1,2,1,NA,NA,NA,NA,20717.382973,22040.621269,2,97,1,1,0.21,4,4,2,0,0,2,34,2,1,1,2 +62920,7,2,1,3,NA,2,2,2,3,38,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12920.2211,12937.679363,2,90,14,14,3.58,4,4,1,1,0,1,37,1,3,1,4 +62921,7,2,2,10,NA,4,4,2,10,127,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8147.287486,8590.325322,2,90,8,8,1.67,6,6,2,2,0,2,35,2,5,3,NA +62922,7,2,2,31,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,89807.047643,92234.66957,3,91,6,6,2.57,1,1,0,0,0,2,31,1,4,5,NA +62923,7,2,1,21,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,20333.447198,19976.945976,1,98,12,4,1.34,4,1,0,0,0,1,21,1,4,6,NA +62924,7,2,2,79,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,16361.152596,17584.911061,1,100,3,3,0.91,1,1,0,0,1,2,79,1,1,2,NA +62925,7,2,2,18,NA,3,3,2,18,226,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,22699.241957,23364.572192,2,95,2,2,0.46,3,3,0,0,0,2,48,1,2,1,2 +62926,7,2,2,1,21,1,1,1,NA,21,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,11414.885224,11901.246118,1,94,6,6,1.11,5,5,1,2,0,2,41,2,1,1,1 +62927,7,2,1,63,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,138075.879417,141933.339512,2,91,15,15,5,3,3,0,0,2,2,62,1,4,1,4 +62928,7,2,2,43,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,2,1,2,2,1,2,2,1,2,2,1,15206.604563,14790.435937,2,90,6,6,0.84,6,6,1,3,1,2,43,1,2,5,NA +62929,7,2,1,68,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,9221.19173,9293.322792,2,95,77,77,NA,2,2,0,0,2,1,68,1,4,1,4 +62930,7,2,1,23,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,4,5,NA,2,2,2,1,2,2,1,2,2,1,42077.383821,44160.926598,1,102,4,4,0.67,4,4,0,1,0,1,23,2,4,5,NA +62931,7,2,1,15,NA,5,6,1,15,187,NA,NA,1,1,NA,10,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11171.449402,11936.033174,1,92,14,14,3.47,4,4,0,2,0,2,53,2,4,1,4 +62932,7,1,2,2,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,35285.563011,0,2,100,15,15,5,4,4,1,1,0,1,29,1,4,1,4 +62933,7,2,2,17,NA,5,6,2,17,207,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11975.458482,12291.118947,1,97,9,9,1.78,6,6,0,1,1,1,45,2,3,1,3 +62934,7,2,2,60,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,1,39030.893313,44151.142675,1,91,7,7,2.2,3,3,0,0,1,2,60,1,2,2,NA +62935,7,2,1,51,NA,2,2,1,NA,NA,2,NA,2,1,6,NA,4,1,NA,1,2,2,1,2,2,2,2,2,2,21139.303536,21566.542108,2,103,12,12,NA,4,4,0,1,0,2,50,2,3,1,4 +62936,7,2,2,35,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,NA,NA,NA,NA,31335.13799,32985.054579,1,95,5,5,1.03,4,4,0,2,0,1,33,1,3,1,3 +62937,7,2,2,63,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,10346.035773,10598.2543,1,99,5,5,1.63,2,2,0,0,2,1,64,NA,NA,1,4 +62938,7,2,2,32,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,NA,NA,NA,NA,36053.766709,37679.125242,1,100,6,6,1.13,4,4,0,3,0,2,32,1,3,5,NA +62939,7,2,1,38,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,41155.167164,49173.131788,1,102,7,7,1.41,5,5,0,2,2,1,72,1,4,1,3 +62940,7,2,1,62,NA,4,4,2,NA,NA,2,NA,2,2,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,9814.165625,10072.791483,1,90,15,15,4.34,4,4,0,0,1,1,62,2,5,1,3 +62941,7,2,2,55,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,4,NA,1,2,2,1,2,2,1,2,2,1,13728.308948,13352.59776,2,90,99,4,1.16,5,2,0,0,1,1,43,NA,NA,1,NA +62942,7,1,1,48,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,91761.294148,0,2,92,15,15,5,3,3,1,0,0,1,48,1,5,1,5 +62943,7,2,1,15,NA,2,2,1,15,189,NA,NA,1,1,NA,10,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18042.255087,18115.696579,1,102,14,14,2.83,6,6,1,2,0,1,36,1,2,1,3 +62944,7,2,2,17,NA,4,4,2,17,211,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13775.846051,13737.029624,2,97,7,7,1.06,7,7,1,2,0,2,40,1,4,5,NA +62945,7,2,2,48,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,19100.40225,19426.955733,1,96,15,15,4.9,4,4,0,1,0,1,47,1,3,1,5 +62946,7,2,1,9,NA,4,4,2,9,111,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9699.683862,9681.447258,2,101,2,2,0.27,6,6,0,3,0,2,45,1,2,5,NA +62947,7,1,2,68,NA,2,2,NA,NA,NA,2,NA,1,1,NA,NA,1,2,NA,2,2,2,1,2,2,NA,NA,NA,NA,11469.456138,0,1,90,4,4,0.79,3,3,0,0,1,2,68,1,1,2,NA +62948,7,2,1,79,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,55509.98679,58756.097166,1,101,15,15,5,3,3,0,0,2,1,79,1,4,1,4 +62949,7,2,2,8,NA,4,4,1,8,97,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9139.784234,9384.299154,2,100,14,14,3.89,4,4,0,2,0,1,38,1,3,1,4 +62950,7,2,2,16,NA,3,3,2,16,201,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,91539.042546,96988.607103,1,101,14,14,3.3,4,4,0,2,0,2,42,1,4,1,3 +62951,7,2,2,23,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,15190.604914,17388.543575,1,96,15,15,5,6,6,1,1,1,2,44,1,3,1,3 +62952,7,2,1,20,NA,5,6,2,NA,NA,2,NA,2,1,3,NA,4,4,NA,1,2,2,1,2,2,1,2,2,1,10547.036825,10866.006067,3,90,15,15,3.7,5,5,0,0,0,1,56,2,3,1,3 +62953,7,2,1,44,NA,5,6,2,NA,NA,2,NA,2,2,2,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,17249.311662,18125.470447,2,91,14,14,3.47,4,4,1,1,0,2,36,2,3,1,5 +62954,7,2,1,28,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,18523.956321,18091.254104,2,99,2,2,0.72,1,1,0,0,0,1,28,1,5,5,NA +62955,7,2,2,31,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,3,1,2,2,1,2,2,1,2,2,1,76827.086279,81170.917712,2,99,15,15,5,2,1,0,0,0,2,31,1,5,1,NA +62956,7,2,2,0,7,5,6,2,NA,8,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,NA,NA,NA,NA,NA,NA,NA,4444.744532,4630.927855,2,90,3,3,0.65,5,3,1,2,0,1,44,2,5,1,5 +62957,7,2,2,3,NA,5,6,1,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5307.591514,5454.53335,2,102,3,3,0.38,5,5,3,0,0,2,30,2,2,1,4 +62958,7,2,2,72,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,65611.003966,67854.891478,1,94,15,15,4.95,4,4,0,0,2,1,72,1,3,1,3 +62959,7,2,2,13,NA,5,6,1,13,166,NA,NA,2,1,4,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8210.014908,8564.874659,2,92,15,15,5,4,4,0,2,1,2,59,1,5,1,5 +62960,7,2,2,3,NA,4,4,2,3,47,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9727.363166,10466.751274,2,97,6,6,1,6,6,1,2,2,2,60,1,2,2,NA +62961,7,2,1,0,6,4,4,1,NA,7,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7882.953266,8719.306286,2,96,5,5,1.5,2,2,1,0,0,2,22,1,3,5,NA +62962,7,2,1,2,NA,4,4,1,2,30,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8009.966208,8254.622305,2,96,2,2,0.44,3,3,2,0,0,2,22,1,2,5,NA +62963,7,2,2,6,NA,5,7,2,6,81,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,22371.648216,23759.450609,1,95,6,6,1.15,5,5,2,1,0,1,29,1,4,6,NA +62964,7,1,1,22,NA,5,6,NA,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,NA,NA,NA,NA,NA,NA,NA,13171.824182,0,1,100,NA,NA,NA,4,4,0,0,1,1,21,NA,NA,5,NA +62965,7,2,2,3,NA,5,7,1,3,38,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,29364.157365,32408.949946,1,102,2,2,0.49,3,3,1,0,0,1,20,1,2,6,NA +62966,7,2,2,21,NA,4,4,2,NA,NA,2,NA,2,2,2,NA,2,1,2,1,2,2,1,2,2,1,2,2,1,24185.894115,24390.02655,1,93,3,3,0.7,3,3,1,0,0,1,23,2,4,1,2 +62967,7,2,1,36,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,27572.205373,28895.579143,1,100,15,15,5,3,3,0,0,0,2,33,1,5,1,4 +62968,7,2,1,5,NA,2,2,1,5,62,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,13610.050526,14582.186889,2,100,3,3,0.76,3,3,1,0,0,2,31,2,1,6,NA +62969,7,2,1,14,NA,4,4,2,14,178,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,16890.963304,17218.04077,1,91,10,10,2.56,5,5,0,3,0,1,51,2,5,1,4 +62970,7,1,1,6,NA,2,2,NA,NA,NA,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12577.115885,0,2,96,3,3,0.54,4,4,1,1,0,1,29,1,2,1,2 +62971,7,2,1,53,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,175544.769665,178639.415011,1,91,15,15,5,2,2,0,0,0,1,53,1,5,1,5 +62972,7,2,1,3,NA,2,2,2,3,41,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,17458.543556,18705.569422,2,91,4,4,0.84,3,3,1,0,0,2,21,1,4,1,2 +62973,7,2,1,10,NA,1,1,1,10,124,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17882.621856,18280.794545,3,92,12,12,NA,6,6,1,3,0,2,33,1,5,1,4 +62974,7,2,1,30,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,86986.68246,91060.136414,2,94,9,9,5,1,1,0,0,0,1,30,1,5,5,NA +62975,7,2,2,10,NA,4,4,2,10,126,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7397.129324,7630.740597,1,96,12,12,NA,5,5,1,2,0,2,35,1,5,1,4 +62976,7,2,2,18,NA,3,3,2,18,221,2,NA,2,2,5,14,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,82089.722105,85880.903702,3,91,14,14,5,2,2,0,0,0,2,48,2,5,3,NA +62977,7,2,1,25,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,50326.347525,51411.397032,1,93,12,12,NA,3,1,0,0,0,1,24,NA,NA,5,NA +62978,7,2,2,18,NA,1,1,1,18,217,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,21062.314667,23105.758741,1,91,14,14,3.9,4,4,0,1,0,1,41,1,2,1,4 +62979,7,2,2,68,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,53370.063988,54427.336747,3,92,4,4,1.13,2,2,0,0,2,1,64,1,3,1,4 +62980,7,1,1,39,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,19384.896286,0,1,94,5,5,1.05,3,3,0,1,0,1,39,1,4,6,NA +62981,7,2,1,32,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,25120.174741,25387.314373,2,102,15,15,4.47,4,4,1,1,0,1,32,1,5,1,4 +62982,7,2,2,66,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,1,49644.076348,54110.530387,1,97,3,3,1.16,1,1,0,0,1,2,66,1,3,2,NA +62983,7,2,1,7,NA,4,4,2,7,93,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7730.47951,9212.541007,1,99,6,6,1.3,5,5,1,2,0,1,34,1,2,1,3 +62984,7,2,2,5,NA,2,2,2,5,62,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8825.559072,9505.166523,2,90,7,7,0.89,7,7,1,3,3,1,60,2,3,1,3 +62985,7,2,1,68,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,11138.867102,11750.838884,1,102,7,7,2.72,2,2,0,0,2,2,67,NA,NA,1,5 +62986,7,2,1,14,NA,3,3,1,14,169,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,69211.537407,68936.770872,1,92,8,8,1.45,6,6,1,3,0,1,36,1,3,1,4 +62987,7,2,1,10,NA,2,2,1,10,125,NA,NA,2,1,3,4,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,13395.612951,13401.547169,2,102,7,7,1.53,5,5,1,2,0,2,37,2,4,1,4 +62988,7,2,1,10,NA,2,2,1,10,128,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11036.458246,11087.266596,1,102,14,14,2.83,6,6,1,2,0,1,36,1,2,1,3 +62989,7,2,2,1,19,5,6,2,NA,21,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,8173.816615,8894.95474,1,97,15,15,5,4,4,2,0,0,2,35,2,4,1,4 +62990,7,2,1,79,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,79754.311902,90534.066519,1,97,9,9,3.97,2,2,0,0,2,1,79,1,3,1,3 +62991,7,2,1,24,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,129608.716834,132839.525748,1,100,8,8,2.97,2,2,0,0,0,1,24,1,5,1,5 +62992,7,2,2,9,NA,1,1,2,9,116,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18668.602894,18957.049554,1,101,4,4,0.84,3,3,0,1,0,1,42,1,4,1,4 +62993,7,2,2,34,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,74501.766669,80316.820348,1,90,14,14,3.93,3,3,1,0,0,1,35,1,2,1,5 +62994,7,2,2,49,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,3,1,NA,1,2,1,1,2,2,NA,NA,NA,NA,18255.735511,18352.270791,2,91,15,15,4.63,7,7,1,2,0,1,36,2,4,1,3 +62995,7,2,1,18,NA,4,4,2,18,220,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11386.695644,11908.648036,2,99,6,6,1.18,5,5,0,3,0,2,38,1,2,5,NA +62996,7,2,2,9,NA,2,2,2,9,114,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13257.060167,14867.908577,2,90,8,8,1.72,5,5,1,2,0,1,20,2,1,1,2 +62997,7,2,1,60,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,29552.786683,29829.95179,2,96,3,3,0.95,2,2,0,0,2,2,62,1,4,1,4 +62998,7,2,1,19,NA,5,6,1,20,NA,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,6558.308393,6849.983523,2,92,99,99,NA,4,1,0,0,0,1,19,1,4,NA,NA +62999,7,2,2,9,NA,5,7,1,9,113,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6137.256046,6434.751859,1,103,15,15,3.7,5,5,0,2,1,1,55,1,5,1,5 +63000,7,2,2,60,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,11862.436765,12619.924744,1,90,2,2,0.45,1,1,0,0,1,2,60,1,5,3,NA +63001,7,2,1,5,NA,4,4,1,5,64,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9624.976734,10219.132066,2,96,3,3,0.38,5,5,1,2,0,2,30,1,3,5,NA +63002,7,2,2,54,NA,2,2,1,NA,NA,2,NA,2,1,8,NA,4,1,NA,2,2,2,1,2,2,NA,NA,NA,NA,21901.662873,22693.823819,2,93,8,8,2.49,3,3,0,0,0,1,52,2,2,1,4 +63003,7,2,1,40,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,151649.038926,151259.483772,1,101,13,13,NA,2,2,0,0,0,1,40,1,2,1,3 +63004,7,2,2,38,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,1,3,1,2,1,1,2,2,1,2,2,NA,13047.751375,13287.186355,2,92,15,15,5,3,3,1,0,0,1,39,2,5,1,5 +63005,7,2,1,19,NA,1,1,1,19,232,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,2,2,2,1,2,2,1,32326.52031,34735.818434,2,94,5,5,0.65,6,6,0,3,0,1,44,2,1,1,1 +63006,7,2,1,53,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,123771.419917,127443.198085,2,98,10,10,3.78,3,3,0,0,0,1,53,1,3,1,4 +63007,7,2,1,80,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,47098.572584,49762.054694,1,95,7,7,2.38,2,2,0,0,2,1,80,1,3,1,4 +63008,7,2,1,38,NA,4,4,2,NA,NA,2,NA,2,2,4,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,15051.024912,15121.525249,3,90,15,15,5,5,5,1,0,1,1,38,2,3,1,4 +63009,7,2,1,6,NA,4,4,2,7,84,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8483.005475,8584.70346,1,96,10,10,2.95,4,4,0,1,0,2,34,2,3,1,5 +63010,7,2,2,78,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,12535.973802,12972.182488,2,100,7,7,2.37,3,3,0,1,1,2,45,1,5,1,NA +63011,7,2,2,16,NA,3,3,2,16,194,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,122091.956024,127137.394167,2,91,15,15,5,3,3,0,1,0,1,52,1,5,1,5 +63012,7,2,1,65,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,121588.761604,120347.630506,1,91,10,10,4.76,2,2,0,0,2,2,64,1,4,1,5 +63013,7,2,1,65,NA,5,6,1,NA,NA,1,1,2,1,8,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,11138.867102,11750.838884,1,102,14,14,5,2,2,0,0,2,1,65,2,5,1,5 +63014,7,2,2,11,NA,4,4,2,11,133,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7814.742747,7978.458393,1,98,8,8,2.97,2,2,0,1,0,2,40,1,4,3,NA +63015,7,2,1,65,NA,5,7,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,117343.481374,118848.614941,1,91,7,7,2.64,2,2,0,0,1,2,58,1,5,1,4 +63016,7,2,2,14,NA,2,2,2,14,170,NA,NA,2,2,3,7,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,12680.621719,14355.413798,2,90,3,3,0.46,5,5,0,2,2,1,75,2,1,1,2 +63017,7,2,1,71,NA,5,6,2,NA,NA,2,NA,2,2,2,NA,1,1,NA,1,2,1,1,2,2,NA,NA,NA,NA,12511.526803,13352.932153,2,100,4,4,0.44,7,7,1,2,2,1,71,2,1,1,1 +63018,7,2,1,10,NA,3,3,1,10,124,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,27154.222487,28089.451048,2,101,4,4,0.73,5,5,1,2,0,1,40,1,5,1,5 +63019,7,2,2,65,NA,2,2,1,NA,NA,2,NA,2,1,9,NA,4,3,NA,2,2,2,2,2,2,1,2,2,2,10235.0654,10662.230581,2,93,3,3,0.87,2,2,0,0,1,2,65,2,4,3,NA +63020,7,2,1,6,NA,1,1,1,6,73,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,13533.281742,15943.839793,1,100,6,6,1.11,5,5,0,2,1,1,38,2,2,1,1 +63021,7,2,2,46,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,3,5,NA,1,2,1,1,2,1,NA,NA,NA,NA,19524.115198,21455.7569,1,93,7,7,2.38,2,2,0,0,0,2,46,2,3,5,NA +63022,7,2,1,49,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,1,92467.370896,92229.84126,1,92,14,14,3.16,6,6,1,1,0,1,49,1,1,1,3 +63023,7,2,1,25,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,124820.027137,126759.886775,1,91,6,3,0.92,2,1,0,0,0,2,24,1,4,6,NA +63024,7,2,2,78,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,NA,12692.401451,13134.05328,2,95,12,12,NA,3,3,0,0,2,1,65,1,4,1,4 +63025,7,2,2,79,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,14226.966896,14722.016314,2,100,5,5,0.95,4,4,0,0,1,2,53,1,3,5,NA +63026,7,2,2,31,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,53830.599426,56471.452044,1,99,15,15,5,3,3,1,0,0,2,31,1,5,1,5 +63027,7,2,1,15,NA,1,1,1,15,181,NA,NA,1,1,NA,8,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,18242.832494,18521.680571,1,102,6,6,1.03,6,6,0,4,0,1,34,2,2,1,1 +63028,7,2,2,6,NA,1,1,1,6,73,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,14414.529053,14932.182215,2,96,8,8,1.33,7,7,2,1,1,1,62,2,1,1,1 +63029,7,2,2,2,NA,5,7,2,2,28,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,20272.436775,20911.100412,2,94,77,77,NA,4,4,2,0,0,2,23,1,2,6,NA +63030,7,2,1,21,NA,1,1,1,NA,NA,2,NA,2,2,5,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,42165.369652,45330.590147,2,102,3,3,0.45,4,4,2,0,0,1,21,2,2,6,NA +63031,7,2,2,77,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,15183.616455,20169.750633,1,90,6,6,1.78,2,2,0,0,1,2,77,1,1,2,NA +63032,7,2,1,14,NA,4,4,2,14,172,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11085.075029,11001.247749,1,93,1,1,0.02,5,5,0,4,0,2,36,NA,NA,5,NA +63033,7,2,1,45,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,153755.392794,158780.137655,1,91,15,15,5,4,4,0,1,0,1,45,1,5,1,5 +63034,7,2,2,5,NA,3,3,2,5,60,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,27257.164734,28966.726071,1,92,4,4,0.61,5,5,1,2,0,1,34,1,3,6,NA +63035,7,2,1,7,NA,5,7,2,7,94,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8017.552697,8398.795399,1,99,6,6,0.6,7,7,2,1,1,2,69,1,3,2,NA +63036,7,2,2,74,NA,5,6,2,NA,NA,2,NA,2,2,7,NA,1,3,NA,1,2,2,1,2,2,1,2,2,NA,12895.665603,13811.504793,1,93,2,2,0.55,1,1,0,0,1,2,74,2,1,3,NA +63037,7,2,2,41,NA,2,2,2,NA,NA,2,NA,2,2,6,NA,1,4,2,2,2,2,1,2,2,2,2,2,2,34501.569761,34681.492512,1,93,5,5,1.36,2,2,0,0,0,2,41,2,1,4,NA +63038,7,2,2,2,NA,5,7,2,2,33,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7871.443574,8074.618887,1,96,6,6,1.49,3,3,1,0,0,2,24,1,4,5,NA +63039,7,2,2,2,NA,1,1,2,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9955.153132,10582.75863,3,92,6,6,1,6,6,1,1,0,1,42,2,1,1,4 +63040,7,2,2,54,NA,5,6,1,NA,NA,2,NA,2,2,6,NA,2,1,NA,1,2,1,NA,NA,NA,1,2,1,3,15268.129241,15348.866231,2,96,NA,NA,NA,4,4,0,0,1,1,67,2,3,1,2 +63041,7,2,1,35,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,14376.416432,15539.834252,2,103,15,15,5,4,4,0,3,0,1,35,1,5,5,NA +63042,7,2,2,12,NA,4,4,2,12,146,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13841.239638,13875.328502,1,96,15,15,4.52,6,6,0,4,0,1,46,1,4,1,4 +63043,7,2,2,20,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,4,5,2,1,2,2,1,2,2,NA,NA,NA,NA,11609.8069,12151.984044,2,103,77,77,NA,5,5,0,2,0,2,39,2,5,1,5 +63044,7,2,1,35,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,79316.940936,94360.361124,1,93,10,10,5,1,1,0,0,0,1,35,1,5,5,NA +63045,7,2,2,53,NA,1,1,1,NA,NA,2,NA,2,2,8,NA,2,4,NA,1,2,2,2,2,2,1,2,2,1,18295.488967,18390.898385,2,103,8,8,1.29,7,7,3,1,0,2,53,2,2,4,NA +63046,7,2,1,1,NA,3,3,2,NA,25,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,39241.111643,42207.80453,1,99,6,6,1.73,3,3,1,1,0,2,42,1,5,3,NA +63047,7,2,2,6,NA,3,3,2,6,81,NA,NA,2,1,2,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14287.66096,14320.169639,2,97,6,6,1.16,4,4,1,1,0,1,27,2,4,1,3 +63048,7,2,1,29,NA,5,6,2,NA,NA,2,NA,2,2,2,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,15875.103787,17176.519619,1,93,10,10,4.76,2,2,0,0,0,1,29,2,5,1,5 +63049,7,2,1,19,NA,2,2,1,19,233,2,NA,2,1,5,15,NA,NA,NA,1,2,2,2,2,2,1,2,2,1,30061.88611,30025.949584,1,92,6,6,0.93,5,5,0,2,0,1,47,2,1,1,1 +63050,7,2,1,24,NA,4,4,2,NA,NA,2,NA,2,2,2,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,12364.328404,12075.509308,1,96,10,10,1.8,7,7,1,1,0,1,57,2,1,1,3 +63051,7,2,1,30,NA,5,6,1,NA,NA,2,NA,2,2,3,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,22403.911395,23911.071969,2,96,14,14,5,2,2,0,0,0,1,30,2,5,1,5 +63052,7,2,2,37,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,5,3,2,1,2,2,1,2,2,NA,NA,NA,NA,19741.154437,19781.46423,1,100,7,7,2.51,2,2,0,1,0,2,37,2,5,3,NA +63053,7,2,2,8,NA,1,1,1,8,101,NA,NA,1,1,NA,2,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,12789.411811,13121.359297,1,102,3,3,0.54,3,3,0,2,0,2,42,2,2,3,NA +63054,7,2,2,11,NA,1,1,1,11,136,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14469.11917,14745.425968,2,92,15,15,3.37,7,7,0,4,0,1,42,2,3,1,1 +63055,7,2,2,2,NA,3,3,2,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,25257.21318,27876.153487,1,98,2,2,0.31,3,3,1,0,0,1,45,NA,NA,1,NA +63056,7,2,1,21,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,15196.92397,16091.373745,2,101,7,3,1.1,3,1,0,0,0,1,21,2,4,5,NA +63057,7,2,1,29,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,43892.276067,44574.41704,1,98,6,6,2.6,2,1,0,0,0,1,29,1,4,5,NA +63058,7,2,2,13,NA,5,6,2,13,158,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6135.470395,6372.721366,1,91,15,15,5,6,6,0,2,2,1,50,2,5,1,5 +63059,7,2,1,7,NA,4,4,1,7,87,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10469.725162,11059.049224,1,100,6,6,1.13,4,4,0,3,0,2,32,1,3,5,NA +63060,7,2,2,7,NA,1,1,1,7,93,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13064.573334,13201.924867,1,103,5,5,0.71,6,6,2,2,0,2,31,2,2,1,2 +63061,7,2,2,37,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,6,1,1,2,2,1,2,2,NA,NA,NA,NA,22326.231285,22166.696692,1,99,7,7,1.06,7,7,3,1,0,1,38,1,4,6,NA +63062,7,2,1,4,NA,4,4,1,4,59,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10690.995725,11500.031681,2,98,5,5,0.59,7,7,3,0,0,2,50,1,5,4,NA +63063,7,2,2,7,NA,3,3,1,7,87,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,60557.637514,61692.695301,3,92,6,6,1.17,4,4,0,2,0,2,30,1,2,1,4 +63064,7,2,1,61,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,1,4,NA,1,2,2,1,2,2,1,2,2,1,6910.118936,7233.371983,2,95,3,3,1.07,1,1,0,0,1,1,61,1,1,4,NA +63065,7,2,1,11,NA,1,1,1,11,143,NA,NA,2,2,3,4,NA,NA,NA,2,1,2,2,2,2,1,2,2,NA,13822.148996,14860.201344,3,92,4,4,0.55,6,6,0,4,0,1,36,2,1,1,3 +63066,7,2,1,3,NA,3,3,2,3,44,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,61250.535365,69105.159981,1,90,8,8,1.67,5,5,2,1,0,2,28,1,4,1,5 +63067,7,2,2,0,5,5,6,1,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6956.259272,7247.645977,1,95,5,5,0.73,6,6,1,0,1,1,62,2,3,1,NA +63068,7,2,1,9,NA,3,3,1,9,119,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,26240.82746,27691.552263,1,94,4,4,0.56,5,5,1,2,0,1,34,1,2,3,NA +63069,7,2,1,20,NA,5,6,2,NA,NA,2,NA,2,2,1,NA,4,5,NA,1,2,2,1,2,2,1,2,2,3,14385.653726,15533.829525,2,101,6,2,0.46,2,1,0,0,0,1,20,2,4,5,NA +63070,7,2,2,70,NA,2,2,1,NA,NA,2,NA,2,1,7,NA,1,5,NA,2,2,2,1,2,2,2,2,2,NA,21122.17432,23417.039872,2,93,6,6,0.64,7,7,2,1,3,2,60,2,3,2,NA +63071,7,2,2,53,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,1,20450.752436,20266.431761,1,98,6,6,1.72,2,2,0,0,0,2,53,1,5,2,NA +63072,7,2,2,12,NA,3,3,2,12,152,NA,NA,2,1,1,7,NA,NA,NA,1,1,1,1,2,1,1,2,2,1,31756.649984,32677.072621,2,97,5,5,0.8,5,5,1,2,0,1,46,2,4,1,2 +63073,7,2,1,16,NA,3,3,1,16,194,NA,NA,1,1,NA,8,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,25367.590269,25034.201904,1,94,6,6,1.26,5,5,0,2,0,2,38,1,4,1,NA +63074,7,2,1,3,NA,4,4,1,3,38,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9016.053035,9698.338509,2,97,NA,99,NA,7,6,2,1,1,2,56,1,3,5,NA +63075,7,2,2,12,NA,2,2,1,12,152,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,20502.928313,21114.699878,2,98,12,12,NA,3,3,0,1,0,2,34,1,4,1,3 +63076,7,2,1,53,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,21168.33083,23066.473787,2,99,2,2,0.4,2,2,0,0,0,2,52,1,3,1,3 +63077,7,2,1,38,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,86986.68246,92645.868047,2,94,15,15,4.59,4,4,1,1,0,2,37,1,5,1,5 +63078,7,2,1,6,NA,1,1,1,6,81,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8828.580268,8822.70874,2,103,10,10,1.63,7,7,1,4,0,1,31,NA,NA,1,4 +63079,7,2,1,17,NA,5,6,1,17,212,2,NA,2,1,5,12,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11171.449402,11936.033174,1,92,14,14,3.47,4,4,0,2,0,2,53,2,4,1,4 +63080,7,2,2,34,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,1,1,2,2,1,2,2,NA,NA,NA,NA,30505.56355,30746.687156,1,97,3,3,0.93,2,2,0,1,0,2,34,1,4,5,NA +63081,7,2,1,62,NA,5,7,2,NA,NA,2,NA,2,1,7,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,19328.482066,19868.466665,3,90,7,7,2.51,2,2,0,0,2,1,62,2,3,1,4 +63082,7,2,2,59,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,175997.804296,180603.118894,1,101,4,2,0.82,2,1,0,0,1,1,63,1,2,6,NA +63083,7,2,2,71,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,69601.920609,70345.22994,1,98,7,7,3.58,1,1,0,0,1,2,71,1,4,2,NA +63084,7,2,1,4,NA,3,3,2,4,54,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,45649.909879,51503.94697,1,99,15,15,5,5,5,3,0,0,2,34,1,5,1,5 +63085,7,2,2,4,NA,4,4,2,4,54,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8267.490849,9012.744386,2,99,2,2,0.19,7,7,3,1,0,2,43,1,2,4,NA +63086,7,2,2,74,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,62212.598767,64340.261278,1,94,15,15,5,2,2,0,0,2,1,75,1,4,1,3 +63087,7,2,1,3,NA,3,3,1,3,45,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,81508.607355,87670.792766,1,94,14,6,1.65,3,2,1,0,0,1,26,1,4,6,NA +63088,7,2,1,44,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,11113.602843,11073.454175,3,90,10,10,2.41,5,5,1,2,0,1,44,2,4,1,5 +63089,7,2,2,43,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,80232.348161,83992.832552,1,99,15,15,4.47,4,4,0,2,0,2,43,1,5,1,5 +63090,7,2,2,15,NA,3,3,2,15,186,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,41202.729804,43105.611516,2,91,6,6,1.26,5,5,0,1,2,2,80,1,4,2,NA +63091,7,2,1,70,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,NA,55996.810038,59271.38884,2,93,15,8,4.48,2,1,0,0,2,2,63,2,4,6,NA +63092,7,2,2,17,NA,4,4,2,18,216,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12581.940435,12644.353117,2,97,6,6,0.92,7,7,1,4,0,2,29,1,3,5,NA +63093,7,2,2,10,NA,3,3,1,10,130,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,1,2,1,2,2,1,21800.021754,23152.363882,3,91,7,1,0,7,1,0,4,0,1,40,1,4,1,3 +63094,7,2,1,80,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,27167.433399,29371.776665,1,94,7,7,2.58,2,2,0,0,2,2,71,1,5,1,4 +63095,7,2,2,4,NA,4,4,1,4,54,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10437.988787,11664.396755,2,100,9,9,2.46,4,4,1,1,1,2,59,1,3,1,3 +63096,7,2,1,8,NA,2,2,1,8,101,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13672.897697,14159.650726,2,100,14,14,3.58,4,4,0,2,0,2,40,NA,NA,1,4 +63097,7,2,1,70,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,71070.181743,74923.26272,1,95,7,7,2.45,2,2,0,0,2,2,70,1,3,1,3 +63098,7,2,2,10,NA,3,3,2,10,127,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,60197.256541,63931.531988,2,94,14,14,2.63,6,6,1,3,0,1,39,1,4,1,4 +63099,7,2,2,3,NA,2,2,1,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,15550.931019,16748.422137,2,102,8,8,1.09,7,7,1,3,0,2,33,2,1,6,NA +63100,7,2,2,13,NA,1,1,1,13,167,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,22424.988432,22856.096824,1,94,5,5,0.87,4,4,0,2,0,2,41,2,4,1,1 +63101,7,2,1,6,NA,4,4,1,7,85,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11060.738342,11193.339318,2,96,6,6,1.48,4,4,1,1,0,2,25,1,4,5,NA +63102,7,2,2,19,NA,1,1,1,19,238,2,NA,2,2,1,12,NA,NA,NA,2,2,2,2,2,2,2,2,2,2,16427.640886,17012.806816,1,102,5,5,0.98,4,4,1,1,0,2,42,2,2,6,NA +63103,7,2,1,46,NA,5,6,2,NA,NA,2,NA,2,2,6,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,12820.674452,13169.378628,3,90,15,15,5,3,3,0,0,0,1,46,2,3,1,3 +63104,7,2,2,6,NA,4,4,1,6,76,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8146.767632,8699.382682,2,100,15,15,4.97,5,5,0,2,1,2,42,1,5,1,5 +63105,7,1,1,14,NA,5,6,NA,NA,NA,NA,NA,2,1,4,9,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8915.81491,0,1,95,3,3,0.43,4,4,0,1,2,1,65,2,5,1,3 +63106,7,2,1,50,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,32720.69734,32838.149884,1,95,3,3,0.95,1,1,0,0,0,1,50,1,2,3,NA +63107,7,2,2,66,NA,2,2,2,NA,NA,2,NA,2,1,7,NA,1,1,NA,2,2,2,2,2,2,2,2,2,2,9716.805546,12994.252166,2,90,3,3,1.1,1,1,0,0,1,2,66,2,1,1,NA +63108,7,2,1,21,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,26847.643051,28699.104328,1,98,4,4,0.66,4,4,2,0,0,2,22,1,4,6,NA +63109,7,2,2,41,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,2,1,2,2,1,2,2,1,2,2,1,105873.555835,111215.69511,1,101,14,14,3.9,4,4,0,2,0,2,41,1,2,1,2 +63110,7,2,1,36,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,22439.245437,22882.446062,2,96,14,14,3.58,4,4,2,0,0,1,36,1,4,1,5 +63111,7,2,1,8,NA,1,1,1,8,103,NA,NA,2,7,77,1,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,11399.23838,11295.714433,1,103,8,8,1.85,5,5,2,1,0,2,25,2,2,1,2 +63112,7,2,2,66,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,1,1,NA,1,2,2,1,2,2,1,2,2,1,17221.648537,17753.661813,1,95,6,6,1.7,2,2,0,0,2,2,66,2,1,1,3 +63113,7,2,2,3,NA,1,1,2,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,17543.203297,19368.16722,1,95,8,8,2.24,4,4,2,0,0,2,29,1,3,1,4 +63114,7,2,1,15,NA,5,6,1,15,189,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11657.164593,12175.606972,1,92,9,9,2.88,3,3,0,2,0,1,50,2,5,3,NA +63115,7,2,1,4,NA,3,3,1,4,59,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,32621.433667,36804.729607,2,101,4,4,0.73,5,5,1,2,0,1,40,1,5,1,5 +63116,7,2,2,34,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,24291.664633,24483.672027,1,99,8,8,4.13,1,1,0,0,0,2,34,1,5,5,NA +63117,7,2,1,24,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,4,6,NA,1,2,2,1,2,2,1,2,2,3,14385.653726,15533.829525,2,101,8,5,2.2,2,1,0,0,0,1,24,2,4,6,NA +63118,7,2,1,16,NA,1,1,1,16,198,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,30061.88611,30025.949584,1,92,7,7,1.48,5,5,0,1,0,1,42,1,5,1,4 +63119,7,2,1,37,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,84933.772167,92023.102027,2,99,15,15,5,2,2,0,0,0,2,37,1,5,1,5 +63120,7,2,2,4,NA,3,3,1,4,58,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,55336.504558,58807.19381,2,102,14,14,3.44,5,5,1,2,0,2,34,1,4,6,NA +63121,7,2,1,9,NA,1,1,1,9,114,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15233.096858,16234.004804,1,94,15,15,4.37,7,7,0,4,1,1,58,1,4,1,5 +63122,7,2,2,3,NA,2,2,1,3,44,NA,NA,2,2,2,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,10301.516763,10950.95816,2,93,6,6,0.93,5,5,1,2,0,1,40,2,4,1,4 +63123,7,2,1,55,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,18753.573091,18904.865313,2,99,2,2,0.77,1,1,0,0,0,1,55,1,3,5,NA +63124,7,2,2,54,NA,5,6,1,NA,NA,2,NA,2,2,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,15460.72194,15832.955199,1,102,9,9,2.39,5,5,0,1,1,1,55,2,5,1,5 +63125,7,2,2,46,NA,4,4,2,NA,NA,2,NA,2,1,6,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,22109.546782,21887.540337,1,93,7,7,1.79,4,4,0,2,0,1,53,2,4,1,4 +63126,7,2,1,44,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,111448.08155,119470.923607,1,90,15,15,5,4,4,0,2,0,1,44,1,5,1,5 +63127,7,2,1,28,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,14391.77847,15024.211748,1,92,14,14,3.3,4,4,2,0,0,1,28,1,4,1,4 +63128,7,2,2,34,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,4,3,1,2,2,1,2,2,1,2,2,1,38589.695298,40356.151096,2,96,6,5,1.84,2,1,0,0,0,2,26,1,2,5,NA +63129,7,2,1,14,NA,1,1,1,14,172,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,22768.423624,23297.239555,2,98,6,6,1.4,3,3,0,1,0,1,56,1,2,1,2 +63130,7,2,2,16,NA,5,6,2,16,196,NA,NA,2,2,1,8,NA,NA,NA,1,2,1,NA,NA,NA,1,2,1,NA,10767.566937,12084.516227,2,91,99,1,0,7,3,0,4,0,1,36,2,9,1,2 +63131,7,2,2,2,NA,4,4,1,2,33,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8480.466509,9125.076563,1,100,13,13,NA,5,5,2,0,0,2,54,1,4,5,NA +63132,7,2,2,80,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,4,2,NA,1,2,1,1,2,2,1,2,1,NA,18698.205673,19635.336647,1,97,15,15,4.81,5,5,0,1,1,1,51,2,5,1,5 +63133,7,2,1,24,NA,1,1,2,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,35669.2076,40318.090187,2,94,8,8,2.33,4,4,2,0,0,1,24,1,2,6,NA +63134,7,2,2,66,NA,2,2,1,NA,NA,2,NA,2,1,6,NA,3,2,NA,2,2,2,2,2,2,2,2,2,2,11851.128358,12345.740673,2,93,4,4,0.69,4,4,0,1,1,2,66,2,3,2,NA +63135,7,2,1,15,NA,4,4,2,15,190,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11351.725436,11256.943498,2,95,7,7,1.74,4,4,0,2,0,2,47,1,5,4,NA +63136,7,2,1,18,NA,3,3,2,18,224,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,66448.116716,70579.976727,2,94,7,7,1.17,6,6,0,3,0,1,40,1,3,1,5 +63137,7,2,1,49,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,19898.840409,19922.416835,2,94,15,15,5,2,2,0,0,0,1,49,2,5,1,5 +63138,7,2,1,15,NA,3,3,2,15,188,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,76583.482739,78051.61978,3,91,4,4,0.92,3,3,0,1,0,2,53,1,4,1,4 +63139,7,2,2,25,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,NA,NA,NA,NA,24118.129224,23465.858863,2,96,3,3,0.59,3,3,1,0,0,2,25,1,4,1,NA +63140,7,2,2,9,NA,1,1,1,9,113,NA,NA,1,1,NA,3,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,12307.832776,12437.228482,2,93,77,77,NA,7,7,3,1,0,2,43,2,1,1,9 +63141,7,2,2,34,NA,4,4,2,NA,NA,2,NA,2,2,4,NA,3,1,2,1,2,2,1,2,2,NA,NA,NA,NA,27303.803575,30038.060995,1,96,10,10,2.95,4,4,0,1,0,2,34,2,3,1,5 +63142,7,2,1,54,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,19064.767778,19872.734197,2,93,10,10,3.93,3,3,0,0,2,1,54,1,5,1,5 +63143,7,2,1,70,NA,5,6,2,NA,NA,2,NA,2,2,5,NA,1,1,NA,1,2,1,1,2,1,1,2,1,NA,10498.47031,11456.643725,3,90,4,4,1.22,2,2,0,0,2,2,69,2,4,1,1 +63144,7,2,1,1,21,2,2,2,NA,22,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,10803.555682,11145.535856,2,94,7,7,1.34,5,5,2,1,0,1,32,2,1,1,NA +63145,7,2,1,50,NA,4,4,2,NA,NA,2,NA,2,2,6,NA,4,4,NA,1,2,2,1,2,2,1,2,2,1,15044.515884,15040.577827,3,90,5,5,0.87,4,4,0,0,0,2,43,2,3,5,NA +63146,7,2,2,6,NA,4,4,1,6,75,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8362.256577,9003.967662,2,100,3,3,0.38,5,5,2,1,0,2,28,1,2,5,NA +63147,7,2,1,41,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,31010.243793,32025.638239,3,92,6,6,1.41,4,3,0,1,0,1,41,1,4,1,4 +63148,7,2,1,40,NA,1,1,2,NA,NA,2,NA,2,2,77,NA,3,1,NA,2,2,2,1,2,2,2,2,2,2,31640.296506,31176.023929,2,94,6,4,1.38,2,1,0,0,0,1,40,2,3,1,NA +63149,7,2,2,43,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,145772.192378,153127.526275,1,95,9,9,2.66,4,4,0,2,0,1,45,1,3,1,3 +63150,7,2,1,19,NA,3,3,2,19,229,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,93665.036597,95017.313859,1,91,15,15,5,4,4,0,1,0,1,45,1,5,1,5 +63151,7,2,1,44,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,17212.153036,21760.360036,3,90,7,6,2.42,2,1,0,0,0,1,44,1,2,6,NA +63152,7,2,2,62,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,15277.358397,15812.991914,2,96,5,1,0,2,1,0,0,1,1,46,2,3,3,NA +63153,7,2,1,2,NA,2,2,2,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13002.944731,13931.716845,2,91,2,2,0.42,3,3,1,1,0,2,27,1,3,5,NA +63154,7,2,1,36,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,1,1,NA,2,2,2,1,2,2,2,2,2,2,51543.062078,51154.050295,3,92,6,6,0.86,7,7,1,4,0,2,36,2,1,1,1 +63155,7,2,1,18,NA,3,3,2,19,228,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,68148.957861,67253.324127,1,93,15,15,3.92,5,5,0,1,0,2,54,1,5,1,5 +63156,7,2,2,70,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,49260.413155,50771.674072,2,100,8,8,3.4,2,2,0,0,2,1,69,1,4,1,4 +63157,7,2,1,13,NA,3,3,2,13,156,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,32477.57544,32050.74555,1,95,4,4,0.65,6,6,2,2,0,2,36,1,4,6,NA +63158,7,2,2,0,5,3,3,1,NA,7,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10263.789813,10611.184403,1,94,8,8,1.39,7,7,2,0,1,2,52,1,5,2,NA +63159,7,2,1,48,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,37724.155022,39553.56554,2,102,4,4,1.16,2,2,0,0,0,1,48,1,4,1,4 +63160,7,2,2,61,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,1,130577.02995,132175.980892,1,98,5,5,1.81,1,1,0,0,1,2,61,1,3,2,NA +63161,7,2,2,37,NA,2,2,1,NA,NA,2,NA,2,2,4,NA,4,3,2,2,2,2,1,2,2,2,2,2,2,39450.135734,38385.688196,2,93,9,9,1.94,6,6,0,3,0,2,37,NA,NA,3,NA +63162,7,2,2,58,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,19000.571418,18807.33617,1,96,8,8,4.48,1,1,0,0,0,2,58,1,4,3,NA +63163,7,2,1,48,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,146181.198007,148606.927767,2,91,15,2,0.85,7,1,0,0,1,1,49,NA,NA,5,NA +63164,7,2,1,54,NA,1,1,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,27343.459193,27021.369249,1,90,15,15,5,4,4,0,0,0,1,54,1,5,1,5 +63165,7,1,2,13,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16537.460749,0,2,100,1,1,0.04,4,4,0,2,0,1,34,NA,NA,6,NA +63166,7,2,2,17,NA,4,4,2,17,205,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,10848.628906,11198.221038,1,99,4,4,0.41,7,7,2,4,0,2,43,1,4,4,NA +63167,7,2,1,37,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,12327.761744,13424.968474,3,90,12,12,NA,5,5,1,2,0,1,37,2,5,1,5 +63168,7,2,1,10,NA,5,6,1,10,131,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8580.826574,9087.233306,1,92,14,14,2.42,6,6,1,3,0,1,30,1,4,6,NA +63169,7,2,2,33,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,NA,NA,NA,NA,53955.606082,55487.991675,2,100,6,6,1.7,3,3,0,1,0,2,33,1,4,6,NA +63170,7,2,2,53,NA,1,1,2,NA,NA,2,NA,2,2,4,NA,1,1,NA,2,2,2,2,2,2,NA,NA,NA,NA,22224.73066,22340.630739,2,94,7,7,1.33,6,6,0,1,0,1,55,2,2,1,1 +63171,7,2,1,20,NA,5,6,1,NA,NA,2,NA,2,2,4,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,9162.933592,9412.398479,1,103,5,5,0.65,6,6,0,0,1,2,26,2,4,5,NA +63172,7,2,2,68,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,1,2,NA,2,2,2,1,2,2,2,2,2,2,13057.178942,15139.165763,1,102,6,6,1.18,5,5,0,2,1,2,42,2,2,2,NA +63173,7,2,1,18,NA,5,6,2,18,217,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,5096.872559,5447.231524,3,91,7,7,1.33,6,6,0,0,2,2,51,2,5,1,5 +63174,7,2,2,47,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,29650.79971,34013.933936,2,90,14,14,5,1,1,0,0,0,2,47,1,5,5,NA +63175,7,2,1,15,NA,3,3,1,15,184,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,31348.486193,31739.246143,1,98,5,5,0.74,5,5,0,3,0,1,35,1,2,6,NA +63176,7,2,1,19,NA,4,4,2,19,230,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13416.172328,13513.882801,1,96,4,4,0.65,4,4,0,0,0,1,19,1,4,NA,NA +63177,7,2,1,60,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,4,NA,1,2,2,1,2,2,1,2,2,1,8355.583627,8420.94363,2,93,10,10,3.93,3,3,0,0,2,1,54,1,5,1,5 +63178,7,2,2,40,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,1,2,1,2,2,1,2,2,1,2,2,1,30543.064147,31583.211468,2,101,8,8,2.81,3,3,0,1,0,1,35,1,1,1,2 +63179,7,2,1,8,NA,2,2,1,8,100,NA,NA,1,1,NA,3,NA,NA,NA,2,1,2,2,2,2,2,2,2,2,13898.598114,14013.214919,2,102,8,8,1.09,7,7,1,3,0,2,33,2,1,6,NA +63180,7,2,1,50,NA,5,6,2,NA,NA,2,NA,2,2,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,10857.294346,10859.552755,1,91,15,15,5,6,6,0,2,2,1,50,2,5,1,5 +63181,7,2,2,67,NA,2,2,2,NA,NA,2,NA,2,1,8,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,9716.805546,10308.451947,2,90,8,8,2.01,4,4,0,0,1,2,67,2,4,2,NA +63182,7,2,2,14,NA,4,4,2,14,171,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10671.280357,10591.403308,1,99,15,8,2.7,4,3,0,2,0,1,49,1,4,6,NA +63183,7,2,2,44,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,2,1,2,2,1,2,2,1,2,2,1,20135.631696,26575.299535,1,96,4,4,1.12,2,2,0,1,0,2,44,1,2,5,NA +63184,7,2,1,3,NA,3,3,2,3,36,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,86817.367332,95073.481824,2,91,15,15,5,4,4,2,0,0,1,34,1,5,1,5 +63185,7,2,1,3,NA,4,4,1,3,40,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10040.033098,11070.778245,1,100,3,3,0.73,3,3,2,0,0,2,39,1,3,5,NA +63186,7,2,1,11,NA,5,7,1,11,136,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11611.58308,11813.013945,1,98,14,14,3.16,6,6,2,2,0,1,39,1,5,1,5 +63187,7,2,1,80,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,26773.686592,29962.63786,2,98,6,6,1.7,2,2,0,0,2,2,80,1,2,1,2 +63188,7,2,2,60,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,4,NA,1,2,2,1,2,2,1,2,2,1,12782.405209,13353.125929,1,100,3,3,1.17,1,1,0,0,1,2,60,1,4,4,NA +63189,7,2,2,0,5,4,4,2,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4964.196196,5018.399368,1,93,1,1,0.16,3,3,1,1,0,2,39,1,3,5,NA +63190,7,2,1,53,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,104765.204996,105038.68379,2,92,15,15,5,5,5,0,3,0,2,46,1,5,1,5 +63191,7,2,2,30,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,70667.985128,72578.248908,2,92,15,7,3.67,2,1,0,0,0,2,30,1,5,1,NA +63192,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,41229.806244,46206.205733,2,103,6,6,1.82,2,2,0,0,2,1,70,1,2,5,NA +63193,7,2,2,41,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,2,1,2,2,1,2,2,1,2,2,1,26389.420306,26882.397721,2,98,3,3,0.96,1,1,0,0,0,2,41,1,4,3,NA +63194,7,2,2,56,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,2,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,12649.084278,13204.362319,3,90,4,4,0.92,3,3,0,0,1,2,56,2,2,1,2 +63195,7,2,1,59,NA,2,2,1,NA,NA,2,NA,2,2,7,NA,3,1,NA,2,2,2,2,2,2,1,2,1,2,24211.824535,24594.266281,2,93,8,8,2.57,3,3,0,0,1,1,59,2,3,1,3 +63196,7,2,1,39,NA,4,4,1,NA,NA,2,NA,2,1,4,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,18838.303827,18900.579975,2,93,12,12,NA,4,4,1,1,0,2,27,2,4,1,4 +63197,7,2,2,27,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,1,1,2,2,1,2,2,1,2,2,1,18070.666316,17918.945427,1,99,7,7,2.38,2,2,0,0,0,2,27,1,5,1,5 +63198,7,2,1,80,NA,4,4,2,NA,NA,2,NA,2,1,6,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,7199.330978,7340.349591,1,93,4,4,1.56,1,1,0,0,1,1,80,2,5,2,NA +63199,7,2,1,12,NA,3,3,1,12,151,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,27156.800586,27669.661454,1,92,5,5,1.05,3,3,1,1,0,2,35,1,4,5,NA +63200,7,2,2,59,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,164722.990078,163821.547042,1,90,15,15,5,3,3,0,0,0,1,59,1,5,1,5 +63201,7,2,1,7,NA,1,1,1,7,90,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12665.770043,13116.669484,1,100,9,9,2.02,6,6,0,3,1,2,39,1,4,1,5 +63202,7,2,1,0,3,5,7,2,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6371.499593,6469.293142,2,95,12,14,3.93,4,3,1,0,0,1,35,1,5,1,4 +63203,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,35334.703093,40990.264786,1,101,3,3,0.9,1,1,0,0,1,2,80,1,2,2,NA +63204,7,2,2,44,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,2,1,2,2,1,2,2,1,2,2,1,26757.554986,26943.613048,2,97,7,7,1.89,3,3,0,0,0,1,50,1,2,1,2 +63205,7,2,1,67,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,1,28216.191929,28480.821588,1,101,7,7,1.83,3,3,0,0,2,1,67,1,1,1,2 +63206,7,2,1,38,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,14204.262514,14001.792163,1,99,7,7,1.06,7,7,3,1,0,1,38,1,4,6,NA +63207,7,2,2,8,NA,3,3,2,8,107,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,52414.628675,53163.961325,1,91,14,14,2.44,7,7,2,4,0,1,33,1,5,1,5 +63208,7,2,1,30,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,105261.096488,116369.237268,1,97,15,15,5,3,3,1,0,0,2,31,1,5,1,5 +63209,7,2,1,39,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,65033.706797,70202.805273,1,102,8,8,2.42,4,4,0,2,0,2,34,1,4,1,3 +63210,7,2,1,10,NA,4,4,2,10,121,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7250.311091,8640.316317,2,99,2,2,0.2,7,7,1,2,1,1,63,1,1,2,NA +63211,7,2,2,46,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,93110.905446,112207.13845,1,92,14,14,3.16,6,6,1,1,0,1,49,1,1,1,3 +63212,7,2,1,62,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,11764.405491,12074.424659,1,97,4,4,1.34,1,1,0,0,1,1,62,1,5,5,NA +63213,7,2,1,43,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,13535.287828,13486.390654,3,92,8,8,0.91,7,7,3,3,1,1,61,NA,NA,1,4 +63214,7,2,1,37,NA,1,1,1,NA,NA,2,NA,2,1,5,NA,1,6,NA,2,2,2,1,2,2,1,2,2,2,37715.365512,38126.275234,2,102,5,5,0.59,7,7,1,3,0,1,37,2,1,6,NA +63215,7,2,2,62,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,11355.3308,11862.334174,1,96,15,15,5,3,3,0,0,1,2,62,1,4,3,NA +63216,7,2,1,54,NA,1,1,2,NA,NA,2,NA,2,1,7,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,29042.244317,28700.143679,1,90,12,12,NA,4,4,0,0,0,1,54,2,4,1,2 +63217,7,1,2,8,NA,5,7,NA,NA,NA,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16195.492817,0,3,91,5,5,0.65,7,7,0,4,0,2,39,1,3,4,NA +63218,7,2,1,35,NA,1,1,2,NA,NA,2,NA,2,2,4,NA,1,1,NA,2,2,2,1,2,2,NA,NA,NA,NA,34887.439952,35451.076414,2,94,3,3,0.82,2,2,0,0,0,1,35,2,1,1,2 +63219,7,2,1,39,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,20698.946375,20973.485449,3,91,15,15,5,1,1,0,0,0,1,39,2,5,5,NA +63220,7,2,1,27,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,22634.531479,23281.741513,1,103,9,2,0.81,3,1,0,0,0,1,27,1,5,5,NA +63221,7,2,2,67,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,16352.915834,18960.412859,3,92,8,8,2.97,2,2,0,0,1,1,49,1,2,3,NA +63222,7,2,2,51,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,20360.306379,19986.123493,2,99,15,15,5,2,2,0,0,0,2,51,1,5,1,5 +63223,7,2,1,59,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,174520.785302,174307.982009,1,95,7,7,3.21,1,1,0,0,0,1,59,1,4,3,NA +63224,7,2,2,31,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,1,2,1,2,2,1,2,2,1,2,2,1,29102.738194,28317.485179,1,103,7,7,0.51,7,7,3,4,0,1,54,2,1,1,1 +63225,7,2,2,63,NA,4,4,2,NA,NA,2,NA,2,1,7,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,11355.3308,11862.334174,1,96,12,12,NA,5,5,2,0,1,2,63,2,5,3,NA +63226,7,2,2,2,NA,2,2,1,2,32,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,9267.834226,9392.475614,2,93,77,77,NA,4,4,1,1,0,2,33,2,4,1,4 +63227,7,2,2,40,NA,1,1,1,NA,NA,2,NA,99,NA,NA,NA,3,1,2,2,2,2,2,2,2,NA,NA,NA,NA,25713.328161,31117.9447,1,103,5,5,0.74,5,5,1,1,0,2,40,99,3,1,1 +63228,7,2,1,27,NA,2,2,2,NA,NA,2,NA,2,1,5,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,44074.735764,53571.145963,2,91,4,4,0.84,3,3,1,0,0,2,21,1,4,1,2 +63229,7,2,1,40,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,19440.793325,19514.660132,2,95,9,9,1.81,6,6,1,1,0,2,56,1,4,3,NA +63230,7,2,1,48,NA,5,6,2,NA,NA,2,NA,2,2,1,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,14455.875684,16658.375886,1,93,9,9,5,1,1,0,0,0,1,48,2,5,5,NA +63231,7,2,2,42,NA,2,2,2,NA,NA,2,NA,2,2,4,NA,4,5,2,2,2,2,2,2,2,2,2,1,2,29141.220673,30195.229087,2,99,99,1,0,4,1,0,0,0,2,42,2,4,5,NA +63232,7,2,2,14,NA,4,4,1,14,170,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10128.026158,10319.790822,2,103,7,7,1.48,5,5,0,1,1,2,80,1,4,3,NA +63233,7,2,1,32,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,23284.536512,27522.885754,1,97,5,5,1.04,4,4,1,1,0,1,32,1,3,6,NA +63234,7,2,2,35,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,20310.041341,20837.576644,1,92,3,3,0.9,1,1,0,0,0,2,35,1,5,5,NA +63235,7,2,2,63,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,16352.915834,17093.606152,3,92,3,3,0.95,2,2,0,0,2,2,63,1,4,1,1 +63236,7,2,1,80,NA,2,2,1,NA,NA,1,1,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,NA,14200.083364,14896.175407,2,98,3,3,1.1,1,1,0,0,1,1,80,1,3,3,NA +63237,7,2,1,2,NA,3,3,1,2,30,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,49276.9767,53002.397569,2,98,15,15,5,3,3,1,0,0,1,26,1,4,1,4 +63238,7,2,2,80,NA,2,2,1,NA,NA,2,NA,2,1,8,NA,2,2,NA,2,2,2,1,2,2,NA,NA,NA,NA,18006.276697,19962.608629,2,93,3,3,0.66,2,2,0,0,1,2,80,2,2,2,NA +63239,7,2,2,6,NA,4,4,1,6,74,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9399.281543,9563.245188,2,96,4,4,0.57,5,5,0,3,0,2,26,1,2,5,NA +63240,7,2,1,5,NA,2,2,1,5,63,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16775.083123,17306.08847,2,98,6,6,1.07,5,5,3,0,0,2,24,1,3,1,3 +63241,7,1,1,9,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,37831.648033,0,1,99,77,77,NA,4,4,0,2,0,2,45,1,3,1,NA +63242,7,2,1,59,NA,1,1,2,NA,NA,2,NA,2,2,6,NA,1,1,NA,2,2,2,1,2,2,NA,NA,NA,NA,25221.349696,24851.265269,3,91,6,6,0.89,7,7,1,1,0,1,59,2,1,1,1 +63243,7,2,1,2,NA,1,1,1,2,26,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12493.910388,13058.677088,2,98,6,6,0.63,7,7,2,2,1,1,60,1,3,1,2 +63244,7,2,1,4,NA,4,4,2,4,49,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9228.425814,10175.8485,1,96,8,8,2,4,4,1,2,0,2,40,1,4,5,NA +63245,7,2,2,40,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,99275.150567,100291.087043,2,95,12,5,1.79,2,1,0,0,0,2,40,1,4,6,NA +63246,7,2,1,13,NA,4,4,2,13,167,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13416.172328,13513.882801,1,96,15,15,5,4,4,0,1,0,1,42,2,4,1,4 +63247,7,2,1,19,NA,5,7,2,19,239,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13251.602554,13277.802057,1,96,15,15,5,3,3,0,0,0,2,40,1,5,1,4 +63248,7,2,1,75,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,67447.112074,71391.281096,1,101,15,15,5,3,3,0,0,2,1,75,1,2,1,2 +63249,7,2,1,67,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,102183.259724,105037.978798,2,90,15,8,4.59,2,1,0,0,2,1,67,1,5,6,NA +63250,7,2,1,17,NA,3,3,2,17,212,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,88198.948426,91036.751291,1,101,9,9,2.6,4,4,0,1,2,2,63,1,4,1,4 +63251,7,2,2,80,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,1,2,NA,1,2,1,1,2,2,NA,NA,NA,NA,15288.064726,15818.288224,3,91,3,3,0.54,3,3,0,0,1,1,57,2,4,1,3 +63252,7,2,1,7,NA,4,4,1,7,95,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11709.3276,12266.117914,1,100,8,8,3.3,2,2,0,1,0,2,44,1,4,3,NA +63253,7,2,2,13,NA,4,4,2,13,164,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11160.089502,11615.801738,2,99,99,99,NA,5,5,0,2,0,2,20,1,3,6,NA +63254,7,2,2,72,NA,2,2,1,NA,NA,2,NA,2,1,8,NA,2,1,NA,2,2,2,1,2,2,1,2,2,NA,23271.708938,25108.705116,1,102,7,7,1.7,4,4,0,0,2,1,44,1,4,4,NA +63255,7,1,1,64,NA,4,4,NA,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,6239.974623,0,1,96,77,77,NA,2,2,0,0,2,1,64,1,5,1,5 +63256,7,2,1,9,NA,4,4,1,9,110,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,10122.702296,10196.10824,2,93,9,9,2.86,4,4,1,1,0,1,30,1,4,6,NA +63257,7,2,2,6,NA,5,6,2,6,83,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6834.715094,7332.504615,2,90,5,5,1.08,3,3,0,1,0,2,29,2,4,1,5 +63258,7,2,1,1,12,3,3,2,NA,13,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,46703.291366,54723.864587,1,93,15,15,5,3,3,1,0,0,1,37,1,5,1,5 +63259,7,2,2,7,NA,1,1,1,7,95,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10118.363218,10311.586628,2,103,10,10,1.63,7,7,1,4,0,1,31,NA,NA,1,4 +63260,7,2,2,42,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,4,4,2,1,2,2,1,2,2,1,2,2,1,36276.046363,36418.32035,2,91,99,99,NA,3,3,0,0,0,1,40,NA,NA,1,4 +63261,7,2,2,41,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,20434.221508,20198.461156,1,102,15,15,5,3,3,0,1,0,1,41,1,5,1,5 +63262,7,2,2,76,NA,1,1,1,NA,NA,2,NA,2,1,8,NA,2,2,NA,2,2,2,1,2,2,2,2,2,NA,19352.965911,23161.019266,1,103,6,6,0.97,6,6,0,3,1,2,50,2,1,1,1 +63263,7,2,1,53,NA,2,2,1,NA,NA,2,NA,2,1,7,NA,3,1,NA,2,2,2,2,2,2,1,2,2,1,24211.824535,24594.266281,2,93,6,6,1.39,4,4,0,0,0,1,53,2,3,1,3 +63264,7,2,1,32,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,1,1,NA,1,2,1,1,2,2,1,2,1,NA,20963.414192,21636.182301,1,100,5,5,0.74,6,6,0,3,0,1,40,2,3,1,4 +63265,7,2,2,28,NA,4,4,2,NA,NA,2,NA,2,2,1,NA,5,6,2,1,2,2,1,2,2,1,2,2,1,28823.434754,27922.831827,1,97,6,1,0,2,1,0,0,0,1,31,1,5,6,NA +63266,7,2,1,0,10,4,4,2,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6575.334977,7272.954395,2,95,2,2,0.42,3,3,2,0,0,1,25,1,3,5,NA +63267,7,2,2,72,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,35965.834545,38220.111719,1,101,3,3,1.12,1,1,0,0,1,2,72,1,3,2,NA +63268,7,2,1,12,NA,2,2,1,12,154,NA,NA,1,1,NA,7,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,15506.325263,16662.012915,1,103,5,5,0.74,5,5,0,1,0,1,47,2,1,1,1 +63269,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,25840.959268,29976.982116,1,101,77,77,NA,2,2,0,0,2,2,80,1,1,2,NA +63270,7,2,1,4,NA,1,1,1,4,55,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16775.083123,17306.08847,2,98,14,14,3.25,5,5,2,1,0,1,37,1,5,1,5 +63271,7,2,1,19,NA,5,6,1,19,236,2,NA,2,2,5,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,8062.957534,8614.793403,1,92,12,12,NA,7,7,1,2,1,2,45,2,3,1,3 +63272,7,2,2,20,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,NA,NA,NA,1,2,2,1,114993.808573,116714.079488,1,98,7,NA,NA,4,1,0,0,0,2,20,1,4,5,NA +63273,7,2,1,66,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,11492.781131,11942.286414,1,100,15,15,5,2,2,0,0,2,2,64,1,3,1,3 +63274,7,2,2,5,NA,5,7,1,5,61,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11956.543345,12952.739683,1,94,2,2,0.33,5,5,1,3,0,2,37,1,4,3,NA +63275,7,2,1,0,3,3,3,2,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,22570.662508,23423.888442,1,92,9,9,2,6,6,1,3,0,1,33,1,4,1,4 +63276,7,2,1,67,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,18079.825103,18175.893804,2,97,3,3,0.92,1,1,0,0,1,1,67,1,1,2,NA +63277,7,2,1,18,NA,3,3,2,18,224,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,69216.263169,70543.167563,1,91,14,14,3.15,5,5,0,1,0,2,50,1,5,1,5 +63278,7,2,2,3,NA,5,6,1,3,39,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7029.864692,7462.832472,3,92,8,8,0.91,7,7,3,3,1,1,61,NA,NA,1,4 +63279,7,2,1,1,18,4,4,2,NA,19,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5770.570361,6126.790978,2,99,5,5,0.65,6,6,2,1,0,2,53,1,4,3,NA +63280,7,2,1,12,NA,5,6,1,12,150,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7558.274942,7903.176011,2,96,15,15,5,3,3,0,2,0,2,42,2,5,4,NA +63281,7,2,1,40,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,4,1,NA,2,2,2,2,2,2,2,2,2,2,35406.972937,35699.930106,2,98,6,6,1.21,4,4,1,0,0,2,49,2,2,6,NA +63282,7,2,1,5,NA,5,7,1,5,64,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11081.601387,11216.767571,2,95,6,6,1.3,4,4,1,1,0,1,47,1,5,1,4 +63283,7,2,1,36,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,19133.795531,19387.575333,2,91,15,15,4.63,7,7,1,2,0,1,36,2,4,1,3 +63284,7,2,1,79,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,81415.860066,87761.355472,1,97,7,7,2.64,2,2,0,0,2,1,79,1,4,1,3 +63285,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,42992.537371,49508.460769,2,95,3,3,1.16,1,1,0,0,1,2,80,1,3,2,NA +63286,7,2,2,0,9,3,3,2,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10692.488346,10402.056617,1,101,4,4,0.79,3,3,1,0,0,1,41,1,3,1,3 +63287,7,2,2,78,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,18956.418923,20374.294465,2,101,99,99,NA,3,3,0,1,1,2,78,1,1,2,NA +63288,7,2,2,58,NA,4,4,2,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,16033.091438,16307.204086,1,96,77,77,NA,4,4,0,0,0,1,52,2,5,1,5 +63289,7,2,1,6,NA,3,3,1,6,77,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,47990.623546,51629.685381,1,100,15,15,4.07,5,5,0,2,0,2,41,1,5,1,4 +63290,7,2,2,16,NA,4,4,2,16,201,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11436.28571,11295.489882,1,93,1,1,0.02,5,5,0,4,0,2,36,NA,NA,5,NA +63291,7,2,1,47,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,21799.527449,22114.217255,1,96,14,14,5,1,1,0,0,0,1,47,1,5,3,NA +63292,7,2,2,6,NA,5,7,1,6,76,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12292.225251,12666.385814,1,95,14,14,3.04,6,6,0,4,0,1,56,1,5,1,4 +63293,7,2,2,61,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,1,9570.416297,10355.226074,2,98,5,5,1.93,1,1,0,0,1,2,61,1,2,2,NA +63294,7,2,2,62,NA,5,7,1,NA,NA,2,NA,2,1,5,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,9525.506997,9950.810696,2,93,9,9,5,1,1,0,0,1,2,62,2,4,3,NA +63295,7,2,1,80,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,44886.08631,48362.89646,2,102,6,6,1.15,5,5,0,0,2,1,80,1,5,1,1 +63296,7,2,2,55,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,16672.82247,17074.238333,1,92,15,15,4.44,5,5,0,0,1,1,65,NA,NA,1,5 +63297,7,2,1,50,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,174520.785302,182298.775287,1,101,14,14,5,3,3,0,1,0,2,36,1,5,1,5 +63298,7,2,2,22,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,16291.99448,17037.586582,1,90,15,15,3.7,5,5,0,0,0,1,54,NA,NA,1,NA +63299,7,2,1,17,NA,1,1,1,17,208,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,22768.423624,23116.446945,2,98,9,9,2.6,4,4,0,2,0,1,30,1,2,1,2 +63300,7,2,2,5,NA,1,1,1,5,63,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,19235.084509,21236.049482,3,92,4,4,0.65,4,4,2,0,0,2,20,1,3,5,NA +63301,7,2,2,63,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,12433.776145,13392.195631,2,99,6,6,1.39,4,4,1,0,1,2,63,1,3,3,NA +63302,7,2,1,28,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,123110.069898,131423.888983,1,101,5,5,1.45,2,2,0,0,0,2,49,1,4,3,NA +63303,7,2,1,7,NA,1,1,2,7,85,NA,NA,2,2,3,0,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,11546.167056,12698.029578,1,90,4,4,0.47,7,7,1,1,0,2,50,2,1,1,1 +63304,7,2,2,32,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,2,1,2,2,1,2,2,1,2,2,1,98760.497744,125641.994435,2,91,15,6,2.69,2,1,0,0,0,1,44,1,3,5,NA +63305,7,2,1,37,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,16905.961576,17390.157008,2,94,7,7,1.18,7,7,1,4,0,2,31,1,4,6,NA +63306,7,2,1,37,NA,2,2,1,NA,NA,2,NA,2,1,5,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,34438.924452,34418.648235,1,100,9,9,2.02,6,6,0,3,1,2,39,1,4,1,5 +63307,7,2,1,8,NA,3,3,1,8,104,NA,NA,1,1,NA,1,NA,NA,NA,1,NA,2,1,2,2,1,2,2,1,66868.503099,69864.859716,1,98,15,15,4.34,4,4,1,1,0,1,41,1,5,1,5 +63308,7,2,1,28,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,22497.998055,22497.243767,1,102,4,2,0.73,2,1,0,0,0,1,36,NA,NA,4,NA +63309,7,2,1,0,10,5,6,1,NA,12,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9148.090461,9898.749752,1,92,14,14,3.3,4,4,2,0,0,1,28,1,4,1,4 +63310,7,2,2,53,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,25964.813959,25539.412946,2,101,2,2,0.74,1,1,0,0,0,2,53,1,2,5,NA +63311,7,2,1,62,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,1,7323.703412,7610.147862,1,96,12,12,NA,7,7,1,0,1,2,59,1,3,1,1 +63312,7,2,1,74,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,65208.881742,76821.663824,3,91,7,7,2.92,2,2,0,0,2,1,74,1,3,1,3 +63313,7,2,1,56,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,20297.001922,20419.260869,1,96,15,15,5,2,2,0,0,0,1,56,1,5,1,5 +63314,7,2,2,0,8,4,4,1,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4200.172174,4368.199293,2,93,10,10,2.26,6,6,2,0,0,1,34,1,4,1,4 +63315,7,2,2,54,NA,5,6,2,NA,NA,2,NA,2,2,6,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,17852.668137,18502.046882,3,91,3,3,0.54,3,3,0,0,1,1,57,2,4,1,3 +63316,7,2,1,10,NA,4,4,2,10,121,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9023.469661,9333.449986,2,90,14,14,4.25,4,4,0,2,1,2,45,2,5,5,NA +63317,7,2,1,32,NA,5,6,2,NA,NA,1,1,2,2,5,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,17585.737085,18369.998342,2,91,12,5,2.2,3,1,0,0,0,1,29,NA,NA,5,NA +63318,7,2,1,27,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,17420.978407,17115.540769,2,97,12,6,2.75,3,1,0,0,0,1,21,NA,NA,77,NA +63319,7,1,2,51,NA,5,6,NA,NA,NA,2,NA,2,1,7,NA,5,77,NA,1,2,2,1,2,2,NA,NA,NA,NA,18322.475193,0,3,91,12,14,5,2,1,0,0,0,2,51,2,5,77,NA +63320,7,2,2,27,NA,5,6,2,NA,NA,2,NA,2,2,2,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,16844.740449,17983.530016,3,91,7,7,2.72,2,2,0,0,0,2,27,2,5,1,5 +63321,7,2,1,6,NA,3,3,2,6,82,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,65374.972543,69123.624578,1,90,15,15,5,4,4,0,2,0,1,37,1,5,1,5 +63322,7,2,2,6,NA,4,4,2,6,81,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9460.53021,9835.43092,1,96,6,6,1.98,2,2,0,1,0,2,29,1,3,5,NA +63323,7,2,2,48,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,16833.890659,17522.038775,3,91,15,15,5,4,4,0,2,0,1,38,2,5,1,5 +63324,7,2,1,35,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,4,1,NA,1,2,2,1,2,1,NA,NA,NA,NA,11715.79771,11871.189399,2,92,5,5,0.64,7,7,1,2,1,1,66,2,1,1,3 +63325,7,2,2,2,NA,1,1,1,2,25,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14326.094268,15816.39252,3,92,15,15,5,3,3,1,0,0,1,41,2,5,1,3 +63326,7,2,2,51,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,11574.200203,11257.441852,2,99,NA,77,NA,7,7,1,0,1,2,51,1,2,1,3 +63327,7,2,1,14,NA,3,3,1,14,176,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,25736.568804,25798.716176,3,92,5,5,1.03,4,4,0,3,0,1,55,1,4,4,NA +63328,7,2,2,61,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,9793.924718,10231.212981,2,100,10,10,2.75,5,5,1,1,1,1,27,1,3,1,5 +63329,7,2,2,71,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,27842.199551,30775.350974,1,90,15,15,5,2,2,0,0,2,1,74,1,3,1,3 +63330,7,2,1,51,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,174520.785302,174976.353865,1,95,12,12,NA,6,6,2,0,0,2,42,1,2,1,5 +63331,7,2,2,31,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,64048.78027,64245.709042,2,95,6,6,1.98,2,2,0,0,0,1,35,1,4,1,4 +63332,7,2,2,15,NA,1,1,1,15,186,NA,NA,1,1,NA,8,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,18515.058419,19360.671834,2,96,6,6,0.87,6,6,1,3,0,1,46,2,1,1,1 +63333,7,2,1,66,NA,4,4,1,NA,NA,2,NA,2,2,8,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,8062.039403,9043.239367,2,103,4,4,0.99,2,2,0,0,2,1,66,2,3,1,NA +63334,7,2,1,9,NA,1,1,1,9,113,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10890.103352,10791.203193,1,102,4,4,0.61,5,5,2,2,0,2,27,2,2,5,NA +63335,7,2,1,10,NA,4,4,2,10,126,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10665.048307,10877.092316,1,96,6,6,1.52,3,3,0,1,0,2,44,1,3,1,3 +63336,7,2,2,9,NA,5,6,1,9,109,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7932.110938,8316.610099,3,92,8,8,0.91,7,7,3,3,1,1,61,NA,NA,1,4 +63337,7,2,1,75,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,8544.243039,9048.352361,2,95,12,12,NA,3,3,0,0,3,2,73,1,2,1,1 +63338,7,2,1,31,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,28996.250643,28582.932384,2,101,14,14,5,1,1,0,0,0,1,31,1,4,3,NA +63339,7,2,2,41,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,15747.833197,16391.584661,3,91,14,14,4.03,4,4,0,2,0,1,51,2,4,1,5 +63340,7,2,1,26,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,34099.599202,34629.549705,1,94,5,5,0.74,5,5,1,1,0,2,24,1,3,1,4 +63341,7,2,1,48,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,1,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,18094.847125,18029.478224,3,91,14,9,2.68,6,4,0,0,2,1,48,2,1,1,1 +63342,7,2,1,10,NA,5,6,2,11,132,NA,NA,2,2,2,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8151.552109,8792.161653,1,90,14,14,3.98,3,3,0,1,0,1,33,2,5,1,5 +63343,7,2,2,45,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,129042.31855,133624.984525,2,101,14,14,4.86,3,3,0,1,0,1,53,1,4,1,5 +63344,7,2,2,26,NA,1,1,1,NA,NA,2,NA,2,2,1,NA,5,1,2,2,1,2,2,2,2,NA,NA,NA,NA,46606.430863,48004.221702,2,102,15,15,5,3,3,1,0,0,1,41,2,2,1,5 +63345,7,2,2,68,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,10346.035773,10598.2543,1,99,6,6,1.84,2,2,0,0,2,1,69,1,3,1,4 +63346,7,2,1,36,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,1,1,NA,2,2,2,2,2,2,NA,NA,NA,NA,51543.062078,54553.310105,3,92,4,4,0.55,6,6,0,4,0,1,36,2,1,1,3 +63347,7,2,2,15,NA,1,1,1,15,189,NA,NA,1,1,NA,9,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,26325.414456,26852.811114,3,92,7,7,1.3,5,5,1,2,0,2,33,2,2,1,1 +63348,7,1,2,10,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14716.367649,0,1,91,6,6,1.13,6,6,1,3,0,1,40,1,4,6,NA +63349,7,2,2,48,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,3,1,NA,1,2,1,1,2,2,NA,NA,NA,NA,20001.392001,24207.190257,1,100,99,99,NA,6,6,0,1,0,1,53,2,2,1,3 +63350,7,2,1,16,NA,3,3,1,16,199,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,103085.56884,109495.609645,1,94,15,15,5,4,4,0,1,0,1,41,1,5,1,5 +63351,7,2,2,30,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,26465.930618,26744.909102,2,100,14,14,4.59,3,3,1,0,0,1,30,NA,NA,1,4 +63352,7,2,1,64,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,125558.167126,127168.668278,1,94,15,15,5,4,3,0,0,1,1,33,1,2,5,NA +63353,7,2,2,23,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,36283.627734,36608.028102,1,102,5,1,0.21,5,4,1,1,0,2,24,1,4,5,NA +63354,7,2,2,1,17,4,4,1,NA,18,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7881.296797,8480.363269,2,96,14,14,3.06,5,5,1,1,1,2,54,1,3,6,NA +63355,7,2,2,9,NA,1,1,2,9,113,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17596.36942,17952.278489,1,97,4,4,0.65,4,4,0,1,0,2,45,2,2,3,NA +63356,7,1,2,70,NA,1,1,NA,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,29145.675285,0,3,92,6,6,1.98,2,2,0,0,2,1,72,1,4,1,1 +63357,7,2,2,31,NA,1,1,2,NA,NA,2,NA,2,2,5,NA,2,6,2,2,2,2,1,2,2,2,2,2,2,31460.18163,32805.207594,2,97,4,4,0.6,6,6,2,2,0,1,35,2,2,6,NA +63358,7,2,1,6,NA,3,3,2,6,82,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14307.565788,15198.555052,3,91,3,3,0.76,3,3,0,1,0,2,24,1,4,6,NA +63359,7,1,1,1,16,3,3,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,50163.512784,0,1,90,15,15,5,4,4,1,1,0,2,39,1,5,1,4 +63360,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,35525.197101,39677.515157,2,93,8,8,2.17,4,4,0,0,2,2,62,1,4,3,NA +63361,7,2,1,67,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,1,8232.241159,8296.636338,2,98,6,6,2.75,1,1,0,0,1,1,67,1,5,2,NA +63362,7,1,2,80,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,38758.039282,0,1,101,6,6,1.78,2,2,0,0,2,1,80,1,2,1,1 +63363,7,2,2,65,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,35475.142583,36054.748166,2,95,2,2,0.75,1,1,0,0,1,2,65,1,5,5,NA +63364,7,2,2,73,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,21143.97379,23464.841482,1,97,12,12,NA,4,4,0,0,2,1,72,1,2,1,3 +63365,7,2,2,50,NA,2,2,1,NA,NA,2,NA,2,2,2,NA,2,1,NA,2,2,2,1,2,2,2,2,1,2,23200.373382,24548.135184,2,93,5,5,1.26,3,3,0,1,0,1,55,2,2,1,2 +63366,7,2,2,11,NA,4,4,2,11,139,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,5221.819282,5505.774343,3,90,3,3,0.37,5,5,2,2,0,2,36,2,4,4,NA +63367,7,2,1,10,NA,4,4,1,10,126,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8714.559478,8865.734494,2,96,12,10,2.17,7,6,2,3,0,1,29,1,4,3,NA +63368,7,2,2,6,NA,1,1,2,6,82,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,14300.71869,15541.734563,2,94,9,9,2.1,5,5,1,2,0,1,31,2,4,1,4 +63369,7,2,2,10,NA,4,4,2,10,122,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8147.287486,8590.325322,2,90,8,8,2.59,3,3,0,2,0,2,35,1,4,6,NA +63370,7,2,2,6,NA,2,2,2,6,82,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15148.721588,15796.67129,2,91,2,2,0.22,4,4,0,3,0,2,45,2,5,4,NA +63371,7,2,1,13,NA,4,4,2,13,161,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10162.625863,10628.468372,2,99,5,5,0.78,5,5,2,2,0,2,30,1,3,5,NA +63372,7,2,2,2,NA,1,1,2,2,32,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,9955.153132,10271.907274,2,94,77,77,NA,4,4,2,0,0,2,27,2,3,1,3 +63373,7,2,2,29,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,16937.04417,23964.143641,2,98,9,9,3.83,2,2,1,0,0,2,29,2,4,5,NA +63374,7,2,1,57,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,1,16851.334496,17374.092058,2,95,4,4,1.34,1,1,0,0,0,1,57,1,1,2,NA +63375,7,2,2,17,NA,3,3,2,17,206,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,22046.14863,22741.646094,2,97,9,9,1.45,7,7,1,2,2,2,45,1,3,5,NA +63376,7,2,1,10,NA,1,1,1,10,124,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13927.458372,14042.313177,2,98,3,3,0.54,3,3,0,2,0,2,35,1,3,5,NA +63377,7,2,2,39,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,28315.055559,38147.595136,1,96,15,15,5,2,2,0,1,0,2,39,1,4,5,NA +63378,7,2,2,18,NA,1,1,1,19,228,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,2,2,2,1,2,2,1,16360.434077,17687.989006,3,91,5,5,1.03,4,4,0,2,0,2,42,2,1,5,NA +63379,7,2,1,10,NA,4,4,2,10,127,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9983.293162,10181.782419,1,97,4,4,0.46,7,7,3,3,0,2,31,1,3,1,NA +63380,7,2,1,47,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,4,NA,1,2,2,1,2,2,1,2,2,1,126789.52929,134450.153638,1,101,7,7,1.74,4,4,1,0,0,1,24,NA,NA,1,4 +63381,7,2,1,3,NA,4,4,2,3,46,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8947.841984,9500.1974,1,91,15,15,5,6,6,1,2,0,2,42,2,5,1,5 +63382,7,2,1,39,NA,1,1,2,NA,NA,2,NA,2,2,5,NA,2,1,NA,2,2,2,2,2,2,NA,NA,NA,NA,30626.581617,30979.39441,2,90,6,6,0.96,5,5,1,1,0,1,39,2,2,1,NA +63383,7,2,1,51,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,16287.780872,16801.552467,2,97,6,6,1.7,2,2,0,0,1,2,62,2,5,1,2 +63384,7,2,2,13,NA,5,7,2,13,161,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9508.389138,9876.066661,3,91,8,8,2.24,4,4,0,2,0,1,45,1,4,1,4 +63385,7,2,2,62,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,15369.196003,16055.414165,1,100,15,5,2.15,2,1,0,0,2,1,60,1,5,6,NA +63386,7,2,1,7,NA,2,2,1,7,91,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13927.458372,13742.678011,2,98,6,6,0.78,7,7,1,3,1,2,63,1,2,4,NA +63387,7,2,1,20,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,25815.880139,25989.236835,2,101,99,1,0.23,3,1,0,0,0,1,20,1,4,5,NA +63388,7,2,2,44,NA,4,4,2,NA,NA,2,NA,2,1,4,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,19100.40225,19426.955733,1,96,4,4,0.65,4,4,0,0,0,1,19,1,4,NA,NA +63389,7,2,1,80,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,31313.292063,33738.773556,1,95,6,6,1.65,2,2,0,0,2,2,80,1,4,1,4 +63390,7,2,1,53,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,151766.599459,154414.492891,3,91,7,7,1.97,4,4,0,0,1,2,77,1,5,2,NA +63391,7,2,1,70,NA,2,2,2,NA,NA,2,NA,2,1,9,NA,4,1,NA,2,2,2,1,2,2,1,2,2,NA,11755.776731,12180.618102,3,90,7,7,1.15,7,7,2,1,1,2,30,1,9,1,4 +63392,7,2,2,22,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,63717.895797,67578.761066,2,101,5,5,1.36,2,2,0,0,0,2,22,1,4,5,NA +63393,7,2,2,19,NA,1,1,1,19,236,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,20502.928313,21226.512457,2,98,8,8,2.24,4,4,0,0,0,1,58,2,1,1,3 +63394,7,2,1,16,NA,5,6,1,16,197,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,5873.088927,6275.048272,1,103,6,6,1.82,2,2,0,1,0,2,56,2,5,77,NA +63395,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,37456.985636,43133.944105,2,98,99,99,NA,2,2,0,0,2,2,80,1,3,1,1 +63396,7,2,1,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,26344.362464,28384.957988,2,95,13,13,NA,2,2,0,0,2,1,80,1,5,1,3 +63397,7,2,2,51,NA,5,6,2,NA,NA,2,NA,2,2,1,NA,2,1,NA,1,2,1,1,2,1,1,2,1,NA,17018.449206,17108.441787,2,91,99,1,0,7,3,0,4,0,1,36,2,9,1,2 +63398,7,2,2,78,NA,5,6,1,NA,NA,2,NA,2,2,8,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,11812.364238,12222.042847,1,94,4,4,1.11,2,2,0,0,1,2,37,2,4,5,NA +63399,7,2,2,5,NA,1,1,1,5,67,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,18078.669459,18848.958225,1,101,2,2,0.26,5,5,3,0,0,2,26,1,2,1,3 +63400,7,2,2,21,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,6,2,1,2,2,1,2,2,1,2,2,1,14883.664782,14924.287598,2,90,8,6,1.46,4,3,1,1,0,2,21,1,5,6,NA +63401,7,2,2,49,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,163194.688032,166437.638141,1,97,8,8,3.57,2,2,0,0,0,2,49,1,3,3,NA +63402,7,2,2,27,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,16844.740449,18124.20195,3,91,14,14,5,2,2,0,0,0,2,27,2,5,1,5 +63403,7,2,1,8,NA,4,4,1,8,104,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10199.928366,10684.945227,1,100,9,9,2.22,5,5,1,2,0,2,40,2,4,1,4 +63404,7,2,2,48,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,20048.680628,21335.7055,2,95,2,2,0.46,3,3,0,0,0,2,48,1,2,1,2 +63405,7,2,2,74,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,15914.916287,16468.700526,2,99,8,8,3.47,2,2,0,0,1,2,74,1,5,2,NA +63406,7,2,1,12,NA,4,4,2,13,156,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12462.601191,12584.643654,2,97,5,5,0.92,5,5,0,3,0,2,54,1,3,2,NA +63407,7,2,2,16,NA,4,4,1,16,203,NA,NA,1,1,NA,66,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12531.903464,13043.632492,2,100,4,4,0.86,3,3,0,2,0,2,36,1,3,5,NA +63408,7,2,1,8,NA,4,4,1,8,107,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13818.701911,14596.53451,2,101,2,2,0.38,3,3,0,2,0,2,56,1,3,2,NA +63409,7,2,2,69,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,11009.072628,11500.615946,2,99,2,2,0.53,2,2,0,0,1,2,69,1,4,2,NA +63410,7,2,1,22,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,16995.648055,16598.645683,2,100,3,3,0.27,7,7,2,1,0,2,41,1,2,5,NA +63411,7,2,1,19,NA,4,4,2,19,233,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13863.378072,13964.345562,1,96,15,15,5,4,4,0,1,0,1,56,1,4,1,5 +63412,7,2,2,40,NA,2,2,2,NA,NA,2,NA,2,2,5,NA,2,1,2,2,2,2,2,2,2,2,2,2,2,26889.724138,34281.795458,3,90,12,12,NA,2,2,0,1,0,2,40,2,2,1,NA +63413,7,2,2,61,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,4,NA,1,2,2,1,2,2,1,2,2,1,128294.718377,130390.843426,1,93,15,15,5,4,3,0,0,3,1,80,1,5,2,NA +63414,7,2,2,27,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,6,2,1,2,2,1,2,2,1,2,2,1,113642.287024,118593.484239,1,101,9,6,2.24,2,1,0,0,0,2,27,1,3,6,NA +63415,7,2,1,18,NA,4,4,2,18,226,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,8364.097643,8526.060452,2,90,6,6,0.96,5,5,0,1,0,1,55,1,4,6,NA +63416,7,2,2,7,NA,4,4,1,7,91,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7619.934086,8032.046596,1,103,8,8,1.95,4,4,0,1,0,2,48,1,5,1,5 +63417,7,2,2,6,NA,3,3,1,6,78,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,61745.495006,63723.291316,2,101,7,7,1.88,4,4,0,2,0,2,36,1,4,1,5 +63418,7,2,2,40,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,5,2,1,2,2,1,2,2,1,2,2,1,26595.398371,26963.678025,1,91,7,7,2.2,3,3,0,0,1,2,60,1,2,2,NA +63419,7,2,1,2,NA,3,3,2,2,25,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,25107.382643,27005.542261,1,95,6,6,1.35,3,3,1,0,0,1,22,1,3,1,4 +63420,7,2,1,62,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,21963.854411,22169.845613,2,102,3,3,1.29,1,1,0,0,1,1,62,1,4,3,NA +63421,7,2,1,13,NA,5,6,1,13,162,NA,NA,1,1,NA,6,NA,NA,NA,1,1,1,1,2,1,1,2,2,1,8915.81491,9312.338117,1,92,2,2,0.33,5,5,0,1,0,1,51,2,1,4,NA +63422,7,2,2,64,NA,1,1,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,12043.867275,12495.995159,1,91,1,1,0.05,2,1,0,0,2,1,72,1,1,3,NA +63423,7,2,2,2,NA,5,6,2,3,36,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6097.947961,6201.918891,1,96,15,15,4.34,4,4,1,1,0,1,36,2,5,1,5 +63424,7,2,1,17,NA,1,1,1,17,206,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,24902.864049,25040.491572,1,94,5,5,0.94,4,4,0,2,0,2,37,2,3,1,2 +63425,7,2,1,51,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,4,1,NA,1,2,1,1,2,2,1,2,2,1,13567.923118,13997.525763,3,91,14,14,4.03,4,4,0,2,0,1,51,2,4,1,5 +63426,7,2,1,58,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,32720.69734,33802.428047,1,95,3,3,1.19,1,1,0,0,0,1,58,1,2,3,NA +63427,7,2,2,9,NA,4,4,2,9,113,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9565.802332,9920.158544,1,96,14,14,2.58,6,6,2,2,0,1,40,2,4,1,4 +63428,7,2,2,13,NA,1,1,1,13,162,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18515.058419,19360.671834,2,96,6,6,1.12,4,4,0,3,0,1,26,1,2,77,NA +63429,7,2,1,21,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,16386.190684,20296.970403,2,90,7,4,1.38,2,1,0,0,0,1,21,1,3,5,NA +63430,7,2,2,4,NA,3,3,2,4,51,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,26966.264969,27815.81123,1,98,6,6,1.31,3,3,2,0,0,2,22,1,3,5,NA +63431,7,2,1,34,NA,5,6,1,NA,NA,2,NA,2,2,6,NA,2,5,NA,1,2,2,1,2,1,1,2,2,1,20071.705576,20599.326983,3,91,6,6,1.12,4,4,0,0,2,1,69,2,3,1,1 +63432,7,2,1,7,NA,3,3,1,7,89,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,48147.167375,49984.220445,3,92,14,14,2.74,6,6,2,2,0,1,35,1,5,1,4 +63433,7,2,1,4,NA,5,7,2,4,51,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10276.262805,11525.953064,1,97,15,15,4.77,4,4,1,1,0,2,40,1,5,1,5 +63434,7,2,2,23,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,16844.740449,17849.904413,3,91,6,3,1.1,3,1,0,0,0,2,23,1,5,5,NA +63435,7,2,1,14,NA,3,3,2,14,177,NA,NA,2,1,1,9,NA,NA,NA,1,1,1,1,2,1,1,2,2,1,26858.274239,26923.130249,2,97,5,5,0.8,5,5,1,2,0,1,46,2,4,1,2 +63436,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,1,2,1,2,2,1,2,2,NA,29302.509441,32727.496464,2,95,15,15,5,3,3,0,0,1,2,47,1,4,1,5 +63437,7,2,2,23,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,128575.977224,133862.807708,1,102,6,4,1.38,2,1,0,0,0,2,23,1,5,5,NA +63438,7,2,1,64,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,6358.062034,6283.458155,1,99,15,15,5,2,2,0,0,2,1,64,1,3,1,4 +63439,7,2,1,51,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,23431.677775,25582.72205,2,93,10,10,3.4,3,3,0,1,0,1,51,1,3,1,4 +63440,7,2,1,70,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,NA,54654.899954,58048.628546,2,103,6,6,1.82,2,2,0,0,2,1,70,1,2,5,NA +63441,7,2,1,3,NA,2,2,2,3,47,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14505.510202,14676.996441,2,94,6,6,1.43,5,4,2,1,0,2,23,2,3,6,NA +63442,7,2,2,51,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,24719.680932,27438.0417,1,97,4,4,1.61,1,1,0,0,0,2,51,1,4,3,NA +63443,7,2,2,8,NA,3,3,2,8,97,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,24070.467912,23750.822126,1,95,7,7,1.17,6,6,1,3,0,2,44,1,4,1,NA +63444,7,2,2,0,2,3,3,1,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8317.65714,8487.710712,1,94,7,7,1.21,6,6,2,2,0,1,31,1,2,6,NA +63445,7,2,2,21,NA,1,1,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,41527.748953,47819.246487,2,97,1,1,0.01,1,1,0,0,0,2,21,1,4,5,NA +63446,7,2,1,16,NA,4,4,1,16,195,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,17606.165994,18260.901254,2,101,6,6,1.16,4,4,0,3,0,2,36,1,4,4,NA +63447,7,2,2,9,NA,4,4,2,9,116,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8192.839047,8748.579234,2,99,5,5,1.32,2,2,0,1,0,2,34,1,4,5,NA +63448,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,47098.572584,49762.054694,1,95,5,5,1.43,2,2,0,0,2,1,80,1,3,1,4 +63449,7,2,1,38,NA,2,2,1,NA,NA,2,NA,2,2,5,NA,2,1,NA,2,2,2,1,2,2,1,2,2,2,41241.224595,43514.733172,2,102,6,6,1.12,4,4,1,1,0,1,38,2,2,1,3 +63450,7,2,1,6,NA,2,2,1,6,83,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16028.98796,15961.028504,1,100,14,14,4.71,3,3,0,1,0,1,38,1,5,1,5 +63451,7,2,1,28,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,16088.355002,17176.258631,2,100,13,13,NA,2,2,0,0,1,2,71,NA,NA,1,NA +63452,7,2,1,11,NA,4,4,1,11,136,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10469.725162,11059.049224,1,100,1,1,0,4,4,1,2,0,2,35,1,2,5,NA +63453,7,2,1,48,NA,1,1,1,NA,NA,2,NA,2,2,6,NA,1,1,NA,2,2,1,1,2,1,2,2,2,2,46745.699003,49120.516055,2,98,13,13,NA,5,5,0,2,0,1,48,2,1,1,2 +63454,7,2,1,13,NA,5,6,2,13,159,NA,NA,2,2,1,6,NA,NA,NA,1,1,1,NA,NA,NA,1,2,1,NA,10346.302718,11892.421636,2,91,99,1,0,7,3,0,4,0,1,36,2,9,1,2 +63455,7,2,1,30,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,24134.97174,25042.42256,1,98,7,7,1.52,4,4,2,0,0,1,30,1,3,1,4 +63456,7,2,1,80,NA,1,1,1,NA,NA,1,1,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,17609.976188,17569.292452,1,98,15,15,5,5,5,0,1,1,2,55,1,5,1,5 +63457,7,2,1,28,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,25807.688156,26357.095043,1,100,15,15,5,4,4,0,0,0,1,54,1,5,1,5 +63458,7,2,2,0,1,2,2,2,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8264.844608,8090.961959,1,93,14,14,4.75,3,3,1,0,0,2,42,1,5,1,5 +63459,7,2,2,80,NA,2,2,2,NA,NA,2,NA,2,1,7,NA,1,2,NA,2,2,2,2,2,2,2,2,2,NA,21933.218587,23583.994398,1,93,2,2,0.43,2,2,0,0,2,2,80,2,1,2,NA +63460,7,2,1,2,NA,3,3,2,2,30,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,47507.757497,54303.981935,1,101,6,6,0.97,7,7,2,1,0,1,43,1,2,1,NA +63461,7,2,2,21,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,34906.069211,35828.732314,1,103,1,1,0.03,3,3,0,0,0,1,50,1,2,3,NA +63462,7,2,2,18,NA,4,4,2,18,218,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,10484.6104,10912.740054,2,99,3,3,0.56,4,4,1,0,0,2,38,1,3,5,NA +63463,7,2,2,61,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,117419.769432,119338.215671,2,95,15,15,5,2,2,0,0,1,1,54,NA,NA,1,4 +63464,7,2,1,7,NA,1,1,1,7,90,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,17882.621856,18280.794545,3,92,8,8,1.55,6,6,1,3,0,2,38,1,5,1,4 +63465,7,2,1,55,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,16287.780872,16385.890285,2,100,10,10,4.42,2,2,0,0,0,2,55,1,2,1,4 +63466,7,2,1,49,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,17602.101156,21123.738865,1,96,14,14,2.19,7,7,0,2,0,1,39,1,2,1,3 +63467,7,2,2,10,NA,4,4,1,11,132,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,9139.784234,11102.911341,2,100,6,6,0.85,6,6,0,2,0,1,59,1,3,1,3 +63468,7,2,1,55,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,26135.885159,26052.523863,2,101,NA,99,NA,2,1,0,0,0,1,55,1,2,3,NA +63469,7,2,2,14,NA,2,2,2,14,175,NA,NA,1,1,NA,9,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,14437.97544,16344.869867,2,90,3,3,0.38,5,5,0,4,0,2,33,2,2,5,NA +63470,7,2,1,2,NA,4,4,2,2,25,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6580.937346,7256.559544,2,97,3,3,0.66,3,3,2,0,0,2,19,1,3,NA,NA +63471,7,2,2,65,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,NA,37074.886861,38850.492434,1,101,3,3,1.07,2,1,0,0,1,2,65,1,3,3,NA +63472,7,2,2,24,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,137368.929197,138597.101074,1,91,6,5,1.93,2,1,0,0,0,2,24,1,4,6,NA +63473,7,2,1,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,31313.292063,33738.773556,1,101,7,7,2.31,2,2,0,0,2,2,80,1,4,1,2 +63474,7,2,1,74,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,74761.468834,80588.325624,2,91,7,7,1.89,3,3,0,0,2,2,69,NA,NA,1,4 +63475,7,2,1,41,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,111236.95715,110951.212312,2,92,15,6,2.75,2,1,0,0,0,1,41,1,4,5,NA +63476,7,2,2,15,NA,1,1,1,15,187,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,21818.047789,22469.060223,2,102,5,5,0.89,4,4,1,2,0,2,36,2,5,3,NA +63477,7,2,2,4,NA,4,4,2,4,56,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10389.292229,10657.457488,2,95,6,6,1.65,2,2,1,0,0,2,27,2,4,5,NA +63478,7,2,1,62,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,22184.040999,24922.402846,2,94,3,3,1.01,1,1,0,0,1,1,62,1,3,3,NA +63479,7,2,2,19,NA,4,4,1,19,235,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,18163.985724,18749.311901,2,101,1,1,0.16,4,1,0,0,0,2,21,1,4,5,NA +63480,7,2,2,9,NA,1,1,1,9,117,NA,NA,1,1,NA,3,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,10870.942302,10985.231575,2,103,5,5,0.89,5,5,1,3,0,2,34,2,1,99,NA +63481,7,2,2,48,NA,2,2,2,NA,NA,2,NA,2,2,3,NA,3,1,NA,2,2,2,2,2,2,1,2,2,2,33737.181071,40665.783943,2,91,4,4,0.76,4,4,1,0,0,2,25,2,4,77,NA +63482,7,2,2,43,NA,4,4,2,NA,NA,2,NA,2,1,6,NA,4,1,2,1,2,2,1,2,2,NA,NA,NA,NA,22513.236051,21981.065205,1,91,10,10,2.56,5,5,0,3,0,1,51,2,5,1,4 +63483,7,2,1,2,NA,1,1,1,2,35,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14810.484787,14830.497242,1,92,10,10,3.04,4,4,2,0,0,2,37,2,5,1,5 +63484,7,2,1,69,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,95193.424282,96086.209653,1,100,5,5,2.15,1,1,0,0,1,1,69,1,5,3,NA +63485,7,2,1,42,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,18668.895165,18966.875509,1,96,13,13,NA,5,5,1,1,0,1,42,1,3,5,NA +63486,7,2,2,11,NA,2,2,2,11,134,NA,NA,2,1,4,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15583.587534,16935.930722,1,93,15,15,5,4,4,0,2,0,1,50,1,5,1,5 +63487,7,2,1,17,NA,4,4,1,17,208,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12972.249316,12937.057154,1,100,15,15,3.7,5,5,0,3,0,1,51,1,5,1,5 +63488,7,2,2,6,NA,4,4,1,6,78,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9309.947844,9654.826166,2,98,14,14,3.36,4,4,0,2,0,1,37,1,4,1,4 +63489,7,2,1,32,NA,3,3,1,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,85455.763827,87903.260844,2,92,10,10,4.89,2,2,0,0,0,2,34,2,5,1,5 +63490,7,2,2,11,NA,3,3,1,11,140,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,58636.069237,60514.266203,1,100,6,6,1.18,5,5,2,2,0,2,40,1,5,3,NA +63491,7,2,1,56,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,146951.437687,151959.13798,1,98,15,15,5,3,3,0,0,0,1,56,1,5,1,5 +63492,7,1,1,69,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,7101.739553,0,2,100,3,3,0.92,1,1,0,0,1,1,69,1,2,3,NA +63493,7,2,2,65,NA,5,6,2,NA,NA,2,NA,2,2,2,NA,3,1,NA,1,2,1,1,2,2,1,2,1,3,14388.729229,15167.035829,1,90,2,2,0.33,2,2,0,0,2,2,65,2,3,1,5 +63494,7,2,2,0,2,4,4,1,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5099.47985,5303.483608,1,100,9,9,1.78,6,6,1,1,0,2,45,2,3,1,3 +63495,7,2,2,14,NA,5,7,1,14,170,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11419.438939,11635.655291,2,103,7,7,1.55,5,5,2,2,0,2,31,1,4,3,NA +63496,7,2,1,58,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,124170.603852,125419.736085,2,98,6,6,2.57,1,1,0,0,0,1,58,1,3,3,NA +63497,7,2,2,1,21,2,2,2,NA,22,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10047.902864,11093.154402,1,90,3,3,0.43,4,4,2,0,0,1,31,1,3,6,NA +63498,7,2,2,70,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,20131.904783,23186.488493,2,98,6,6,3.01,1,1,0,0,1,2,70,1,3,2,NA +63499,7,2,2,33,NA,2,2,1,NA,NA,2,NA,2,2,5,NA,1,6,2,2,2,2,2,2,2,2,2,2,2,38218.668882,37878.487888,2,102,8,8,1.09,7,7,1,3,0,2,33,2,1,6,NA +63500,7,2,1,53,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,15001.445077,15740.201709,2,99,7,7,1.63,4,4,0,2,0,1,53,1,3,3,NA +63501,7,1,2,4,NA,1,1,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13366.393396,0,3,92,8,8,2.01,4,4,1,0,0,2,49,2,5,4,NA +63502,7,2,1,73,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,11245.778093,11672.431186,1,98,5,5,1.59,2,2,0,0,2,1,73,1,2,1,5 +63503,7,2,2,3,NA,3,3,1,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,52983.056893,55223.723565,3,91,15,15,5,6,6,1,3,0,2,40,1,5,1,5 +63504,7,2,1,54,NA,1,1,1,NA,NA,2,NA,2,1,7,NA,1,1,NA,1,2,2,1,2,2,1,2,2,2,33162.406014,34847.152396,3,92,10,10,4.3,5,2,2,1,1,2,68,1,3,1,1 +63505,7,2,2,0,1,3,3,1,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,23207.538828,22577.170535,1,94,9,9,2.88,3,3,1,0,0,2,28,1,4,1,4 +63506,7,2,2,60,NA,2,2,2,NA,NA,2,NA,2,2,6,NA,1,4,NA,2,2,2,2,2,2,1,2,2,2,9716.805546,10308.451947,2,90,5,5,1.19,3,3,1,0,1,2,60,2,1,4,NA +63507,7,2,2,61,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,1,8308.628726,9015.10987,2,95,3,3,1.31,1,1,0,0,1,2,61,1,2,2,NA +63508,7,2,2,34,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,4,2,1,2,2,1,2,2,1,2,2,1,21340.150623,22501.62641,2,95,4,4,1.19,2,2,0,0,0,2,34,1,4,4,NA +63509,7,2,1,20,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,104488.914565,106745.836574,1,98,3,2,0.54,4,1,0,0,0,1,20,1,4,5,NA +63510,7,2,2,56,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,196995.351093,199029.909449,1,91,15,15,5,2,2,0,0,0,2,56,1,4,1,4 +63511,7,2,1,1,17,3,3,2,NA,19,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,24594.444896,28818.16319,1,98,4,4,0.66,4,4,2,0,0,2,22,1,4,6,NA +63512,7,2,1,64,NA,2,2,1,NA,NA,2,NA,2,2,5,NA,1,1,NA,2,2,2,2,2,2,2,2,2,2,11019.434708,12461.093856,3,91,4,4,0.81,3,3,0,0,1,1,64,2,1,1,1 +63513,7,1,1,17,NA,4,4,NA,NA,NA,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,NA,NA,NA,NA,15360.522091,0,1,98,15,15,5,4,4,0,2,0,2,50,1,5,1,5 +63514,7,2,2,80,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,13399.379222,14870.161708,2,90,4,4,1.2,2,2,0,0,2,2,80,1,3,2,NA +63515,7,2,2,54,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,220233.315202,222507.874115,1,98,14,14,5,2,2,0,0,0,1,59,1,3,1,4 +63516,7,2,2,54,NA,2,2,1,NA,NA,2,NA,2,2,6,NA,1,4,NA,2,2,2,1,2,2,2,2,2,2,22632.809716,22750.837894,1,103,3,3,0.79,2,2,0,0,0,2,54,2,1,4,NA +63517,7,2,1,10,NA,5,7,1,10,123,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7101.095162,7528.512272,2,96,15,15,5,3,3,0,2,0,2,42,2,5,4,NA +63518,7,2,2,3,NA,1,1,2,3,39,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13366.393396,13935.903375,2,94,6,6,1.15,5,5,1,2,0,1,33,1,2,1,2 +63519,7,2,1,54,NA,4,4,2,NA,NA,2,NA,2,1,7,NA,5,4,NA,1,2,2,1,2,2,1,2,2,1,16117.991297,16620.832307,1,96,9,9,2.78,4,4,0,2,0,1,54,2,5,4,NA +63520,7,2,2,0,0,3,3,1,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,21671.775435,21083.121886,1,98,15,15,4.77,4,4,2,0,0,1,35,1,4,1,5 +63521,7,2,2,15,NA,5,6,2,15,183,NA,NA,2,1,4,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8424.942002,9162.575745,2,94,15,15,5,3,3,0,1,0,1,50,1,2,1,4 +63522,7,2,1,6,NA,4,4,2,6,82,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8579.422451,8987.382625,1,99,3,3,0.75,2,2,0,1,0,2,41,1,5,77,NA +63523,7,2,2,22,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,128171.594518,135937.909642,1,93,14,7,3.95,2,1,0,0,0,2,26,1,5,5,NA +63524,7,2,2,70,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,24072.616069,27614.797496,1,100,4,4,1.16,2,2,0,0,2,1,73,1,3,1,3 +63525,7,1,2,52,NA,5,6,NA,NA,NA,2,NA,2,2,4,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,12649.084278,0,3,90,77,77,NA,3,3,0,0,0,1,56,NA,NA,1,5 +63526,7,2,2,9,NA,3,3,1,9,114,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,51531.402068,50847.086518,1,94,14,14,2.96,5,5,0,3,0,2,39,1,4,1,3 +63527,7,2,2,11,NA,1,1,1,11,140,NA,NA,1,1,NA,4,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,12215.503444,12532.555214,1,102,5,5,0.92,5,5,0,3,0,2,39,2,3,1,3 +63528,7,2,2,34,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,43717.124878,44415.60038,2,101,6,6,1.54,3,3,0,1,0,2,34,1,4,1,3 +63529,7,2,1,23,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,31962.323978,33458.586112,1,100,4,4,1.06,3,2,0,0,0,1,22,1,4,6,NA +63530,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,28483.117096,31921.002992,1,94,3,3,0.39,6,6,1,0,2,1,80,1,4,1,3 +63531,7,2,1,32,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,1,6,NA,2,2,2,1,2,2,1,2,2,2,54969.430704,54554.559034,1,100,NA,13,NA,2,1,0,0,0,1,32,2,1,6,NA +63532,7,2,1,54,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,4,NA,1,2,2,1,2,2,1,2,2,1,19752.546483,23704.421997,1,102,12,12,NA,7,7,3,2,0,2,52,1,4,5,NA +63533,7,2,2,32,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,6,3,1,2,2,1,2,2,1,2,2,1,41791.57979,40949.069487,2,102,15,12,NA,5,4,0,3,0,1,42,2,4,6,NA +63534,7,2,1,39,NA,2,2,1,NA,NA,2,NA,2,1,6,NA,3,1,NA,2,2,2,2,2,2,NA,NA,NA,NA,43108.74283,42783.38752,2,91,8,8,1.85,5,5,0,2,1,1,39,2,3,1,4 +63535,7,2,2,3,NA,2,2,2,4,49,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9793.360626,10410.766193,3,90,15,15,4.2,6,6,1,0,2,1,60,1,5,1,4 +63536,7,2,1,0,0,3,3,2,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12105.109893,11778.058179,1,95,6,6,0.83,7,6,2,1,0,1,43,1,4,1,4 +63537,7,2,1,1,19,5,6,2,NA,19,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5492.796032,5818.035599,2,100,4,4,0.5,6,6,2,1,0,1,30,2,4,1,3 +63538,7,2,2,62,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,16519.058735,17573.900053,1,97,77,77,NA,3,3,0,0,3,2,62,1,5,1,NA +63539,7,2,1,14,NA,1,1,1,14,173,NA,NA,2,2,2,8,NA,NA,NA,2,1,2,1,2,2,1,2,2,2,30061.88611,30025.949584,1,92,5,5,0.87,4,4,0,2,0,1,42,2,1,1,4 +63540,7,2,2,57,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,27944.169354,28022.783308,2,94,3,3,1.24,1,1,0,0,0,2,57,1,2,3,NA +63541,7,2,1,70,NA,2,2,2,NA,NA,2,NA,2,1,7,NA,1,1,NA,2,2,2,1,2,2,1,2,2,NA,11755.776731,15354.199056,3,90,12,12,NA,6,6,0,0,2,1,70,2,1,1,1 +63542,7,2,2,2,NA,3,3,2,2,28,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14718.567269,15747.930582,2,97,3,3,0.43,6,6,1,3,0,2,36,2,4,3,NA +63543,7,2,2,74,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,5,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,13446.397433,13865.38304,1,93,13,13,NA,2,2,0,0,2,1,76,2,5,1,5 +63544,7,2,1,63,NA,2,2,2,NA,NA,2,NA,2,2,7,NA,4,1,NA,2,2,2,2,2,2,1,2,2,2,9357.880765,9682.593718,2,90,10,10,2,7,7,0,3,1,1,63,2,4,1,NA +63545,7,2,2,56,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,19319.908753,18964.846355,1,96,15,15,5,2,2,0,0,0,1,56,1,5,1,5 +63546,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,30212.098573,35047.752261,2,98,3,3,1.1,1,1,0,0,1,2,80,1,1,2,NA +63547,7,2,1,0,4,4,4,2,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5825.739712,6022.371944,1,99,2,2,0.43,3,3,2,0,0,2,26,1,4,5,NA +63548,7,2,2,0,10,3,3,2,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9189.424641,8939.81946,1,98,6,6,1.65,2,2,1,0,0,2,24,1,3,4,NA +63549,7,2,2,5,NA,4,4,2,5,71,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9404.475744,9924.78953,1,96,14,14,2.58,6,6,2,2,0,1,40,2,4,1,4 +63550,7,2,2,51,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,14834.928147,19579.353906,1,103,2,2,0.53,2,2,0,1,0,2,51,1,3,5,NA +63551,7,2,2,54,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,109027.902363,130159.069706,2,103,15,15,3.44,7,7,0,1,2,2,79,1,3,2,NA +63552,7,2,1,50,NA,2,2,1,NA,NA,2,NA,2,2,7,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,23431.677775,23884.31716,2,93,8,8,2,4,4,1,1,0,1,50,2,4,1,4 +63553,7,2,1,76,NA,4,4,2,NA,NA,2,NA,2,1,7,NA,3,3,NA,1,2,2,1,2,2,1,2,2,NA,8155.039267,8917.162886,3,90,99,99,NA,2,2,0,0,1,1,76,2,3,3,NA +63554,7,2,1,61,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,8895.639271,8965.223759,1,96,15,15,5,2,2,0,0,2,1,61,1,5,1,5 +63555,7,2,1,6,NA,2,2,1,6,76,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13898.598114,14013.214919,2,102,14,14,2.44,7,7,0,2,1,2,71,1,3,3,NA +63556,7,2,1,64,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,9082.311855,9548.677283,1,96,7,7,2.64,2,2,0,0,2,1,64,2,5,1,5 +63557,7,2,1,3,NA,5,7,2,3,40,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8981.553859,10073.795326,3,91,15,15,5,3,3,1,0,0,2,39,2,5,1,5 +63558,7,2,2,18,NA,3,3,2,19,228,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,99340.784743,108314.70799,2,94,12,12,NA,5,5,1,1,0,1,37,1,4,1,3 +63559,7,2,1,41,NA,5,6,2,NA,NA,2,NA,2,1,8,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,19184.316833,20543.822351,1,97,15,15,4.77,4,4,1,1,0,1,41,2,4,1,5 +63560,7,2,1,40,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,116464.874823,116165.700541,2,94,7,7,1.17,6,6,0,3,0,1,40,1,3,1,5 +63561,7,1,2,65,NA,2,2,NA,NA,NA,2,NA,2,2,6,NA,1,1,NA,2,2,2,1,2,2,NA,NA,NA,NA,10938.831279,0,1,93,6,6,1.55,3,3,0,0,3,1,61,2,4,1,1 +63562,7,2,1,22,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,43892.276067,44574.41704,1,98,6,1,0,2,1,0,0,0,1,29,1,4,5,NA +63563,7,2,1,16,NA,4,4,2,16,196,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,10817.360862,11313.215634,2,99,99,99,NA,5,5,0,2,0,2,20,1,3,6,NA +63564,7,1,2,80,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,65706.229298,0,1,101,10,10,4.3,2,2,0,0,2,1,80,1,2,1,4 +63565,7,2,2,4,NA,1,1,1,4,52,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12280.58152,13558.091553,2,92,14,14,4.03,4,4,1,1,1,2,30,1,5,4,NA +63566,7,2,2,62,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,14809.997435,16069.288743,2,101,13,3,0.64,5,4,0,3,1,2,62,1,1,2,NA +63567,7,2,2,9,NA,5,7,2,9,115,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10699.45895,11230.540406,1,97,8,8,2.51,3,3,0,2,0,2,39,2,4,2,NA +63568,7,2,1,19,NA,4,4,1,19,235,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12792.875152,12871.476461,2,93,99,99,NA,7,6,1,0,0,1,19,1,3,NA,NA +63569,7,2,2,49,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,2,2,2,1,2,2,NA,NA,NA,NA,25778.164795,26907.837256,2,90,77,77,NA,3,3,0,0,0,2,49,1,2,5,NA +63570,7,1,1,71,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,17780.584319,0,1,97,3,3,1.16,1,1,0,0,1,1,71,1,2,3,NA +63571,7,2,1,36,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,12031.037329,12793.158379,1,99,10,10,3.99,3,3,0,1,0,1,36,2,2,6,NA +63572,7,2,2,28,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,81857.569857,83650.947594,2,92,15,7,3.67,4,1,0,0,0,1,28,1,5,5,NA +63573,7,2,2,20,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,22154.886709,21259.816918,1,96,7,7,2.31,2,2,0,0,1,2,62,1,3,3,NA +63574,7,2,1,6,NA,5,6,2,6,78,NA,NA,1,1,NA,1,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,5399.929397,5851.470272,3,91,15,15,5,3,3,0,1,0,2,40,2,5,1,5 +63575,7,2,1,19,NA,5,6,2,19,233,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,6999.347953,7445.743611,3,90,9,9,2.6,4,4,0,0,1,1,62,2,4,1,5 +63576,7,2,1,46,NA,2,2,2,NA,NA,2,NA,2,1,5,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,39244.104141,38781.831565,1,90,15,15,5,4,4,1,1,0,2,40,1,5,6,NA +63577,7,2,2,5,NA,1,1,1,5,68,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12714.663639,13256.404976,1,102,4,4,0.5,6,6,2,2,0,1,25,1,2,1,3 +63578,7,2,2,41,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,2,1,2,2,1,2,2,1,2,2,1,17754.413992,17268.517878,2,99,6,6,1.11,5,5,1,2,0,2,41,1,2,5,NA +63579,7,2,1,63,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,120735.071461,122283.708051,1,94,8,8,2.41,3,3,0,0,3,1,63,1,4,1,5 +63580,7,2,1,9,NA,3,3,1,9,114,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,24713.905595,25821.327941,1,98,4,4,0.67,5,5,1,2,0,1,29,1,4,1,3 +63581,7,2,2,14,NA,5,6,1,14,173,NA,NA,1,1,NA,8,NA,NA,NA,1,1,1,1,2,1,1,2,2,1,5760.953091,5914.685125,2,92,8,8,1.91,5,5,0,2,1,2,47,2,1,1,3 +63582,7,2,2,57,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,33821.324425,34164.529253,3,92,4,3,0.52,5,4,0,0,0,2,57,1,4,1,2 +63583,7,2,1,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,38321.717684,40488.857872,1,95,15,15,5,2,2,0,0,2,2,80,1,4,1,4 +63584,7,2,2,30,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,33506.462855,33906.169633,2,96,3,3,0.38,5,5,1,2,0,2,30,1,3,5,NA +63585,7,2,2,8,NA,4,4,2,8,99,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7282.523598,8846.731146,2,99,5,5,0.76,5,5,0,2,0,1,51,1,2,1,2 +63586,7,2,1,4,NA,4,4,1,4,56,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11342.022131,11810.675983,2,102,4,4,0.53,6,6,2,2,0,2,27,1,2,1,2 +63587,7,2,1,36,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,69063.138927,71041.142737,1,92,8,8,1.45,6,6,1,3,0,1,36,1,3,1,4 +63588,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,41229.806244,46206.205733,1,103,6,6,1.98,2,2,0,0,2,1,80,1,5,1,4 +63589,7,2,1,80,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,1,1,NA,1,2,2,1,2,1,1,2,2,NA,12882.868646,13921.030537,2,92,77,77,NA,5,5,0,1,2,2,80,NA,NA,1,1 +63590,7,2,1,21,NA,4,4,2,NA,NA,2,NA,2,1,5,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,21495.752024,21074.130073,1,91,15,15,5,6,6,1,2,0,2,42,2,5,1,5 +63591,7,2,2,19,NA,5,6,1,19,236,2,NA,2,2,1,13,NA,NA,NA,1,2,1,1,2,1,1,2,2,NA,6145.01663,6308.997467,2,101,12,1,0,5,1,0,0,0,2,19,2,3,NA,NA +63592,7,2,2,2,NA,4,4,2,2,33,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6276.300496,6799.229858,2,99,1,1,0.1,6,6,2,3,0,2,31,1,2,5,NA +63593,7,2,1,77,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,73144.179917,78844.986335,2,91,77,77,NA,2,2,0,0,2,2,70,1,3,1,4 +63594,7,2,1,2,NA,4,4,2,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5256.453918,5473.651288,1,99,5,5,0.84,5,5,2,1,0,1,35,1,3,1,2 +63595,7,2,2,27,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,3,1,2,1,2,1,1,2,1,NA,NA,NA,NA,8044.549611,8388.06604,2,92,10,6,1.12,7,4,1,1,1,2,27,2,3,1,3 +63596,7,2,1,74,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,15470.980685,17519.370244,1,91,7,7,3.58,1,1,0,0,1,1,74,1,2,1,NA +63597,7,2,1,22,NA,5,6,1,NA,NA,2,NA,2,2,1,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,14385.653726,15564.966804,2,101,14,8,4.59,2,1,0,0,0,1,22,2,4,5,NA +63598,7,2,2,18,NA,2,2,2,18,223,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,16189.692833,16766.382859,1,93,15,15,2.96,7,7,0,1,1,2,18,1,2,NA,NA +63599,7,1,2,76,NA,2,2,NA,NA,NA,2,NA,2,1,8,NA,1,1,NA,2,2,2,2,2,2,NA,NA,NA,NA,18241.877822,0,2,93,7,7,2.31,2,2,0,0,2,1,80,2,1,1,1 +63600,7,2,2,10,NA,3,3,1,10,128,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,51093.739991,50940.240166,2,102,14,14,3.44,5,5,1,2,0,2,34,1,4,6,NA +63601,7,2,1,5,NA,3,3,1,6,73,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,NA,NA,NA,NA,NA,NA,NA,50644.672852,56040.796491,2,100,NA,NA,NA,5,5,1,2,0,1,36,NA,NA,3,NA +63602,7,2,1,34,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,18838.303827,19546.605226,2,93,5,5,1.05,3,3,1,0,0,2,29,1,3,5,NA +63603,7,2,1,11,NA,1,1,1,11,141,NA,NA,1,1,NA,5,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,13533.281742,14131.961026,1,100,7,7,1.74,4,4,0,2,0,2,39,2,1,1,3 +63604,7,2,2,2,NA,1,1,1,2,26,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11414.885224,11778.085279,1,94,7,7,1.56,4,4,2,0,0,1,21,1,4,1,4 +63605,7,2,1,7,NA,4,4,2,7,86,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9502.15317,9484.287948,2,97,3,3,0.4,6,6,2,3,0,2,25,1,2,5,NA +63606,7,2,1,6,NA,3,3,1,6,76,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,24713.905595,25821.327941,1,98,4,4,0.67,5,5,1,2,0,1,29,1,4,1,3 +63607,7,2,1,41,NA,1,1,2,NA,NA,2,NA,2,1,6,NA,2,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,36273.943099,35741.678901,1,90,15,15,4.77,4,4,1,1,0,2,41,1,5,1,2 +63608,7,2,2,71,NA,2,2,1,NA,NA,2,NA,2,1,8,NA,1,4,NA,2,2,2,1,2,2,2,2,1,NA,12972.932238,13949.32349,2,93,6,6,0.98,5,5,0,2,1,1,48,2,5,1,5 +63609,7,2,1,66,NA,5,7,1,NA,NA,2,NA,2,1,6,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,23761.280382,24066.059994,2,103,5,5,1.2,3,3,0,0,2,1,66,2,2,1,2 +63610,7,2,1,16,NA,4,4,2,16,195,NA,NA,2,2,4,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11523.287163,11546.069645,1,96,8,8,2.17,4,4,0,2,0,2,45,2,5,4,NA +63611,7,2,1,80,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,2,1,NA,1,1,2,1,2,2,1,2,2,NA,20944.990388,22567.358502,2,95,6,6,1.57,3,3,0,0,2,1,80,1,2,1,4 +63612,7,1,1,5,NA,5,7,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8006.699948,0,1,90,15,15,5,3,3,1,0,0,1,42,1,5,1,5 +63613,7,2,1,30,NA,2,2,2,NA,NA,2,NA,2,1,6,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,40219.06806,40845.122132,1,93,9,9,3.98,3,2,0,0,0,2,27,1,3,1,4 +63614,7,2,2,58,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,32144.824104,32969.273278,2,97,2,2,0.77,1,1,0,0,0,2,58,1,2,3,NA +63615,7,2,2,26,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,128171.594518,135937.909642,1,93,14,9,5,2,1,0,0,0,2,26,1,5,5,NA +63616,7,2,1,9,NA,5,6,2,9,115,NA,NA,2,1,3,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6026.102306,6805.584778,2,95,6,6,1.08,4,4,1,1,0,1,39,1,4,1,4 +63617,7,2,1,29,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,90303.174138,94631.352733,2,92,15,8,4.59,2,1,0,0,0,2,29,1,5,1,NA +63618,7,2,2,2,NA,5,6,1,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6024.192029,6555.678695,2,103,15,15,5,3,3,1,0,0,1,35,1,9,1,5 +63619,7,2,1,1,21,3,3,1,NA,22,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,53040.637714,62149.552868,3,91,8,8,1.95,4,4,2,0,0,2,30,1,5,1,4 +63620,7,2,1,61,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,14113.631895,14272.623174,1,92,9,9,3.97,2,2,0,0,1,2,59,1,5,1,4 +63621,7,2,2,61,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,129999.035519,129559.2554,1,98,14,14,4.96,2,2,0,0,2,1,71,1,5,1,5 +63622,7,2,1,18,NA,3,3,2,18,222,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,88448.252445,87285.839384,1,95,9,9,3.24,3,3,0,0,0,2,42,1,4,3,NA +63623,7,2,1,80,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,20611.860643,21777.486671,1,99,5,5,2.02,1,1,0,0,1,1,80,1,5,2,NA +63624,7,2,2,7,NA,1,1,1,7,90,NA,NA,2,2,3,1,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,13616.85154,14798.521446,1,102,6,6,1.73,3,3,0,1,0,1,30,2,5,1,4 +63625,7,2,2,23,NA,1,1,1,NA,NA,2,NA,2,1,6,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,50915.06085,54078.415833,3,92,2,2,0.4,3,3,1,0,0,1,21,1,2,6,NA +63626,7,2,2,39,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,58826.425292,59007.297053,1,102,8,8,1.6,7,7,0,4,0,2,39,1,4,1,4 +63627,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,56180.550638,62747.143757,2,98,8,8,3.4,2,2,0,0,2,1,80,1,4,1,4 +63628,7,1,1,61,NA,3,3,NA,NA,NA,1,2,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,125558.167126,0,3,91,12,5,2.02,2,1,0,0,1,1,61,1,3,3,NA +63629,7,2,2,36,NA,5,6,2,NA,NA,2,NA,2,2,4,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,15542.93857,15828.161907,3,91,7,7,2.16,3,3,1,0,1,2,36,2,5,1,NA +63630,7,2,2,11,NA,3,3,1,11,141,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,41020.258665,40851.726244,1,103,15,15,5,2,2,0,1,0,1,49,1,5,77,NA +63631,7,2,2,32,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,85610.546667,92292.669073,2,91,15,15,5,4,4,2,0,0,1,35,1,5,1,5 +63632,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,65891.955175,73297.270697,1,95,7,7,2.72,2,2,0,0,2,1,80,1,3,1,3 +63633,7,2,1,48,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,13232.135,13189.930654,2,99,15,15,4.9,7,7,1,4,0,2,53,1,5,1,5 +63634,7,2,1,4,NA,4,4,2,4,53,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8890.779467,9258.147648,3,91,1,1,0.07,6,6,2,3,0,2,30,1,2,3,NA +63635,7,2,1,79,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,1,2,NA,55241.951079,58472.387275,2,93,7,7,2.31,2,2,0,0,2,2,79,1,3,1,5 +63636,7,2,1,17,NA,4,4,2,17,204,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11093.269222,11505.803928,2,99,3,3,0.44,5,5,1,1,0,2,53,1,4,1,3 +63637,7,2,1,7,NA,3,3,2,7,92,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,74331.764009,78594.005469,2,91,15,15,5,3,3,0,2,0,1,44,2,5,3,NA +63638,7,2,2,47,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,125007.681473,127469.032295,1,92,10,10,3.4,3,3,0,0,0,1,56,1,4,1,5 +63639,7,2,1,55,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,16970.447459,16981.184092,1,99,8,8,1.99,5,5,1,0,0,1,55,1,5,1,2 +63640,7,2,1,0,1,3,3,2,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6420.20398,6662.903304,2,97,3,3,0.33,6,6,2,0,0,2,22,2,4,1,3 +63641,7,2,1,12,NA,3,3,1,12,146,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,81241.067732,81008.266507,2,102,14,14,3.44,5,5,1,2,0,2,34,1,4,6,NA +63642,7,2,1,25,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,20759.115219,21340.685849,1,93,2,2,0.32,3,3,0,1,0,1,25,1,3,6,NA +63643,7,2,2,18,NA,3,3,1,18,223,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,71832.578284,75129.017547,1,92,10,10,2.1,6,6,1,1,0,2,29,1,4,1,2 +63644,7,2,2,2,NA,4,4,1,2,29,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8010.447273,8217.210509,2,93,7,7,2.58,2,2,1,0,0,2,32,1,5,5,NA +63645,7,2,1,15,NA,5,7,2,15,185,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13693.32264,13720.395459,1,96,5,5,1.45,2,2,0,1,0,2,41,1,4,3,NA +63646,7,1,1,9,NA,1,1,NA,NA,NA,NA,NA,1,1,NA,2,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,13822.148996,0,2,94,5,5,0.65,6,6,0,2,0,1,53,NA,NA,6,NA +63647,7,2,2,2,NA,4,4,2,2,28,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5158.14785,5587.91487,3,90,99,99,NA,5,5,1,1,1,2,63,1,3,2,NA +63648,7,2,2,31,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,71034.153987,71525.773464,1,101,7,7,1.55,5,5,1,2,0,2,31,1,4,1,2 +63649,7,2,1,1,21,3,3,2,NA,23,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,38636.988369,42311.269327,1,91,15,15,4.59,4,4,2,0,0,1,35,1,5,1,5 +63650,7,2,2,62,NA,1,1,1,NA,NA,2,NA,2,7,77,NA,1,1,NA,2,2,2,1,2,2,NA,NA,NA,NA,7863.861726,8261.011593,1,102,13,13,NA,7,7,3,1,2,2,62,2,1,1,2 +63651,7,2,2,76,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,1,1,NA,1,2,1,1,2,2,1,2,1,NA,13446.397433,13865.38304,1,93,3,3,0.82,2,2,0,0,2,1,80,2,5,1,1 +63652,7,2,1,28,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,1,2,1,2,2,1,1,2,NA,16995.648055,19983.260181,1,96,12,12,NA,7,7,1,0,1,2,59,1,3,1,1 +63653,7,2,2,19,NA,2,2,1,19,229,2,NA,2,2,3,12,NA,NA,NA,2,2,2,1,2,2,2,2,1,2,12712.538972,12956.930724,2,93,4,4,0.56,5,5,0,0,0,2,49,2,2,5,NA +63654,7,2,1,11,NA,2,2,2,11,136,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9807.589376,10028.771,2,90,7,7,1.66,4,4,0,3,0,2,34,1,5,3,NA +63655,7,2,2,17,NA,3,3,2,17,209,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,97212.131473,101229.4133,1,91,15,15,5,3,3,0,1,0,1,52,NA,NA,1,5 +63656,7,2,2,16,NA,4,4,2,16,203,NA,NA,1,1,NA,8,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,7825.55935,7975.961244,3,90,3,3,0.37,5,5,2,2,0,2,36,2,4,4,NA +63657,7,2,1,30,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,21280.199633,23174.199432,1,97,14,14,4.5,3,3,1,0,0,1,30,1,5,1,5 +63658,7,2,1,10,NA,3,3,1,10,124,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,71470.369236,87471.572436,2,101,8,8,2.81,3,3,0,2,0,1,48,1,3,3,NA +63659,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,36810.071228,39501.597518,1,95,14,14,5,1,1,0,0,1,1,80,1,3,2,NA +63660,7,2,1,11,NA,3,3,1,12,144,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,20080.431771,20654.625485,1,94,4,4,1,3,3,0,1,0,2,41,1,4,5,NA +63661,7,2,2,46,NA,3,3,1,NA,NA,2,NA,2,1,4,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,30747.096519,32457.841726,2,91,2,2,0.44,3,3,0,1,0,1,46,2,3,1,4 +63662,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,33707.673642,36318.620408,2,95,10,10,4.3,2,2,0,0,2,1,80,1,5,1,4 +63663,7,2,2,42,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,1,4,2,2,2,2,1,2,2,NA,NA,NA,NA,32208.300114,32376.263659,1,102,4,4,0.67,4,4,0,1,0,1,23,2,4,5,NA +63664,7,2,1,58,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,18916.732604,18939.145414,2,91,9,9,5,1,1,0,0,0,1,58,1,5,3,NA +63665,7,2,1,56,NA,2,2,1,NA,NA,2,NA,2,1,7,NA,3,5,NA,2,2,2,1,2,2,2,2,1,2,23431.677775,27795.676997,2,93,14,14,2.91,6,6,2,0,1,2,74,NA,NA,2,NA +63666,7,2,2,79,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,30880.887565,31700.101057,1,98,3,3,1.12,1,1,0,0,1,2,79,1,3,2,NA +63667,7,2,2,2,NA,3,3,2,2,28,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,36506.435703,36986.142564,1,98,9,9,2.6,4,4,1,1,0,1,31,1,4,1,5 +63668,7,2,1,4,NA,1,1,1,5,60,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14716.463544,14890.443704,2,96,5,5,0.76,5,5,1,2,0,1,44,2,1,1,3 +63669,7,2,1,31,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,87811.478076,90326.44396,1,90,8,8,1.67,5,5,2,1,0,2,28,1,4,1,5 +63670,7,2,2,8,NA,4,4,2,8,97,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7239.045424,7432.710238,1,99,7,7,1.06,7,7,3,1,0,1,38,1,4,6,NA +63671,7,1,2,14,NA,5,7,NA,NA,NA,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5268.765205,0,1,99,9,9,2.68,4,4,0,2,0,1,43,2,3,1,NA +63672,7,2,1,9,NA,2,2,2,9,112,NA,NA,1,1,NA,2,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,11567.189008,12721.148711,2,90,2,2,0.32,3,3,0,1,0,1,53,NA,NA,1,1 +63673,7,2,1,43,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,126789.52929,126463.833097,1,101,6,6,0.97,7,7,2,1,0,1,43,1,2,1,NA +63674,7,2,1,5,NA,5,6,2,5,67,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8253.750998,8652.000238,1,90,7,7,1.52,4,4,2,0,0,2,30,2,4,6,NA +63675,7,2,1,12,NA,3,3,2,12,155,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,101055.977672,102514.960722,1,90,15,15,5,4,4,0,2,0,1,44,1,5,1,5 +63676,7,2,1,2,NA,4,4,2,2,35,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5447.377416,6006.624362,2,90,15,15,5,4,4,1,1,0,1,53,2,5,1,5 +63677,7,2,2,2,NA,1,1,2,2,28,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13065.99844,14425.21291,1,95,6,6,1.37,3,3,1,1,0,2,28,1,4,5,NA +63678,7,2,2,22,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,2,5,2,1,2,2,2,2,2,1,2,2,1,32537.532358,33640.063825,2,90,1,1,0.22,3,3,0,1,0,2,48,2,2,5,NA +63679,7,2,1,0,11,3,3,2,NA,12,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,20370.716701,21140.779334,1,91,15,15,4.2,5,5,3,0,0,2,32,1,4,1,5 +63680,7,2,1,54,NA,1,1,2,NA,NA,2,NA,2,2,3,NA,1,1,NA,2,2,2,2,2,2,2,2,2,2,22446.308035,23586.645568,2,94,7,7,1.04,7,7,0,3,0,1,37,2,1,1,3 +63681,7,2,2,5,NA,3,3,2,5,70,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,59190.129038,61693.294338,2,91,15,15,5,5,5,2,1,0,2,40,1,5,1,5 +63682,7,2,1,14,NA,3,3,2,14,176,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,77169.155154,77548.231618,1,101,14,14,3.9,4,4,0,2,0,2,41,1,2,1,2 +63683,7,2,1,53,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,29181.414565,29257.589647,1,94,3,3,0.39,6,6,1,0,2,1,80,1,4,1,3 +63684,7,2,2,54,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,17364.980275,22918.553497,2,93,7,7,2.78,2,2,0,1,0,2,54,1,4,3,NA +63685,7,2,2,60,NA,2,2,1,NA,NA,2,NA,2,2,5,NA,4,1,NA,2,2,2,1,2,2,2,2,2,2,12437.053229,13000.378144,3,91,5,5,0.89,4,4,0,2,2,1,61,2,3,1,4 +63686,7,2,2,60,NA,2,2,1,NA,NA,2,NA,2,1,9,NA,4,1,NA,1,2,2,NA,NA,NA,1,2,2,1,12237.578196,12748.319173,2,93,8,8,2.17,4,4,0,0,3,1,80,2,2,1,2 +63687,7,2,1,69,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,11761.359913,11893.852645,1,92,14,14,5,2,2,0,0,2,1,69,1,5,1,5 +63688,7,2,1,2,NA,5,6,2,2,25,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8253.750998,8652.000238,1,90,7,7,1.52,4,4,2,0,0,2,30,2,4,6,NA +63689,7,2,2,66,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,93265.413087,97732.118213,2,98,15,15,5,2,2,0,0,2,2,66,1,3,1,1 +63690,7,2,1,29,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,12971.121387,14034.473347,1,93,15,15,5,2,2,0,0,0,1,29,2,5,1,5 +63691,7,2,1,21,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,2,2,2,1,2,2,1,40899.412129,44211.773156,1,94,5,5,0.57,7,7,2,1,0,1,58,2,1,1,1 +63692,7,2,2,22,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,30275.274308,30259.77569,2,101,4,2,0.6,2,1,0,0,0,2,22,1,4,5,NA +63693,7,2,2,11,NA,1,1,1,11,137,NA,NA,1,1,NA,4,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,16986.005478,17421.337631,2,102,8,8,1.91,5,5,1,2,0,1,36,2,1,1,4 +63694,7,1,1,6,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,46081.129115,0,2,95,15,15,4.63,5,5,1,2,0,1,32,1,4,1,4 +63695,7,1,1,56,NA,4,4,NA,NA,NA,1,2,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,15599.953109,0,1,99,12,12,NA,1,1,0,0,0,1,56,1,3,5,NA +63696,7,2,1,15,NA,1,1,1,15,191,NA,NA,1,1,NA,8,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,18635.323223,18738.312717,1,103,5,5,0.74,5,5,1,1,0,2,40,99,3,1,1 +63697,7,2,1,41,NA,4,4,2,NA,NA,2,NA,2,1,5,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,17602.101156,18151.242681,1,96,10,10,2.95,4,4,0,1,0,2,34,2,3,1,5 +63698,7,2,1,42,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,1,5,NA,2,2,2,2,2,2,1,2,1,NA,34128.967046,33628.177065,2,93,3,3,0.87,2,2,0,0,1,2,65,2,4,3,NA +63699,7,2,2,47,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,18462.756377,18592.086302,1,99,6,6,1.46,3,3,0,0,1,2,80,NA,NA,2,NA +63700,7,2,1,40,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,4,NA,1,2,2,1,2,2,1,2,2,1,17602.101156,21123.738865,1,96,14,14,2.19,7,7,0,2,0,1,39,1,2,1,3 +63701,7,2,1,55,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,145790.86143,146040.776498,1,90,15,15,5,4,4,0,1,0,2,53,1,5,1,5 +63702,7,2,2,11,NA,3,3,1,11,136,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,56803.692074,58623.195384,1,100,15,15,5,4,4,0,2,0,2,47,1,5,1,5 +63703,7,2,2,2,24,4,4,1,2,24,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7382.686927,7791.142847,2,100,3,3,0.38,5,5,2,1,0,2,28,1,2,5,NA +63704,7,2,2,75,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,NA,14534.533756,15040.28544,1,96,12,12,NA,3,3,0,0,2,1,77,NA,NA,6,NA +63705,7,2,1,8,NA,2,2,2,8,101,NA,NA,1,1,NA,3,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,9807.589376,10786.008845,2,90,3,3,0.38,5,5,0,4,0,2,33,2,2,5,NA +63706,7,2,1,13,NA,3,3,1,13,157,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,28732.336483,28618.270464,3,92,7,7,0.81,7,7,2,4,0,1,40,NA,NA,1,4 +63707,7,2,2,63,NA,2,2,1,NA,NA,2,NA,2,1,8,NA,3,3,NA,1,2,2,1,2,2,1,2,2,2,9048.366564,9718.651548,2,93,9,9,4.92,1,1,0,0,1,2,63,2,3,3,NA +63708,7,2,1,63,NA,5,6,1,NA,NA,2,NA,2,1,8,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,13133.86792,13808.275718,2,102,8,8,1.72,5,5,0,2,1,1,63,2,5,1,5 +63709,7,2,2,16,NA,4,4,2,16,202,NA,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,10484.6104,10912.740054,2,99,1,1,0.07,4,4,1,1,0,2,24,1,2,5,NA +63710,7,2,1,37,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,94644.050918,104631.781207,2,91,15,15,5,5,5,1,2,0,1,37,1,4,6,NA +63711,7,1,2,7,NA,2,2,NA,NA,NA,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16442.636525,0,1,98,8,8,2.97,2,2,0,1,0,2,38,1,5,5,NA +63712,7,2,1,2,NA,3,3,2,2,25,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,21071.650532,24690.382982,2,97,6,6,1.16,4,4,1,1,0,1,27,2,4,1,3 +63713,7,2,1,52,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,127000.852889,126845.993399,2,92,15,15,5,2,1,0,0,0,1,52,1,5,6,NA +63714,7,2,1,48,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,87954.465296,88343.63479,2,97,15,15,4.97,5,5,1,0,0,1,48,1,4,1,3 +63715,7,2,2,8,NA,4,4,1,8,105,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12120.418061,13050.526646,2,101,3,3,0.65,3,3,0,1,0,2,54,1,3,5,NA +63716,7,2,1,2,NA,2,2,2,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,8331.647763,8430.145707,2,90,3,3,0.46,5,5,1,3,0,2,35,2,1,4,NA +63717,7,2,2,50,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,37070.062227,37637.166459,1,92,1,1,0.03,2,2,0,1,0,2,50,1,4,3,NA +63718,7,2,2,50,NA,2,2,2,NA,NA,2,NA,2,1,5,NA,3,2,NA,1,2,2,1,2,2,1,2,2,1,30543.825378,35038.368904,2,91,2,2,0.86,1,1,0,0,0,2,50,2,3,2,NA +63719,7,2,1,21,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,34099.599202,34629.549705,1,94,5,5,0.74,5,5,1,1,0,2,24,1,3,1,4 +63720,7,2,1,5,NA,1,1,1,5,62,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16775.083123,17973.290893,2,98,1,1,0.19,3,3,2,0,0,2,31,1,4,2,NA +63721,7,2,2,22,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,NA,NA,NA,1,2,2,1,118761.81384,121363.708734,1,94,8,8,2.43,3,3,0,0,0,2,46,1,3,1,NA +63722,7,1,1,35,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,NA,NA,NA,NA,NA,NA,NA,17371.064048,0,1,96,NA,NA,NA,4,4,1,1,0,2,37,NA,NA,1,4 +63723,7,2,2,62,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,14204.126838,15256.34028,3,92,5,5,1.56,2,2,0,0,1,1,58,1,3,1,2 +63724,7,2,1,33,NA,1,1,1,NA,NA,2,NA,2,2,3,NA,3,1,NA,2,2,2,2,2,2,NA,NA,NA,NA,51543.062078,51154.050295,3,92,3,3,0.52,5,5,2,1,0,2,29,2,1,1,3 +63725,7,2,1,5,NA,3,3,2,5,67,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,30883.231636,34843.624635,1,95,7,7,1.17,6,6,1,3,0,2,44,1,4,1,NA +63726,7,2,2,12,NA,2,2,2,12,147,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,21449.694498,22089.715913,1,98,3,3,0.4,7,7,2,3,0,2,31,2,5,1,2 +63727,7,2,2,4,NA,5,6,1,4,49,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5879.523197,6241.641704,2,91,15,15,4.63,7,7,1,2,0,1,36,2,4,1,3 +63728,7,2,2,11,NA,1,1,1,11,136,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,16986.005478,17733.622754,2,102,7,7,1.53,5,5,1,2,0,1,36,1,2,1,3 +63729,7,2,1,50,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,160904.289966,160708.090054,1,97,15,15,3.89,5,5,0,2,0,1,50,1,4,6,NA +63730,7,2,1,14,NA,3,3,1,14,170,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,71934.689876,71392.8162,1,100,15,15,5,5,5,0,3,0,1,47,1,5,1,5 +63731,7,2,1,51,NA,2,2,2,NA,NA,2,NA,2,2,77,NA,1,3,NA,2,2,2,2,2,2,NA,NA,NA,NA,24172.845721,24635.602694,2,99,1,1,0.03,2,2,0,0,0,1,51,2,1,3,NA +63732,7,2,1,60,NA,2,2,2,NA,NA,2,NA,2,1,8,NA,3,1,NA,1,2,2,1,2,2,1,2,2,2,5185.036848,5649.75477,2,90,7,7,0.89,7,7,1,3,3,1,60,2,3,1,3 +63733,7,2,2,58,NA,2,2,1,NA,NA,2,NA,2,1,7,NA,4,4,NA,1,2,2,1,2,2,1,2,2,1,23297.357076,24139.998866,2,93,9,9,2.6,4,4,0,0,0,2,58,2,4,4,NA +63734,7,2,1,43,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,32980.717958,32895.997285,1,95,2,2,0.6,1,1,0,0,0,1,43,1,4,3,NA +63735,7,2,1,29,NA,5,6,2,NA,NA,2,NA,2,2,1,NA,4,1,NA,1,2,1,1,2,2,NA,NA,NA,NA,14385.653726,15533.829525,2,101,5,3,1.1,2,1,0,0,0,1,29,2,4,1,NA +63736,7,2,1,36,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,30631.476666,31783.189579,2,101,6,6,1.54,3,3,0,1,0,2,34,1,4,1,3 +63737,7,2,1,8,NA,4,4,1,8,104,NA,NA,2,2,2,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11443.206518,12087.326286,1,100,9,9,1.78,6,6,1,1,0,2,45,2,3,1,3 +63738,7,2,1,46,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,19260.892847,19199.459573,2,97,5,5,0.76,5,5,0,0,0,2,50,1,4,5,NA +63739,7,2,2,71,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,12863.404053,17087.605763,2,90,2,2,0.31,5,5,0,2,1,2,71,1,2,2,NA +63740,7,2,1,8,NA,3,3,2,8,100,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,26349.460983,27598.763847,2,97,4,4,1.09,2,2,0,1,0,2,35,1,2,4,NA +63741,7,2,1,72,NA,1,1,1,NA,NA,1,2,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,NA,21815.897449,24704.366996,3,92,5,4,1.39,2,1,0,0,2,2,63,NA,NA,3,NA +63742,7,2,2,20,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,5,3,1,1,2,1,2,2,1,1,2,NA,87944.345504,91474.433025,2,98,10,10,3.78,3,3,0,0,0,1,53,1,3,1,4 +63743,7,2,2,9,NA,1,1,1,9,116,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15962.145468,16371.237244,2,98,14,14,4.05,3,3,0,1,0,1,38,1,3,1,4 +63744,7,2,2,50,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,196995.351093,202246.928022,1,91,15,15,5,3,3,0,1,0,1,52,NA,NA,1,5 +63745,7,2,1,0,4,1,1,1,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,1,2,NA,NA,NA,NA,7284.164858,7692.652584,2,98,5,5,0.76,5,5,3,1,0,2,27,1,3,4,NA +63746,7,2,1,49,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,28542.421068,29427.85637,2,101,2,2,0.73,1,1,0,0,0,1,49,1,3,5,NA +63747,7,2,1,4,NA,5,6,2,4,54,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,5953.107662,6129.253313,3,90,5,5,1.15,3,3,1,0,0,1,32,2,3,1,1 +63748,7,2,2,11,NA,2,2,1,11,141,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12307.832776,13375.906079,2,93,10,10,2.26,6,6,0,4,0,1,34,1,4,1,3 +63749,7,2,2,43,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,4,1,2,1,2,1,1,2,1,1,2,1,3,9145.761989,9194.124252,2,92,10,8,2.01,7,4,1,1,1,2,27,2,3,1,3 +63750,7,2,2,20,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,23845.8146,22808.13483,1,98,12,1,0.27,4,1,0,0,0,1,21,1,4,6,NA +63751,7,2,2,5,NA,1,1,1,5,66,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10493.785765,11155.348431,2,103,77,77,NA,5,5,1,2,0,2,30,1,2,1,2 +63752,7,2,1,60,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,25436.904729,28576.794771,1,94,3,3,1.25,1,1,0,0,1,1,60,1,3,3,NA +63753,7,2,1,33,NA,1,1,1,NA,NA,2,NA,2,2,3,NA,3,6,NA,2,2,2,2,2,2,2,2,2,2,34438.924452,34835.654759,1,100,8,3,0.68,6,3,1,0,0,1,33,2,3,6,NA +63754,7,2,2,46,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,99120.116925,102640.158973,2,98,15,15,5,4,4,0,2,0,2,46,1,4,1,NA +63755,7,2,1,2,NA,3,3,2,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,46257.816906,49754.984306,2,94,15,15,5,3,3,1,0,0,1,34,1,5,1,5 +63756,7,2,2,2,NA,4,4,1,2,30,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8754.193667,9543.319886,2,98,5,5,0.59,7,7,3,0,0,2,50,1,5,4,NA +63757,7,2,2,5,NA,2,2,2,5,67,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,8825.559072,9505.166523,2,90,6,6,0.66,7,7,2,2,0,2,24,2,4,6,NA +63758,7,2,1,28,NA,5,6,2,NA,NA,2,NA,2,2,5,NA,4,5,NA,1,2,2,1,2,2,1,2,2,3,11182.713216,11928.362428,2,90,99,4,1.38,3,1,0,0,2,1,60,NA,NA,1,NA +63759,7,2,1,56,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,90969.330762,95023.624595,1,99,14,14,4.86,3,3,0,1,0,1,56,1,5,1,5 +63760,7,2,1,16,NA,4,4,2,16,195,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13416.172328,13756.125082,1,96,7,7,1.39,5,5,0,2,2,1,69,2,2,1,2 +63761,7,2,2,21,NA,2,2,1,NA,NA,2,NA,2,1,2,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,40149.982555,39975.11173,2,103,7,7,2.64,2,2,0,0,0,2,21,2,3,1,3 +63762,7,2,1,23,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,34128.92969,36973.759081,1,92,5,5,1.15,3,3,1,0,0,1,23,1,4,1,4 +63763,7,2,2,17,NA,5,6,2,17,205,2,NA,2,1,4,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,7649.811754,7945.620413,2,90,6,6,1.24,4,4,0,1,0,1,57,2,5,1,3 +63764,7,2,2,14,NA,1,1,2,14,172,NA,NA,2,2,4,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18368.872199,18995.639955,2,94,12,12,NA,4,4,0,2,0,1,47,2,2,1,2 +63765,7,2,1,80,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,1,2,NA,1,1,2,1,2,2,1,1,2,NA,24952.423186,27719.90048,2,98,14,14,4.64,3,3,0,0,1,1,49,1,3,1,9 +63766,7,2,2,54,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,163102.567998,164787.083347,1,99,15,15,5,2,2,0,0,0,1,54,1,3,1,4 +63767,7,2,1,66,NA,1,1,1,NA,NA,2,NA,2,1,7,NA,1,6,NA,2,2,2,1,2,2,1,2,2,2,11019.434708,11290.181976,3,91,4,4,1.38,2,1,0,0,1,1,66,2,1,6,NA +63768,7,2,1,64,NA,2,2,2,NA,NA,2,NA,2,2,6,NA,2,1,NA,2,2,2,2,2,2,1,2,2,2,8609.250304,9380.869295,2,90,12,12,NA,3,3,0,0,2,2,61,2,3,4,NA +63769,7,2,1,44,NA,2,2,2,NA,NA,2,NA,2,1,3,NA,3,1,NA,1,2,2,1,2,2,2,2,2,2,37883.328863,38044.589557,1,93,15,15,2.96,7,7,0,1,1,2,18,1,2,NA,NA +63770,7,2,2,11,NA,4,4,1,12,144,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10422.423011,10751.577119,1,98,3,3,0.86,2,2,0,1,0,2,34,1,4,5,NA +63771,7,2,1,43,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,32719.762791,34306.488277,1,101,7,7,2.71,2,2,0,0,0,1,43,1,4,1,4 +63772,7,2,1,65,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,136843.962333,135447.112041,1,95,14,14,5,2,2,0,0,2,2,65,1,4,1,4 +63773,7,2,1,56,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,31302.008691,30991.200711,2,91,9,9,5,1,1,0,0,0,1,56,1,5,5,NA +63774,7,2,1,8,NA,3,3,1,8,104,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,62291.152254,66151.751642,3,92,6,6,1.17,4,4,0,2,0,2,30,1,2,1,4 +63775,7,2,2,1,22,5,6,2,NA,23,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4686.494502,4910.642079,1,90,14,14,3.33,5,5,1,2,0,1,41,1,5,1,5 +63776,7,2,1,7,NA,1,1,2,7,87,NA,NA,1,1,NA,2,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,16288.924956,19190.320193,1,101,5,5,0.51,7,7,0,3,2,1,75,2,1,1,1 +63777,7,2,2,41,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,5,2,1,2,2,1,2,2,1,2,2,1,30442.30641,30653.986309,1,95,77,77,NA,3,3,0,0,0,2,41,1,2,5,NA +63778,7,2,2,14,NA,4,4,1,14,171,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10972.028338,11002.546815,1,103,2,2,0.53,2,2,0,1,0,2,51,1,3,5,NA +63779,7,2,1,4,NA,4,4,2,4,55,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9488.600894,10206.6462,2,97,6,6,0.92,7,7,1,4,0,2,29,1,3,5,NA +63780,7,2,2,44,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,NA,NA,NA,NA,35126.205635,35295.519265,1,95,7,7,1.17,6,6,1,3,0,2,44,1,4,1,NA +63781,7,2,2,63,NA,2,2,1,NA,NA,2,NA,2,2,2,NA,4,6,NA,1,2,2,1,2,2,2,2,2,2,10680.068244,11125.805824,2,93,15,8,4.48,2,1,0,0,2,2,63,2,4,6,NA +63782,7,2,2,1,19,5,7,1,NA,20,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5899.406975,6347.827712,1,103,3,3,0.37,5,5,1,2,0,2,30,1,4,5,NA +63783,7,2,2,10,NA,4,4,1,10,130,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8930.342072,9169.253826,1,100,15,15,3.7,5,5,0,3,0,1,51,1,5,1,5 +63784,7,2,2,40,NA,1,1,1,NA,NA,2,NA,2,1,6,NA,4,1,2,2,2,2,2,2,2,NA,NA,NA,NA,34954.173075,36023.601038,3,92,9,9,2.46,4,4,0,2,0,1,43,2,3,1,4 +63785,7,1,2,32,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,3,1,3,1,2,2,1,2,2,NA,NA,NA,NA,86578.861495,0,2,101,8,8,1.72,5,5,0,3,0,1,37,1,3,1,3 +63786,7,2,1,8,NA,5,6,2,8,98,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6276.493588,6689.515302,1,98,15,15,5,4,4,1,1,0,1,40,NA,NA,1,5 +63787,7,2,1,30,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,18404.681357,22792.166915,1,95,6,6,0.81,6,6,2,2,0,1,30,1,3,1,4 +63788,7,2,2,40,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,3,2,1,2,2,1,2,2,1,2,2,1,123493.356057,126566.961964,1,102,3,3,0.92,1,1,0,0,0,2,40,1,3,3,NA +63789,7,1,1,29,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,84850.826285,0,3,90,15,15,5,2,1,0,0,0,1,29,1,5,1,NA +63790,7,2,1,11,NA,4,4,2,11,135,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11277.594097,11665.009628,1,90,5,5,0.74,5,5,0,2,0,2,18,1,4,NA,NA +63791,7,2,2,0,8,1,1,1,NA,8,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6700.950086,6971.360383,2,96,3,3,0.24,7,7,2,3,1,2,40,1,3,3,NA +63792,7,2,2,2,NA,5,6,2,2,35,NA,NA,2,2,2,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6075.554662,6069.137471,1,93,14,14,4.86,3,3,1,0,0,1,31,2,5,1,5 +63793,7,2,2,27,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,2,1,2,2,1,2,2,NA,NA,NA,NA,33202.24577,45456.634755,1,99,4,4,1.02,2,2,0,1,0,2,27,1,4,3,NA +63794,7,2,1,4,NA,3,3,2,4,50,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,78946.660075,92504.536814,3,91,15,15,5,4,4,1,1,0,2,41,1,5,1,5 +63795,7,2,1,59,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,152467.08796,152281.176016,1,94,10,7,3.76,2,1,0,0,0,1,59,1,4,6,NA +63796,7,2,2,36,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,5,6,2,1,2,2,1,2,2,1,2,2,1,18901.436377,19274.920746,3,91,15,10,5,2,1,0,0,0,2,36,1,5,6,NA +63797,7,2,1,14,NA,3,3,2,14,170,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,127790.772987,128099.355719,1,97,15,15,3.89,5,5,0,2,0,1,50,1,4,6,NA +63798,7,2,2,2,NA,3,3,2,2,27,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,50865.409844,56139.684211,1,101,7,7,1.74,4,4,1,0,0,1,24,NA,NA,1,4 +63799,7,2,1,69,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,3,1,NA,1,2,1,1,2,1,1,2,1,3,10288.337394,12038.909334,3,91,6,6,1.12,4,4,0,0,2,1,69,2,3,1,1 +63800,7,2,2,3,NA,5,6,2,3,36,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4938.043177,5022.237557,1,91,2,2,0.32,3,3,1,1,0,2,28,1,4,77,NA +63801,7,2,2,64,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,10192.188896,10440.656902,1,99,6,6,2.3,1,1,0,0,1,2,64,1,5,3,NA +63802,7,2,2,48,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,18462.756377,18043.935864,1,99,7,7,3.4,1,1,0,0,0,2,48,1,5,3,NA +63803,7,2,2,36,NA,1,1,1,NA,NA,2,NA,2,2,3,NA,2,6,2,2,2,2,2,2,2,2,2,2,2,41791.57979,45058.092516,2,102,7,7,1.79,4,4,0,2,0,1,40,2,2,6,NA +63804,7,2,1,61,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,5729.786464,5774.606655,2,95,14,14,4.58,3,3,0,1,1,1,61,1,4,1,5 +63805,7,2,2,53,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,27769.056387,28050.845299,1,94,7,7,1.65,5,4,0,0,0,1,46,1,4,1,4 +63806,7,2,1,70,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,38226.070503,39676.327756,1,99,12,12,NA,2,2,0,0,2,1,70,1,5,1,5 +63807,7,2,2,61,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,10798.193871,11318.855823,2,95,2,2,0.67,2,2,0,0,1,2,61,1,3,3,NA +63808,7,1,2,13,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,23477.73925,0,1,91,6,6,1.13,6,6,1,3,0,1,40,1,4,6,NA +63809,7,2,2,10,NA,3,3,2,10,126,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,55626.447796,54931.333538,1,95,9,9,2.13,6,6,0,4,0,2,44,1,1,1,1 +63810,7,2,1,16,NA,5,6,1,16,198,NA,NA,2,2,1,8,NA,NA,NA,1,2,1,1,2,2,1,2,1,NA,7558.274942,7964.822305,2,96,4,4,0.92,3,3,0,1,1,2,41,2,2,1,2 +63811,7,1,2,4,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12129.691938,0,1,97,7,7,1.74,4,4,2,0,0,1,34,1,5,1,5 +63812,7,2,2,47,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,30932.175051,30085.634936,2,101,3,3,0.68,2,2,0,0,0,1,58,1,1,6,NA +63813,7,2,1,67,NA,4,4,2,NA,NA,2,NA,2,2,2,NA,5,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,6016.509449,6063.572478,1,93,4,4,1.38,1,1,0,0,1,1,67,2,5,2,NA +63814,7,2,1,17,NA,3,3,2,17,208,2,NA,2,1,4,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,57357.902168,67351.058423,1,99,77,77,NA,4,4,1,1,0,1,31,2,3,1,3 +63815,7,2,1,8,NA,4,4,2,8,98,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8579.422451,9062.344401,1,99,5,5,1.13,3,3,1,1,0,2,30,1,1,4,NA +63816,7,2,1,5,NA,4,4,2,5,67,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7431.820906,7738.904727,1,99,6,6,1.3,5,5,1,2,0,1,34,1,2,1,3 +63817,7,2,2,47,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,19075.861607,18553.800612,1,96,15,15,5,2,2,0,1,0,2,47,1,5,3,NA +63818,7,2,2,40,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,2,1,2,2,1,2,2,NA,NA,NA,NA,35126.205635,36772.568368,1,95,1,1,0.12,3,3,0,2,0,2,40,1,5,3,NA +63819,7,2,2,0,11,1,1,2,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7579.106293,8082.789623,1,90,15,15,4.77,4,4,1,1,0,2,41,1,5,1,2 +63820,7,2,2,58,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,15521.115746,15561.208623,2,100,5,5,1.08,3,3,0,0,0,1,38,1,2,5,NA +63821,7,2,1,4,NA,4,4,1,4,56,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10510.490567,10944.785425,2,98,6,6,1,5,5,2,1,0,2,31,1,4,6,NA +63822,7,2,1,13,NA,4,4,2,13,160,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13416.172328,13756.125082,1,96,14,14,2.19,7,7,0,2,0,1,39,1,2,1,3 +63823,7,2,1,21,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,104488.914565,109862.797404,1,98,3,1,0.27,4,1,0,0,0,1,20,1,4,5,NA +63824,7,1,1,34,NA,5,6,NA,NA,NA,2,NA,2,1,5,NA,3,4,NA,1,2,2,1,2,2,NA,NA,NA,NA,16974.834956,0,1,93,9,9,1.77,7,7,0,2,0,2,56,NA,NA,5,NA +63825,7,2,1,31,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,20729.794283,21506.407763,3,91,14,14,5,1,1,0,0,0,1,31,1,5,5,NA +63826,7,1,1,9,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,55902.987481,0,1,103,15,15,5,2,2,0,1,0,2,52,2,5,3,NA +63827,7,2,2,52,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,29756.667529,30535.306876,2,98,4,4,1.19,2,2,0,0,0,2,52,1,3,1,NA +63828,7,2,2,64,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,118611.064701,118209.809508,1,91,10,10,4.76,2,2,0,0,2,2,64,1,4,1,5 +63829,7,2,2,42,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,NA,NA,NA,NA,80418.665565,83274.564983,2,100,10,10,3.13,4,4,0,2,0,1,45,1,4,1,4 +63830,7,2,2,64,NA,2,2,1,NA,NA,2,NA,2,1,6,NA,1,1,NA,2,2,2,1,2,2,2,2,1,NA,11225.5556,12146.092964,2,93,8,8,2.62,3,3,0,0,2,2,64,2,1,1,1 +63831,7,2,2,23,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,6,2,1,2,2,1,2,2,1,2,2,1,20000.263815,19016.481945,1,102,12,12,NA,7,7,3,2,0,2,52,1,4,5,NA +63832,7,2,1,46,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,133542.212862,137914.897649,3,91,8,8,1.95,4,4,2,0,0,2,30,1,5,1,4 +63833,7,2,1,9,NA,2,2,1,9,118,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13927.458372,13742.678011,2,98,6,6,0.78,7,7,1,3,1,2,63,1,2,4,NA +63834,7,2,2,52,NA,4,4,1,NA,NA,2,NA,2,1,6,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,15776.849485,18474.07459,2,93,14,14,2.78,5,5,0,0,0,1,52,2,4,1,2 +63835,7,2,2,76,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,1,2,1,2,2,1,1,2,NA,12535.973802,12972.182488,2,100,15,15,4.97,5,5,0,2,1,2,42,1,5,1,5 +63836,7,2,1,16,NA,4,4,2,16,197,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12462.601191,12584.643654,2,97,5,5,0.92,5,5,0,3,0,2,54,1,3,2,NA +63837,7,2,2,70,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,63504.762752,64182.95787,1,91,10,10,5,1,1,0,0,1,2,70,1,4,2,NA +63838,7,2,2,78,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,25812.913537,27430.822937,2,95,4,4,1.34,1,1,0,0,1,2,78,1,3,2,NA +63839,7,2,1,75,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,9257.537917,9400.859081,1,99,10,10,2.71,5,5,1,1,2,1,75,1,1,1,3 +63840,7,2,1,10,NA,3,3,2,10,125,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,57057.523607,61384.115788,1,98,10,10,3.04,4,4,0,2,0,2,47,1,4,1,3 +63841,7,2,1,27,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,59682.963348,63721.06052,2,102,10,10,4.76,2,2,0,0,0,1,27,1,4,1,4 +63842,7,2,1,0,7,5,6,2,NA,8,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8577.614982,8519.98112,2,91,14,14,4.19,3,3,1,0,0,2,31,1,5,1,5 +63843,7,2,2,13,NA,2,2,2,13,159,NA,NA,2,2,3,6,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,17848.732433,20206.102312,2,91,99,99,NA,6,6,1,3,0,2,20,2,2,5,NA +63844,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,28974.537912,30613.083607,1,99,6,6,1.7,2,2,0,0,2,2,77,1,3,1,5 +63845,7,2,1,43,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,28813.038041,29247.173902,1,94,3,3,1.21,1,1,0,0,0,1,43,1,4,3,NA +63846,7,2,1,3,NA,3,3,1,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,38749.197676,45403.777431,1,92,6,6,1.24,4,4,1,1,0,1,30,1,3,3,NA +63847,7,2,1,58,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,152467.08796,155918.172532,3,91,6,6,2.24,1,1,0,0,0,1,58,1,3,5,NA +63848,7,2,1,31,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,16214.132654,16029.957596,3,90,15,15,4.89,5,5,0,0,0,2,57,2,3,1,3 +63849,7,2,1,34,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,71279.707602,73321.195079,1,103,14,14,2.96,5,5,1,2,0,1,34,1,4,1,5 +63850,7,2,2,49,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,140084.621651,140222.178533,1,102,10,10,4.76,2,2,0,0,0,1,23,1,5,5,NA +63851,7,2,1,9,NA,4,4,1,9,111,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13423.881856,14179.490667,2,101,1,1,0.27,3,3,0,2,0,2,36,1,3,5,NA +63852,7,2,1,50,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,158509.005274,161135.953834,1,100,15,15,5,4,4,0,1,0,1,50,1,4,1,4 +63853,7,2,2,36,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,77299.255327,77536.924917,2,92,15,15,5,2,2,0,0,0,2,36,1,5,1,5 +63854,7,2,2,5,NA,1,1,2,6,72,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,14812.229505,15746.041025,1,97,8,8,1.45,6,6,2,2,0,2,36,2,2,1,1 +63855,7,2,1,8,NA,2,2,2,8,97,NA,NA,2,1,3,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14700.46789,14706.980156,1,97,15,15,5,4,4,1,1,0,2,43,1,5,1,5 +63856,7,2,2,20,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,23845.8146,22808.13483,1,98,2,1,0.13,4,1,0,0,0,2,19,1,4,NA,NA +63857,7,1,1,4,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8199.080864,0,1,90,4,4,0.67,5,5,3,0,0,2,32,2,3,3,NA +63858,7,2,2,20,NA,2,2,1,NA,NA,2,NA,2,2,4,NA,2,6,1,2,2,2,2,2,2,2,2,2,2,42621.881199,51089.379491,2,102,8,8,1.09,7,7,1,3,0,2,33,2,1,6,NA +63859,7,2,1,55,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,17648.758915,17930.45653,2,99,3,3,0.44,5,5,1,1,0,2,53,1,4,1,3 +63860,7,2,2,50,NA,5,7,2,NA,NA,2,NA,2,1,7,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,120670.257812,123358.620194,3,90,9,9,3.14,3,3,0,0,0,1,56,2,3,1,3 +63861,7,2,1,63,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,138075.879417,141933.339512,2,91,15,15,5,2,2,0,0,1,2,57,1,5,1,5 +63862,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,NA,43004.283229,49692.210403,1,97,NA,77,NA,2,1,0,0,2,1,80,1,3,6,NA +63863,7,2,1,6,NA,4,4,2,6,74,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9502.15317,9484.287948,2,97,13,13,NA,6,6,2,2,0,2,24,1,2,6,NA +63864,7,2,1,3,NA,1,1,2,3,44,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,14993.478359,14600.446315,1,97,6,3,0.45,7,6,2,1,0,1,29,2,2,1,1 +63865,7,2,1,2,NA,2,2,1,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11853.772636,11869.789876,2,96,6,6,1.12,4,4,2,0,0,1,27,2,2,6,NA +63866,7,2,2,0,3,2,2,1,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,2,2,2,NA,NA,NA,NA,7367.430495,7419.943227,2,91,2,2,0.19,5,5,3,0,0,1,24,2,1,1,3 +63867,7,2,2,35,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,28930.832375,30957.619671,1,92,5,5,1.05,3,3,1,1,0,2,35,1,4,5,NA +63868,7,2,1,69,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,131445.986898,130104.237054,1,95,10,10,5,1,1,0,0,1,1,69,1,5,3,NA +63869,7,1,1,36,NA,3,3,NA,NA,NA,1,1,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,86986.68246,0,2,94,15,15,5,2,2,0,0,0,1,36,1,2,1,4 +63870,7,2,2,11,NA,4,4,2,11,140,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8184.286585,8442.757341,2,97,2,2,0.21,7,7,2,3,0,2,32,1,4,5,NA +63871,7,2,2,45,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,18490.479848,18604.849683,2,100,7,7,2.37,3,3,0,1,1,2,45,1,5,1,NA +63872,7,2,2,18,NA,5,6,1,18,218,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,1,1,2,2,1,6370.316505,6989.133332,2,92,7,7,1.17,6,6,0,1,1,1,78,2,1,1,3 +63873,7,2,1,80,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,8763.51401,9280.560292,2,100,5,3,1.29,3,1,0,0,2,2,80,1,1,2,NA +63874,7,2,1,3,NA,1,1,2,3,40,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,14505.510202,14964.673559,2,94,7,7,1.23,6,6,2,1,0,1,33,2,1,6,NA +63875,7,2,2,64,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,1,10266.896689,11139.888992,1,96,3,3,1.25,1,1,0,0,1,2,64,1,2,2,NA +63876,7,2,2,9,NA,4,4,1,9,119,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7321.387082,7717.353133,1,103,3,3,0.52,3,3,0,2,0,2,45,1,4,5,NA +63877,7,2,2,20,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,30275.274308,29672.504425,2,101,12,1,0.32,4,1,0,0,0,2,20,1,4,5,NA +63878,7,2,1,8,NA,3,3,1,8,105,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,25457.327997,26428.651236,3,92,6,6,1.41,4,3,0,1,0,1,41,1,4,1,4 +63879,7,2,1,76,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,38226.070503,39676.327756,1,99,7,7,3.31,1,1,0,0,1,1,76,1,5,2,NA +63880,7,2,2,77,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,53541.401974,54961.757487,1,99,7,7,2.72,2,2,0,0,2,1,77,1,2,1,3 +63881,7,2,2,25,NA,3,3,2,NA,NA,2,NA,2,2,2,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,50197.83865,52206.228199,1,93,12,6,2.75,4,1,0,0,0,2,25,2,5,5,NA +63882,7,2,1,43,NA,5,6,1,NA,NA,2,NA,2,2,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,15271.238172,15754.77307,3,91,15,15,5,3,3,0,1,0,2,44,2,5,1,5 +63883,7,1,2,80,NA,2,2,NA,NA,NA,2,NA,2,1,8,NA,1,2,NA,2,2,2,2,2,2,NA,NA,NA,NA,17318.187297,0,2,90,4,4,0.57,5,5,1,0,2,2,80,2,1,2,NA +63884,7,2,1,51,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,7867.418849,7869.055339,1,103,77,77,NA,6,6,0,2,2,1,70,NA,NA,1,1 +63885,7,2,1,19,NA,4,4,1,19,230,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,17606.165994,17558.40257,2,101,1,1,0.32,2,1,0,0,0,1,19,1,4,NA,NA +63886,7,2,2,7,NA,5,6,2,7,95,NA,NA,2,1,2,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11068.40581,11617.80042,1,97,15,15,5,3,3,0,1,0,2,40,1,5,1,5 +63887,7,2,2,64,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,1,94637.019439,107051.932277,1,94,7,7,3.13,1,1,0,0,1,2,64,1,3,2,NA +63888,7,2,1,25,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,20948.005175,20851.734447,2,98,5,5,0.59,7,7,3,0,0,2,50,1,5,4,NA +63889,7,2,1,48,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,28813.038041,29425.409675,1,94,1,1,0.36,1,1,0,0,0,1,48,1,3,5,NA +63890,7,2,2,60,NA,2,2,2,NA,NA,2,NA,2,1,6,NA,1,4,NA,2,2,2,1,2,2,2,2,2,2,9716.805546,10308.451947,2,90,3,3,0.68,2,2,0,0,1,1,21,2,4,5,NA +63891,7,2,2,55,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,18441.731082,18102.807884,1,96,9,9,4.13,2,2,0,0,1,2,55,1,4,5,NA +63892,7,2,2,10,NA,3,3,1,10,131,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,49543.011606,52616.361829,1,94,15,15,5,6,6,0,4,0,1,38,1,5,1,4 +63893,7,1,1,6,NA,2,2,NA,NA,NA,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,12722.361971,0,2,93,8,8,2.62,3,3,0,1,0,1,43,2,4,6,NA +63894,7,2,2,19,NA,4,4,2,19,231,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13775.846051,13737.029624,2,97,7,7,1.06,7,7,1,2,0,2,40,1,4,5,NA +63895,7,2,1,37,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,18094.858384,18452.252422,1,96,15,15,5,3,3,0,1,0,2,37,1,4,1,4 +63896,7,2,2,9,NA,5,6,2,9,118,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9620.269705,10320.938187,2,91,14,14,3.47,4,4,1,1,0,2,40,2,5,1,NA +63897,7,2,2,7,NA,2,2,2,7,95,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13338.830817,13909.366846,1,90,6,6,1.68,3,3,1,1,0,2,36,2,4,4,NA +63898,7,2,2,51,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,NA,NA,NA,1,2,2,1,24870.513993,25000.211608,2,98,6,6,0.63,7,7,2,2,1,1,60,1,3,1,2 +63899,7,2,2,75,NA,2,2,1,NA,NA,2,NA,2,1,8,NA,1,3,NA,2,2,2,2,2,2,NA,NA,NA,NA,18006.276697,20109.914446,2,93,3,3,1.14,1,1,0,0,1,2,75,2,1,3,NA +63900,7,2,2,36,NA,5,6,1,NA,NA,2,NA,2,1,3,NA,1,1,1,1,2,1,1,2,1,NA,NA,NA,NA,14138.631841,14167.501749,3,92,77,77,NA,7,7,2,4,1,1,62,NA,NA,1,NA +63901,7,2,1,12,NA,2,2,1,12,155,NA,NA,1,1,NA,7,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,20560.901695,20875.182272,2,96,2,2,0.27,6,6,1,3,0,1,34,NA,NA,1,NA +63902,7,2,1,68,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,143397.643998,144742.519652,2,98,10,10,4.76,2,2,0,0,2,1,68,1,4,1,NA +63903,7,2,1,19,NA,4,4,1,19,235,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13731.625553,14242.275028,1,100,14,14,3.93,3,3,0,1,0,2,47,1,5,4,NA +63904,7,2,2,42,NA,3,3,2,NA,NA,2,NA,2,2,6,NA,4,4,3,1,2,2,1,2,2,NA,NA,NA,NA,113005.700223,113116.666806,1,99,10,10,5,1,1,0,0,0,2,42,2,4,4,NA +63905,7,2,1,23,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,4,5,NA,1,2,1,1,2,1,NA,NA,NA,NA,14979.624397,15387.451243,1,102,3,2,0.73,2,1,0,0,0,1,24,2,4,5,NA +63906,7,2,1,8,NA,4,4,2,8,98,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11324.954668,11525.075349,1,93,4,4,1.03,3,3,1,1,0,2,35,2,3,4,NA +63907,7,2,1,60,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,11492.781131,11582.681279,1,100,15,14,5,2,1,0,0,2,1,60,1,5,6,NA +63908,7,2,1,55,NA,1,1,2,NA,NA,2,NA,2,1,7,NA,2,1,NA,2,2,2,2,2,2,2,2,2,2,22446.308035,22116.943066,2,94,7,7,1.33,6,6,0,1,0,1,55,2,2,1,1 +63909,7,2,2,62,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,43972.04458,44690.47559,2,96,3,3,0.95,2,2,0,0,2,2,62,1,4,1,4 +63910,7,1,2,41,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,5,1,3,1,2,2,1,2,2,NA,NA,NA,NA,134076.17118,0,1,98,15,15,5,3,3,0,0,0,2,41,1,5,1,NA +63911,7,2,2,67,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,10083.559248,10533.779383,1,96,9,9,4.92,1,1,0,0,1,2,67,1,4,3,NA +63912,7,2,1,28,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,11477.00145,11789.46785,2,100,12,5,1.88,5,1,0,0,0,1,22,NA,NA,5,NA +63913,7,2,1,18,NA,2,2,2,18,223,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,14081.782012,14391.713696,2,90,2,2,0.25,5,5,0,1,0,2,41,2,4,1,NA +63914,7,2,2,7,NA,1,1,1,7,88,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15962.145468,16535.37648,2,98,9,9,2.6,4,4,0,2,0,1,30,1,2,1,2 +63915,7,2,2,40,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,20048.680628,20209.076405,2,95,7,7,1.13,6,6,0,3,1,1,52,1,4,1,4 +63916,7,2,1,34,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,19788.748292,21708.160855,1,94,4,4,0.59,5,5,0,3,0,1,34,1,2,1,4 +63917,7,2,1,71,NA,2,2,1,NA,NA,2,NA,2,1,8,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,14055.866747,14300.892374,2,93,5,5,1.32,2,2,0,0,2,1,71,2,4,1,1 +63918,7,2,1,49,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,152858.509804,157853.944421,1,95,12,12,NA,3,3,0,0,0,1,49,1,5,1,NA +63919,7,2,1,2,NA,1,1,2,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11160.282155,11957.436882,2,97,2,2,0.27,3,3,2,0,0,2,19,1,3,NA,NA +63920,7,2,2,29,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,1,1,2,2,1,2,2,1,2,2,1,104934.725755,109561.954446,2,98,10,10,4.42,2,2,0,0,0,1,31,1,4,1,3 +63921,7,2,1,3,NA,4,4,2,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8402.233801,8920.908511,2,101,1,1,0.1,6,6,1,2,1,2,27,1,2,1,2 +63922,7,2,2,38,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,4,5,2,1,2,2,1,2,2,1,2,2,3,14767.290807,18767.43866,2,90,5,5,1.43,2,2,0,1,0,2,38,2,4,5,NA +63923,7,2,2,52,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,13728.308948,13391.816234,2,90,15,15,5,4,4,0,0,0,1,57,2,5,1,5 +63924,7,2,2,29,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,4,2,1,2,2,1,2,2,1,2,2,1,18730.678506,18151.501185,2,96,4,4,0.57,6,6,0,3,0,2,29,1,3,4,NA +63925,7,1,2,32,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,4,6,3,1,2,2,1,2,2,NA,NA,NA,NA,18933.643351,0,1,91,6,6,1.13,6,6,1,3,0,1,40,1,4,6,NA +63926,7,2,1,34,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,21317.283165,21013.422419,2,96,5,5,0.67,6,6,1,2,1,1,34,1,4,1,4 +63927,7,2,1,37,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,1,1,NA,2,2,1,1,2,1,2,2,2,2,34997.800447,34733.660984,2,96,3,3,0.46,5,5,1,2,0,1,37,1,1,1,2 +63928,7,2,2,42,NA,4,4,2,NA,NA,2,NA,2,1,8,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,22754.478969,25596.207975,1,96,7,7,3.58,1,1,0,0,0,2,42,2,5,5,NA +63929,7,2,2,34,NA,2,2,2,NA,NA,2,NA,2,1,99,NA,4,1,1,1,2,2,2,2,2,1,2,2,1,28899.648059,29089.927914,1,96,15,15,5,4,4,0,2,0,1,36,2,3,1,4 +63930,7,2,1,4,NA,5,7,2,4,52,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7666.445036,8598.756895,1,96,6,6,1.34,3,3,1,0,0,2,42,2,4,6,NA +63931,7,1,2,32,NA,5,6,NA,NA,NA,2,NA,2,1,4,NA,3,2,3,1,2,2,1,2,2,NA,NA,NA,NA,20584.427267,0,1,95,6,6,1.34,4,4,0,2,0,2,32,2,3,2,NA +63932,7,2,1,1,13,1,1,1,NA,14,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15546.999135,15290.852049,2,98,10,10,3.82,3,3,1,0,0,2,33,1,4,1,2 +63933,7,2,2,6,NA,3,3,2,6,76,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,19880.837381,19632.404233,1,95,2,2,0.22,4,4,2,1,0,2,22,1,2,5,NA +63934,7,2,1,18,NA,2,2,2,18,227,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,26628.917773,31355.430562,1,101,5,5,0.51,7,7,0,3,2,1,75,2,1,1,1 +63935,7,2,1,17,NA,3,3,2,17,209,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,20991.942732,21394.366957,1,91,3,3,0.62,3,3,0,1,0,2,55,1,4,4,NA +63936,7,2,1,35,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,110819.46221,119829.247006,2,96,10,7,3.67,2,1,0,0,0,1,35,1,5,5,NA +63937,7,2,2,15,NA,4,4,1,16,192,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12744.907234,12578.013387,2,93,7,7,2.78,2,2,0,1,0,2,54,1,4,3,NA +63938,7,2,2,12,NA,4,4,1,13,156,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12208.965913,12602.394285,2,100,15,15,4.97,5,5,0,2,1,2,42,1,5,1,5 +63939,7,2,1,66,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,9221.19173,9293.322792,2,95,5,5,1.32,2,2,0,0,2,1,66,1,2,1,4 +63940,7,2,1,15,NA,2,2,2,15,183,NA,NA,1,1,NA,9,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,16033.31661,16386.200415,2,90,10,10,3.13,4,4,1,2,0,2,39,1,5,4,NA +63941,7,2,2,53,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,14680.520497,15280.64157,3,91,9,9,3.24,3,3,0,1,1,1,64,2,2,1,5 +63942,7,2,2,42,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,2,1,2,2,1,2,2,NA,NA,NA,NA,145772.192378,148626.818504,1,95,12,12,NA,6,6,2,0,0,2,42,1,2,1,5 +63943,7,2,2,29,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,137368.929197,138597.101074,1,91,8,7,3.21,2,1,0,0,0,1,33,1,5,6,NA +63944,7,2,1,20,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,39031.957066,39875.03294,1,95,77,77,NA,3,3,0,0,0,2,41,1,2,5,NA +63945,7,2,2,29,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,87611.353116,90505.825807,2,92,10,10,5,1,1,0,0,0,2,29,1,5,5,NA +63946,7,2,1,39,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,15867.258653,19649.848899,3,91,6,6,1.22,5,5,1,2,0,2,37,1,4,1,2 +63947,7,2,1,1,16,4,4,1,NA,17,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6376.965739,6454.74783,2,100,6,6,1.51,3,3,1,0,0,1,29,1,3,1,4 +63948,7,2,2,50,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,24351.694017,24510.535836,1,100,12,14,5,2,1,0,0,0,2,50,1,3,6,NA +63949,7,2,2,50,NA,2,2,1,NA,NA,2,NA,2,1,6,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,18295.488967,19299.909712,2,103,12,12,NA,4,4,0,1,0,2,50,2,3,1,4 +63950,7,2,2,28,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,22531.325817,21485.967466,2,91,15,15,5,4,4,0,0,1,1,61,NA,NA,1,2 +63951,7,2,1,14,NA,4,4,2,14,178,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11806.79775,12091.578602,1,91,15,15,5,6,6,1,2,0,2,42,2,5,1,5 +63952,7,2,2,10,NA,3,3,1,10,123,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,63812.58912,64724.869865,3,91,15,15,5,2,2,0,1,0,1,42,1,5,2,NA +63953,7,2,2,31,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,1,1,1,2,2,1,2,2,1,2,2,1,39561.667842,38764.112139,3,92,7,7,1.49,5,5,0,2,1,2,62,1,4,2,NA +63954,7,2,1,41,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,3,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,17249.311662,20609.214634,2,91,6,6,1.57,3,3,0,1,0,1,41,2,3,1,3 +63955,7,2,2,65,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,128294.718377,130390.843426,1,93,15,12,NA,4,1,0,0,3,1,80,1,5,2,NA +63956,7,2,2,33,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,87648.893016,94490.113574,2,91,15,15,5,4,4,2,0,0,2,33,1,5,1,5 +63957,7,2,2,59,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,19676.781212,23812.59189,1,103,7,7,1.33,5,5,0,1,1,1,28,1,2,1,3 +63958,7,2,2,60,NA,2,2,1,NA,NA,2,NA,2,1,7,NA,3,2,NA,2,2,2,1,2,2,2,2,1,2,11851.128358,12729.036357,2,93,6,6,0.64,7,7,2,1,3,2,60,2,3,2,NA +63959,7,2,1,41,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,27356.080541,28129.563738,1,101,6,6,1.17,4,4,0,1,0,1,41,1,3,6,NA +63960,7,2,1,21,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,25651.892165,25126.271361,1,97,6,6,1.41,3,3,0,1,0,2,51,1,4,5,NA +63961,7,2,2,0,9,1,1,1,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6699.512423,6879.514499,3,91,15,14,4.03,5,4,2,0,0,1,42,2,4,1,5 +63962,7,1,2,80,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,54095.581484,0,2,91,6,6,2.24,1,1,0,0,1,2,80,1,3,2,NA +63963,7,2,1,72,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,83244.241244,88112.194036,2,102,15,15,5,2,2,0,0,2,1,72,1,5,1,NA +63964,7,2,1,62,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,85786.890667,86591.455494,2,96,15,15,5,3,2,0,0,1,1,62,1,5,1,2 +63965,7,2,1,72,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,19115.0887,22519.216384,2,98,6,6,1.26,4,4,0,1,2,2,63,1,3,1,3 +63966,7,2,2,34,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,NA,NA,NA,NA,26426.249254,26363.744856,1,99,7,1,0.24,2,1,0,0,0,2,38,1,5,6,NA +63967,7,2,2,24,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,5,2,1,2,2,1,2,2,NA,NA,NA,NA,16929.836231,18556.498474,2,101,8,5,1.84,2,1,0,0,0,2,27,2,5,5,NA +63968,7,2,2,61,NA,2,2,1,NA,NA,2,NA,2,2,6,NA,1,3,NA,2,2,2,1,2,2,2,2,2,2,10310.145764,11073.900839,1,100,13,13,NA,4,4,0,1,1,1,26,2,3,5,NA +63969,7,2,1,8,NA,4,4,1,8,106,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9173.220503,9355.60378,2,96,4,4,0.57,6,6,0,3,0,2,29,1,3,4,NA +63970,7,2,2,9,NA,5,6,1,10,120,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10235.530383,11121.127441,1,100,7,7,2.51,2,2,0,1,0,2,37,2,5,3,NA +63971,7,2,2,36,NA,5,6,1,NA,NA,2,NA,2,2,1,NA,3,1,2,1,2,1,1,2,2,1,2,1,NA,21470.176619,21617.60214,1,98,7,7,2.71,2,2,0,0,0,1,43,1,3,1,3 +63972,7,2,1,15,NA,3,3,2,15,189,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,74123.161671,78732.269389,1,93,15,15,4.59,4,4,0,1,0,1,57,1,5,1,5 +63973,7,2,2,15,NA,5,6,2,15,190,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12224.9472,12547.183925,1,97,14,14,2.72,7,7,0,2,0,1,40,1,5,1,5 +63974,7,2,1,53,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,139662.869107,140583.8015,1,100,15,15,5,3,3,0,0,0,1,53,1,5,1,4 +63975,7,2,2,6,NA,4,4,1,6,80,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9309.947844,9472.353128,2,98,2,2,0.31,4,4,2,1,0,2,27,1,2,4,NA +63976,7,2,1,1,13,4,4,1,NA,14,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8022.100831,8575.148723,2,102,7,7,1.53,5,5,1,3,0,2,36,1,5,5,NA +63977,7,2,2,22,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,18070.666316,17713.108755,1,99,6,6,1.46,3,3,0,0,1,2,80,NA,NA,2,NA +63978,7,2,1,12,NA,2,2,1,12,146,NA,NA,2,2,1,6,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,15674.964193,15512.049412,2,93,9,9,1.49,7,7,0,3,0,2,41,2,5,1,5 +63979,7,2,1,8,NA,3,3,2,8,105,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,65374.972543,69123.624578,1,90,15,15,5,4,4,0,2,0,1,37,1,5,1,5 +63980,7,2,2,6,NA,4,4,2,6,79,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7814.742747,8095.069503,2,95,7,7,2.64,2,2,0,1,0,1,48,1,2,77,NA +63981,7,2,2,6,NA,3,3,1,6,82,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,43528.185872,43349.34959,1,92,8,8,1.45,6,6,1,3,0,1,36,1,3,1,4 +63982,7,2,2,69,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,41983.304745,42669.243011,1,101,7,7,2.31,3,2,0,0,1,2,69,1,4,2,NA +63983,7,2,1,31,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,94698.084211,97410.286035,1,101,5,5,0.89,5,5,1,2,0,1,31,1,2,1,1 +63984,7,2,1,24,NA,5,7,2,NA,NA,2,NA,2,2,2,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,33942.93341,34470.44913,3,91,6,6,2.04,2,2,0,0,0,1,24,2,4,5,NA +63985,7,2,1,5,NA,2,2,2,5,70,NA,NA,2,2,2,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,12403.412256,12420.172189,2,90,2,2,0.32,4,4,1,2,0,2,34,2,1,77,NA +63986,7,2,1,75,NA,1,1,2,NA,NA,2,NA,2,1,9,NA,1,1,NA,2,2,2,1,2,2,2,1,2,NA,16607.774808,17550.450209,1,101,3,3,0.93,2,2,0,0,2,1,75,2,1,1,1 +63987,7,2,1,0,1,4,4,2,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6238.040326,6448.58866,1,93,10,10,2.91,4,4,2,0,0,2,27,1,5,1,4 +63988,7,2,1,4,NA,1,1,1,4,55,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,16775.083123,16797.750213,2,98,2,2,0.27,4,4,2,0,0,2,20,2,2,6,NA +63989,7,2,2,53,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,31785.728924,32871.467684,1,101,3,3,0.92,2,2,0,1,0,2,53,1,5,3,NA +63990,7,2,1,17,NA,5,6,2,17,204,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,6666.045669,7317.485505,3,90,13,13,NA,3,3,0,2,0,2,41,2,3,4,NA +63991,7,2,2,44,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,NA,NA,NA,NA,22707.329726,23247.668083,2,97,2,2,0.27,4,4,0,2,0,1,51,1,2,4,NA +63992,7,2,1,44,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,19696.958879,19993.739669,2,95,1,1,0.4,1,1,0,0,0,1,44,1,4,5,NA +63993,7,2,1,8,NA,1,1,1,8,103,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13927.458372,14007.413517,3,92,7,7,1.41,5,5,1,2,0,1,40,1,3,1,4 +63994,7,2,2,9,NA,4,4,1,9,115,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12120.418061,13050.526646,2,101,1,1,0.21,4,4,1,2,0,2,26,1,3,5,NA +63995,7,2,1,56,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,16851.334496,16987.280633,2,95,1,1,0,1,1,0,0,0,1,56,1,2,2,NA +63996,7,2,1,35,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,19478.738759,23024.340691,1,90,7,7,2.1,3,3,0,1,0,1,35,1,3,6,NA +63997,7,2,2,79,NA,3,3,2,NA,NA,2,NA,2,2,6,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,27102.582153,29013.853259,1,93,13,13,NA,1,1,0,0,1,2,79,2,1,2,NA +63998,7,2,2,48,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,29448.834066,32687.247837,1,97,9,9,5,1,1,0,0,0,2,48,1,5,5,NA +63999,7,2,2,44,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,14254.989855,14385.318229,1,103,15,15,3.7,5,5,0,2,1,1,55,1,5,1,5 +64000,7,2,1,31,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,NA,NA,NA,1,2,2,1,17879.023129,20112.694262,2,90,NA,NA,NA,1,1,0,0,0,1,31,1,3,5,NA +64001,7,2,1,7,NA,4,4,1,7,92,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13423.881856,14062.200951,2,101,5,5,0.89,4,4,1,1,1,2,38,1,4,77,NA +64002,7,2,1,80,NA,3,3,2,NA,NA,2,NA,2,1,9,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,31039.556381,33443.834712,1,96,15,15,5,2,2,0,0,2,2,80,1,5,1,5 +64003,7,2,2,47,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,138322.767578,143283.052066,1,95,14,14,5,2,2,0,0,0,1,54,1,4,1,3 +64004,7,2,2,0,10,1,1,2,NA,10,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,6331.376224,6501.48724,2,97,4,4,0.6,6,6,2,2,0,1,35,2,2,6,NA +64005,7,2,2,12,NA,1,1,1,12,152,NA,NA,2,2,3,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18515.058419,19512.090709,2,96,5,5,0.76,5,5,1,2,0,1,44,2,1,1,3 +64006,7,2,2,9,NA,5,7,1,9,116,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,19608.444487,19549.535258,2,98,3,3,0.38,5,5,0,4,0,2,39,1,4,5,NA +64007,7,1,1,0,7,1,1,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,2,2,2,NA,NA,NA,NA,7530.249163,0,2,102,12,12,NA,6,6,1,0,0,2,53,1,4,1,1 +64008,7,2,1,4,NA,4,4,2,4,54,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8123.332359,8458.989525,1,96,14,14,2.58,6,6,2,2,0,1,40,2,4,1,4 +64009,7,2,1,32,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,18666.270458,19921.991676,2,93,77,77,NA,2,2,0,0,0,2,28,2,5,1,5 +64010,7,1,1,3,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13345.162299,0,2,102,14,14,4.86,3,3,1,0,0,1,30,1,5,1,5 +64011,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,27118.033816,33710.198359,1,94,5,5,1.39,2,2,0,0,2,1,60,1,1,5,NA +64012,7,2,2,16,NA,3,3,2,17,205,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,27482.814969,29965.467716,2,95,7,7,1.13,6,6,0,3,1,1,52,1,4,1,4 +64013,7,2,1,80,NA,5,6,2,NA,NA,2,NA,2,1,5,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,8606.120537,9222.025464,1,93,2,2,0.69,1,1,0,0,1,1,80,2,5,2,NA +64014,7,2,2,20,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,26141.606772,25260.281919,1,92,9,6,2.24,3,1,0,0,0,2,21,NA,NA,5,NA +64015,7,2,1,32,NA,1,1,2,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,45691.377881,46792.745533,3,91,14,14,5,2,2,0,0,0,1,32,1,4,6,NA +64016,7,2,2,0,8,2,2,2,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5234.186769,5271.49441,2,90,3,3,0.46,5,5,3,0,0,2,22,1,2,5,NA +64017,7,2,2,24,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,128585.755579,132183.659765,2,97,9,9,4.08,2,2,0,0,0,2,24,1,4,1,3 +64018,7,2,1,35,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,18289.793332,18322.51979,1,99,10,10,3.13,4,4,0,2,0,1,35,1,4,1,5 +64019,7,2,2,10,NA,2,2,2,10,123,NA,NA,1,1,NA,4,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,13154.122703,13626.512275,1,93,9,9,2.46,4,4,0,2,0,1,35,2,1,1,1 +64020,7,2,2,17,NA,5,6,2,17,209,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11225.761275,11659.847432,2,91,8,8,2.34,4,4,0,2,0,1,56,2,5,1,5 +64021,7,2,2,62,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,13057.178942,13648.591881,1,102,10,10,4.42,2,2,0,0,2,2,62,1,5,1,4 +64022,7,2,2,27,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,14516.765165,13843.248577,3,90,15,15,4.34,4,4,0,0,1,1,65,1,3,1,4 +64023,7,2,1,80,NA,1,1,1,NA,NA,1,1,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,14200.083364,15006.095575,2,98,99,99,NA,1,1,0,0,1,1,80,1,1,2,NA +64024,7,2,2,62,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,94637.019439,96511.799704,1,94,4,4,1.71,1,1,0,0,1,2,62,1,4,3,NA +64025,7,2,1,31,NA,3,3,1,NA,NA,2,NA,2,1,7,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,88274.617148,90802.847573,2,92,15,14,5,2,1,0,0,0,2,29,1,5,6,NA +64026,7,2,2,29,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,18097.801029,17207.598344,2,97,NA,99,NA,7,6,2,1,1,2,56,1,3,5,NA +64027,7,2,2,5,NA,3,3,1,5,67,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,25864.922734,27487.163063,1,95,7,2,0.35,5,4,1,2,0,1,26,1,4,6,NA +64028,7,2,1,11,NA,2,2,2,11,142,NA,NA,1,1,NA,4,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,9390.522479,9862.720437,2,90,1,1,0.14,2,2,0,1,0,2,36,1,3,3,NA +64029,7,2,1,22,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,NA,NA,NA,1,2,2,1,39915.513053,41236.907607,2,98,7,7,1.53,5,5,0,0,0,2,48,1,3,5,NA +64030,7,2,1,6,NA,2,2,1,6,78,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,14821.597351,14686.992722,3,92,6,6,0.86,7,7,1,4,0,2,36,2,1,1,1 +64031,7,2,2,19,NA,1,1,1,19,233,2,NA,1,1,NA,13,NA,NA,NA,2,2,2,2,2,2,1,2,2,NA,16781.078148,17658.768186,2,103,77,77,NA,5,5,0,2,0,2,45,2,4,5,NA +64032,7,2,1,46,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,36319.60275,35786.668567,1,103,8,8,4.48,1,1,0,0,0,1,46,1,4,3,NA +64033,7,2,2,64,NA,5,6,2,NA,NA,2,NA,2,2,1,NA,5,1,NA,1,2,1,1,2,2,1,2,1,3,14102.354333,14646.654863,3,91,7,7,2.16,3,3,1,0,1,2,36,2,5,1,NA +64034,7,2,2,62,NA,1,1,1,NA,NA,2,NA,2,2,6,NA,1,1,NA,2,2,2,2,2,2,2,2,2,2,13473.304889,14578.166065,2,96,5,5,0.68,6,6,0,3,2,1,60,2,1,1,1 +64035,7,2,1,8,NA,2,2,1,8,98,NA,NA,1,1,NA,2,NA,NA,NA,2,1,2,1,2,2,1,2,2,NA,15039.041447,15306.786696,3,91,5,5,0.89,4,4,0,2,2,1,61,2,3,1,4 +64036,7,2,1,69,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,28953.774534,28658.225591,1,98,6,5,1.93,2,1,0,0,2,1,69,1,4,6,NA +64037,7,2,1,28,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,12538.868652,13740.340257,2,95,15,15,5,4,1,0,0,0,1,29,NA,NA,99,NA +64038,7,2,1,4,NA,4,4,2,4,53,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8325.511113,9180.237397,2,99,6,6,1.13,4,4,1,1,0,1,33,1,3,6,NA +64039,7,2,2,0,4,4,4,2,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,3689.415307,3729.699375,2,99,13,13,NA,4,4,1,0,0,2,50,1,2,1,9 +64040,7,2,1,31,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,19185.622388,19060.093906,2,95,5,1,0,3,1,0,0,0,1,31,1,4,5,NA +64041,7,2,1,9,NA,4,4,1,9,109,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,10122.702296,10692.492997,2,100,77,77,NA,4,4,0,1,1,2,28,1,3,5,NA +64042,7,2,1,39,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,16905.961576,17944.772858,2,94,4,4,1.16,2,2,0,0,0,1,39,1,2,1,5 +64043,7,2,1,14,NA,4,4,2,14,177,NA,NA,2,2,4,10,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11523.287163,11546.069645,1,96,8,8,2.17,4,4,0,2,0,2,45,2,5,4,NA +64044,7,2,2,8,NA,1,1,1,8,107,NA,NA,1,1,NA,2,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,10870.942302,11918.469007,1,103,10,10,2.82,4,4,0,2,0,1,41,2,1,1,1 +64045,7,2,2,4,NA,3,3,1,4,58,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,52159.241328,54365.068635,1,100,6,6,1.18,5,5,2,2,0,2,40,1,5,3,NA +64046,7,2,2,39,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,6,2,1,2,2,1,2,2,1,2,2,1,38500.994547,38409.930489,2,91,2,2,0.81,1,1,0,0,0,2,39,1,2,6,NA +64047,7,2,2,34,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,58826.425292,61096.366503,1,102,8,8,2.42,4,4,0,2,0,2,34,1,4,1,3 +64048,7,2,2,54,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,150482.742079,150600.121666,2,98,8,8,3.67,2,2,0,0,0,2,54,1,4,3,NA +64049,7,2,2,16,NA,1,1,1,16,195,NA,NA,2,2,4,10,NA,NA,NA,1,2,2,2,2,2,1,2,2,1,15690.47168,16407.081535,1,102,5,5,0.62,7,7,1,3,0,1,49,2,2,1,1 +64050,7,2,2,41,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,35469.911999,45030.280097,2,91,3,3,0.86,2,2,0,0,0,2,41,1,4,1,3 +64051,7,2,1,21,NA,2,2,2,NA,NA,2,NA,2,2,4,NA,3,5,NA,1,2,2,NA,NA,NA,1,2,2,1,52571.533452,58252.213979,1,93,4,4,0.92,3,3,0,0,1,1,60,NA,NA,1,4 +64052,7,2,1,60,NA,1,1,1,NA,NA,2,NA,2,2,6,NA,1,4,NA,2,2,2,1,2,2,2,2,2,2,10004.038848,10557.19122,2,102,8,8,4.13,1,1,0,0,1,1,60,2,1,4,NA +64053,7,2,1,8,NA,1,1,2,8,102,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13285.093011,13346.253362,2,94,6,6,1.15,5,5,1,2,0,1,33,1,2,1,2 +64054,7,2,2,19,NA,4,4,2,19,233,2,NA,1,1,NA,14,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,10484.6104,10912.740054,2,99,3,3,0.56,4,4,1,0,0,2,38,1,3,5,NA +64055,7,2,2,59,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,1,16033.091438,16414.611167,1,96,4,4,1.02,3,3,0,0,0,2,59,1,3,2,NA +64056,7,2,1,18,NA,3,3,2,18,221,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,34847.322278,35515.35986,2,91,6,6,1.26,5,5,0,1,2,2,80,1,4,2,NA +64057,7,2,2,11,NA,3,3,1,11,141,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,38662.840486,39387.514697,2,92,15,15,5,5,5,0,3,0,2,46,1,5,1,5 +64058,7,2,2,50,NA,4,4,2,NA,NA,2,NA,2,2,4,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,15499.383981,15868.203732,2,99,5,5,1.26,3,3,1,0,0,2,50,2,3,5,NA +64059,7,2,2,68,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,1,12886.419545,13879.729659,2,97,1,1,0.22,1,1,0,0,1,2,68,1,3,2,NA +64060,7,2,2,2,NA,3,3,1,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,27529.278041,30383.810541,1,92,5,5,1.05,3,3,1,1,0,2,35,1,4,5,NA +64061,7,2,2,47,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,35126.205635,35329.988956,1,95,1,1,0.17,2,2,0,1,0,2,47,1,2,3,NA +64062,7,2,2,10,NA,4,4,1,10,127,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9309.947844,9654.826166,2,98,14,14,3.36,4,4,0,2,0,1,37,1,4,1,4 +64063,7,2,2,62,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,32161.692893,32052.891523,1,99,2,2,0.78,1,1,0,0,1,2,62,1,4,3,NA +64064,7,2,2,46,NA,5,6,1,NA,NA,2,NA,2,2,8,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,17668.324663,18093.708295,1,102,14,14,4.86,3,3,0,1,0,1,42,1,4,1,5 +64065,7,2,1,46,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,106195.998472,105923.202819,1,93,15,15,5,2,2,0,0,0,1,46,1,4,1,5 +64066,7,2,2,11,NA,2,2,1,11,142,NA,NA,2,2,3,6,NA,NA,NA,2,1,2,1,2,2,1,2,2,2,15929.068964,16501.112136,2,102,5,5,0.59,7,7,1,3,0,1,37,2,1,6,NA +64067,7,2,1,2,NA,2,2,1,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,2,2,2,NA,NA,NA,NA,12915.99793,13324.846215,2,102,4,4,0.57,6,6,2,3,0,2,26,2,3,1,NA +64068,7,2,1,10,NA,1,1,1,10,131,NA,NA,1,1,NA,4,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,12231.897958,12180.037346,1,100,7,7,1.3,5,5,0,3,0,1,43,2,2,1,4 +64069,7,2,2,39,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,6,2,1,2,2,1,2,2,1,2,2,1,74050.783686,75666.677003,1,94,6,6,1.31,3,3,0,0,0,2,46,1,5,6,NA +64070,7,2,2,7,NA,3,3,1,7,89,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,48532.852397,48387.04619,1,101,7,7,1.55,5,5,1,2,0,2,31,1,4,1,2 +64071,7,2,1,67,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,1,11074.62349,11161.252677,2,101,5,5,0.89,4,4,1,1,1,2,38,1,4,77,NA +64072,7,2,2,50,NA,1,1,2,NA,NA,2,NA,2,2,3,NA,1,1,NA,2,2,2,1,2,2,1,2,2,2,21828.388259,21942.221447,3,91,6,6,0.89,7,7,1,1,0,1,59,2,1,1,1 +64073,7,2,1,13,NA,4,4,1,13,159,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12972.249316,12937.057154,1,100,15,15,3.7,5,5,0,3,0,1,51,1,5,1,5 +64074,7,1,1,50,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,16287.780872,0,2,100,6,6,2.04,2,2,0,0,0,2,50,1,2,1,3 +64075,7,2,1,22,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,34099.599202,35074.640491,1,94,2,2,0.42,3,3,0,0,0,2,52,1,4,1,1 +64076,7,2,2,1,21,3,3,2,NA,23,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,26071.535804,27174.107547,1,93,10,10,2.48,5,5,2,1,0,1,40,2,5,1,5 +64077,7,2,1,45,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,30489.729187,30783.113246,3,92,12,12,NA,3,2,0,0,0,1,45,1,3,1,3 +64078,7,2,1,17,NA,4,4,1,17,206,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,17606.165994,18260.901254,2,101,14,14,4.03,4,4,0,1,0,2,40,1,5,1,5 +64079,7,2,2,25,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,41328.871311,42415.982935,2,93,9,9,2.6,4,4,0,0,0,2,58,2,4,4,NA +64080,7,2,1,0,3,2,2,2,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7004.278208,7004.40731,1,93,5,5,1.3,3,3,1,1,0,2,28,2,4,5,NA +64081,7,2,1,11,NA,4,4,2,11,143,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12176.538896,12387.770281,2,97,2,2,0.3,4,4,0,2,0,1,42,1,2,6,NA +64082,7,2,1,64,NA,3,3,2,NA,NA,2,NA,2,2,5,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,167711.394252,169284.299948,1,101,10,10,4.63,2,2,0,0,1,1,64,2,3,1,4 +64083,7,2,2,76,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,30634.82105,30961.983694,1,95,7,7,2.16,3,3,0,0,1,1,45,1,3,1,4 +64084,7,2,1,80,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,33810.591598,40546.042621,3,91,13,13,NA,3,3,0,1,1,1,80,1,3,2,NA +64085,7,2,2,13,NA,5,6,2,13,160,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10164.140113,10557.174707,3,91,15,15,5,4,4,0,2,0,1,44,2,5,1,5 +64086,7,2,2,45,NA,5,6,2,NA,NA,2,NA,2,1,4,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,18040.833018,19102.925896,1,96,9,9,4.1,2,2,0,0,0,2,45,2,5,1,5 +64087,7,2,1,18,NA,1,1,2,18,225,2,NA,2,2,5,14,NA,NA,NA,1,2,2,1,2,2,NA,NA,NA,NA,20398.562455,20186.553847,3,92,8,8,2.01,4,4,1,0,0,2,49,2,5,4,NA +64088,7,2,2,9,NA,3,3,1,9,119,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,24832.585001,24642.096114,2,101,3,3,0.6,3,3,0,2,0,1,39,1,4,4,NA +64089,7,2,2,54,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,16567.527819,16240.172481,1,96,15,15,5,3,3,0,0,0,1,55,1,4,1,5 +64090,7,2,1,18,NA,4,4,2,18,218,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11351.725436,11256.943498,2,95,14,14,3.47,4,4,0,0,0,2,45,1,4,1,4 +64091,7,2,1,53,NA,5,6,2,NA,NA,2,NA,2,2,2,NA,1,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,12274.966216,12700.371312,3,90,5,5,1.05,3,3,0,0,0,1,53,2,1,1,2 +64092,7,2,1,18,NA,3,3,2,18,220,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,NA,NA,NA,NA,71458.892941,71654.216305,2,94,3,3,0.54,4,4,0,1,0,2,48,1,3,1,3 +64093,7,2,2,8,NA,5,6,1,8,97,NA,NA,1,1,NA,1,NA,NA,NA,1,1,1,1,2,1,1,2,2,NA,10387.513218,10891.034934,1,92,15,15,5,4,4,1,1,0,1,38,2,5,1,5 +64094,7,2,1,0,8,4,4,1,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7882.953266,8719.306286,2,96,7,7,1.79,4,4,2,0,0,2,49,1,3,1,3 +64095,7,2,1,37,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,113559.363135,118892.640077,2,102,14,14,4.93,3,3,0,1,0,1,37,1,5,1,5 +64096,7,2,1,10,NA,5,6,2,10,120,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,8246.426933,8701.859504,1,99,7,5,1.84,2,1,0,1,0,1,47,2,4,5,NA +64097,7,2,2,6,NA,4,4,1,6,73,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9139.784234,9841.162002,2,100,2,2,0.33,5,5,0,4,0,2,27,1,3,5,NA +64098,7,2,1,54,NA,4,4,2,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,19374.410926,19463.695548,1,96,4,4,0.65,4,4,0,0,0,1,19,1,4,NA,NA +64099,7,2,2,71,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,NA,90234.245265,93002.542962,2,101,7,7,3.9,1,1,0,0,1,2,71,1,5,3,NA +64100,7,1,1,5,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,58116.402634,0,1,97,15,15,5,5,5,2,0,1,1,43,1,5,1,5 +64101,7,2,2,0,5,4,4,2,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,3861.876549,4016.370213,1,96,8,8,1.61,6,6,3,0,0,1,33,2,5,1,4 +64102,7,2,2,63,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,9240.841805,10026.588852,2,95,13,13,NA,2,2,0,0,1,1,56,1,9,1,1 +64103,7,2,2,12,NA,5,6,1,12,148,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9505.147857,9693.556382,1,92,14,14,2.42,6,6,1,3,0,1,30,1,4,6,NA +64104,7,2,2,4,NA,4,4,1,4,52,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8340.858072,8802.325948,2,103,6,6,1.11,5,5,1,2,0,2,36,1,4,5,NA +64105,7,2,2,8,NA,1,1,1,8,107,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14042.378151,15260.975241,1,102,14,14,4.03,4,4,0,2,0,1,30,1,5,6,NA +64106,7,2,1,34,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,68184.631488,70137.474393,2,95,4,4,1.34,1,1,0,0,0,1,34,1,4,5,NA +64107,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,65891.955175,72165.622258,1,95,7,7,2.38,2,2,0,0,2,1,80,1,3,1,4 +64108,7,2,2,2,NA,3,3,2,2,28,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,18127.266286,20006.89679,2,95,6,6,1.08,4,4,1,1,0,1,39,1,4,1,4 +64109,7,1,2,45,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,80232.348161,0,1,99,77,77,NA,4,4,0,2,0,2,45,1,3,1,NA +64110,7,2,2,6,NA,4,4,2,6,81,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7282.523598,7776.514874,2,99,3,3,0.93,2,2,0,1,0,2,27,1,4,3,NA +64111,7,2,2,33,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,2,1,2,2,1,2,2,1,2,2,1,28047.519499,31779.09658,2,90,1,1,0.14,1,1,0,0,0,2,33,1,2,5,NA +64112,7,2,1,14,NA,2,2,1,14,179,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18635.323223,19040.145288,2,103,12,12,NA,4,4,0,1,0,2,50,2,3,1,4 +64113,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,35434.580514,38808.357492,1,95,3,3,0.96,1,1,0,0,1,2,80,1,4,2,NA +64114,7,2,1,9,NA,5,6,1,9,111,NA,NA,2,1,3,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,5769.526317,6088.16495,1,100,5,5,0.74,6,6,0,3,0,1,40,2,3,1,4 +64115,7,2,1,8,NA,4,4,2,8,101,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7370.805738,7721.29497,2,99,15,15,4.9,7,7,1,4,0,2,53,1,5,1,5 +64116,7,2,1,23,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,34099.599202,35276.751365,1,94,7,7,1.65,5,4,0,0,0,1,46,1,4,1,4 +64117,7,2,2,16,NA,3,3,2,16,194,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,60694.411883,64307.712903,1,99,15,15,4.47,4,4,0,2,0,2,43,1,5,1,5 +64118,7,2,2,0,3,1,1,1,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7782.311913,7756.671982,1,94,7,7,1.56,4,4,2,0,0,1,21,1,4,1,4 +64119,7,2,2,6,NA,3,3,1,6,73,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,48532.852397,48387.04619,1,98,15,15,5,5,5,0,3,0,2,41,1,5,6,NA +64120,7,2,1,77,NA,2,2,2,NA,NA,2,NA,2,2,4,NA,1,4,NA,2,2,2,2,2,2,1,2,2,NA,15301.031416,15853.994551,1,90,99,99,NA,5,5,0,2,1,2,50,2,4,4,NA +64121,7,2,2,34,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,5,3,2,1,2,2,1,2,2,1,2,2,1,27127.983961,27837.333201,2,90,7,7,1.66,4,4,0,3,0,2,34,1,5,3,NA +64122,7,2,2,67,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,1,6,NA,2,2,2,2,2,2,1,2,2,2,15876.871857,17178.834476,2,102,NA,13,NA,2,1,0,0,1,1,50,2,1,6,NA +64123,7,2,2,1,21,1,1,1,NA,22,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12871.484115,14210.463876,2,102,3,3,0.45,4,4,2,0,0,1,21,2,2,6,NA +64124,7,2,1,6,NA,4,4,1,6,78,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9261.557132,9782.87535,2,100,8,8,1.8,5,5,0,3,0,2,43,1,3,1,3 +64125,7,1,1,4,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,55061.722794,0,2,95,15,15,4.63,5,5,1,2,0,1,32,1,4,1,4 +64126,7,2,2,7,NA,1,1,1,7,92,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,19059.339877,19259.716076,1,95,13,13,NA,5,5,1,2,0,2,34,2,1,1,1 +64127,7,2,2,69,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,18695.172864,19350.637044,2,102,7,7,1.68,5,5,0,0,3,1,70,2,4,1,4 +64128,7,2,1,59,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,124170.603852,126212.047685,1,92,6,6,2.39,1,1,0,0,0,1,59,1,4,3,NA +64129,7,2,2,7,NA,4,4,2,7,92,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7588.605543,8170.947433,1,99,4,4,0.53,7,7,3,1,0,2,26,1,1,5,NA +64130,7,2,1,69,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,2,1,NA,1,2,1,1,2,1,1,2,1,1,13977.762704,14745.704028,1,92,77,77,NA,4,4,0,0,2,1,59,2,5,1,5 +64131,7,2,2,79,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,36067.495928,37024.300659,1,95,5,5,1.36,2,2,0,0,1,2,79,1,3,2,NA +64132,7,2,2,41,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,20303.639991,21936.687597,1,97,15,15,4.07,5,5,0,3,0,1,42,2,5,1,5 +64133,7,2,2,36,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,57151.56429,59304.909373,2,95,8,8,2.17,4,4,1,1,0,1,43,1,4,1,5 +64134,7,2,2,49,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,29670.405171,29084.152013,2,101,10,10,3.89,3,3,0,1,0,2,49,1,4,1,3 +64135,7,2,2,23,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,11206.329484,11903.241195,2,103,15,15,5,3,3,0,0,0,2,52,2,4,1,5 +64136,7,2,1,9,NA,1,1,1,9,118,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12624.747427,12616.351223,2,92,15,15,3.37,7,7,0,4,0,1,42,2,3,1,1 +64137,7,2,2,72,NA,5,6,2,NA,NA,2,NA,2,2,4,NA,1,2,NA,1,2,1,1,2,1,1,2,1,NA,10125.392704,11197.313648,2,91,12,12,NA,7,6,0,4,2,2,72,2,1,2,NA +64138,7,2,1,36,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,20071.705576,20337.925283,3,91,14,14,5,2,1,0,0,0,1,36,1,5,6,NA +64139,7,2,2,32,NA,2,2,2,NA,NA,2,NA,2,2,4,NA,2,6,2,2,2,2,1,2,2,NA,NA,NA,NA,34401.268523,35501.848089,2,97,4,4,0.67,4,4,0,2,0,1,39,2,2,6,NA +64140,7,2,2,16,NA,4,4,1,16,192,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12531.903464,12935.738352,2,100,5,5,1.07,4,4,0,1,0,2,36,1,3,5,NA +64141,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,26344.362464,29482.177939,2,95,4,4,1.46,1,1,0,0,1,1,80,1,1,2,NA +64142,7,2,1,73,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,14537.797299,15440.503889,3,91,77,77,NA,2,2,0,0,2,1,73,1,5,1,5 +64143,7,2,1,58,NA,1,1,1,NA,NA,2,NA,2,2,6,NA,1,1,NA,2,2,2,2,2,2,NA,NA,NA,NA,25737.628192,27045.174332,1,94,5,5,0.57,7,7,2,1,0,1,58,2,1,1,1 +64144,7,2,2,2,NA,5,7,1,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9254.729183,9958.191837,2,98,15,15,4.17,6,6,1,1,0,2,40,1,4,1,4 +64145,7,2,1,2,NA,1,1,1,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12493.910388,13386.323284,2,98,1,1,0.19,3,3,2,0,0,2,31,1,4,2,NA +64146,7,2,2,47,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,20303.639991,21936.687597,1,97,15,15,5,6,6,0,3,0,1,47,1,5,1,5 +64147,7,2,2,34,NA,1,1,1,NA,NA,2,NA,2,2,5,NA,1,6,2,2,2,2,2,2,2,1,2,2,2,45655.090694,44423.220436,3,92,3,3,0.51,5,5,1,2,0,2,34,2,1,6,NA +64148,7,2,1,2,NA,4,4,2,2,30,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6580.937346,6661.20735,2,101,7,7,2.16,3,3,1,0,1,2,64,1,3,2,NA +64149,7,2,1,29,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,108504.032354,117548.425574,1,92,6,6,1.57,3,3,0,1,0,1,29,1,4,6,NA +64150,7,2,1,8,NA,4,4,1,8,106,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12839.999482,13062.740187,2,96,8,8,1.72,5,5,0,3,0,1,39,1,5,1,4 +64151,7,2,1,21,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,124820.027137,131239.54259,1,91,10,10,3.51,3,3,0,0,1,1,21,1,4,5,NA +64152,7,2,1,14,NA,4,4,1,14,173,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,16261.995423,16421.244198,2,96,5,5,1.13,3,3,1,1,0,2,31,1,3,5,NA +64153,7,2,2,11,NA,4,4,2,11,135,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6979.847147,8479.043057,1,99,7,7,1.53,5,5,0,3,0,1,39,1,3,1,3 +64154,7,2,2,59,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,19675.36066,19726.184442,2,96,14,14,4.26,3,3,0,0,0,1,20,1,4,5,NA +64155,7,2,1,11,NA,4,4,1,12,144,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11543.27965,11681.665542,1,98,1,1,0.03,3,3,0,2,0,2,38,1,4,5,NA +64156,7,2,2,8,NA,5,6,1,9,109,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,5142.091355,5516.602825,3,91,15,15,5,3,3,0,1,0,2,44,2,5,1,5 +64157,7,2,2,68,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,136832.42119,141624.96623,2,91,12,5,2.03,2,1,0,0,2,2,68,1,4,6,NA +64158,7,2,1,27,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,17420.978407,17095.959542,2,97,7,7,3.67,1,1,0,0,0,1,27,1,4,1,NA +64159,7,2,1,75,NA,1,1,2,NA,NA,2,NA,2,2,9,NA,1,1,NA,2,2,2,1,2,2,2,2,2,NA,17161.371047,18002.626237,1,101,5,5,0.51,7,7,0,3,2,1,75,2,1,1,1 +64160,7,2,1,13,NA,5,6,1,13,167,NA,NA,2,1,2,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11171.449402,11936.033174,1,92,7,7,1.56,4,4,0,2,0,2,38,2,4,6,NA +64161,7,2,2,51,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,18441.731082,18102.807884,1,96,15,15,5,2,2,0,0,0,2,51,1,5,5,NA +64162,7,2,1,18,NA,3,3,2,18,222,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,35639.306876,36153.844915,2,91,99,99,NA,3,3,0,0,0,1,40,NA,NA,1,4 +64163,7,2,1,48,NA,5,6,2,NA,NA,2,NA,2,2,5,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,12262.33683,12778.149281,2,100,15,15,5,3,3,0,1,0,1,48,2,5,1,5 +64164,7,2,1,47,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,19440.793325,20264.695737,2,95,15,10,3.67,5,3,0,0,0,1,47,1,5,1,3 +64165,7,2,2,6,NA,1,1,1,6,73,NA,NA,1,1,NA,0,NA,NA,NA,2,1,1,1,2,1,NA,NA,NA,NA,20495.125801,20710.596821,2,98,3,3,0.4,6,6,1,2,0,2,29,2,1,4,NA +64166,7,2,1,7,NA,2,2,2,7,92,NA,NA,2,2,3,0,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,10490.055059,10676.813132,3,90,4,4,0.63,5,5,0,3,0,1,45,2,4,1,4 +64167,7,2,2,21,NA,5,6,1,NA,NA,2,NA,2,2,1,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,16929.836231,17652.770039,2,101,1,1,0.14,2,1,0,0,0,2,21,2,4,5,NA +64168,7,2,1,31,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,96844.935107,100539.350089,2,98,10,10,4.42,2,2,0,0,0,1,31,1,4,1,3 +64169,7,2,1,17,NA,3,3,1,17,207,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,29202.587704,29754.083616,3,92,6,6,0.74,7,7,2,1,0,2,46,1,2,1,4 +64170,7,2,2,22,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,NA,NA,NA,NA,19337.563688,19353.557903,1,96,6,6,1.21,4,4,2,0,0,1,24,1,4,1,3 +64171,7,2,1,11,NA,3,3,2,11,135,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,25604.034863,28346.339599,1,95,10,6,1.34,5,4,1,2,0,1,32,1,3,6,NA +64172,7,2,1,80,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,10455.739374,11701.098067,1,101,3,3,0.86,2,2,0,0,2,2,80,1,2,1,1 +64173,7,2,2,38,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,17430.913214,17517.807291,1,90,5,5,1.06,4,4,0,2,0,1,53,1,3,1,4 +64174,7,2,2,18,NA,2,2,2,18,222,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,16189.692833,16766.382859,1,93,15,15,2.96,7,7,0,1,1,2,18,1,2,NA,NA +64175,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,35434.580514,39416.921733,1,95,2,2,0.83,1,1,0,0,1,2,80,1,2,2,NA +64176,7,2,1,72,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,10160.645851,10359.669924,1,96,9,9,3.97,2,2,0,0,2,1,72,1,4,1,5 +64177,7,2,1,2,NA,3,3,2,2,32,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,22388.62869,26233.531918,2,97,1,1,0.21,4,4,2,0,0,2,34,2,1,1,2 +64178,7,2,1,7,NA,5,6,1,7,88,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6765.693703,7164.978412,2,92,15,15,5,3,3,0,1,0,1,45,2,4,1,4 +64179,7,2,1,52,NA,1,1,1,NA,NA,2,NA,2,2,7,NA,1,1,NA,2,2,2,2,2,2,2,2,2,2,25118.469449,25612.281104,2,98,5,5,1.63,2,2,0,0,0,2,53,2,1,1,1 +64180,7,2,2,31,NA,2,2,2,NA,NA,2,NA,2,1,5,NA,4,1,2,2,2,2,1,2,2,NA,NA,NA,NA,38184.257672,39182.709093,2,91,9,9,2.6,4,4,1,1,0,2,31,2,4,1,5 +64181,7,2,2,56,NA,1,1,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,23409.465713,23644.84324,2,97,14,9,5,2,1,0,0,0,2,56,1,3,6,NA +64182,7,2,2,67,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,90638.027317,92118.903864,2,100,6,6,2.04,2,2,0,0,2,1,74,1,4,1,3 +64183,7,2,2,18,NA,1,1,1,18,223,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,27070.679378,27847.54398,1,92,7,7,1.48,5,5,0,1,0,1,42,1,5,1,4 +64184,7,2,1,67,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,36438.408188,36780.151097,1,101,3,3,0.66,2,2,0,0,1,1,67,1,2,3,NA +64185,7,2,2,14,NA,5,6,2,14,170,NA,NA,2,1,4,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11975.458482,12291.118947,1,97,7,7,1.48,5,5,1,2,0,1,40,2,5,1,4 +64186,7,2,1,63,NA,2,2,1,NA,NA,2,NA,2,1,8,NA,1,1,NA,2,2,2,1,2,2,1,2,2,1,9068.437099,9499.757798,2,93,9,9,3.97,2,2,0,0,1,2,57,2,3,1,1 +64187,7,2,1,6,NA,3,3,1,6,81,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,66003.625505,68276.88064,1,101,14,14,3.15,5,5,2,1,0,1,35,1,4,1,5 +64188,7,1,1,65,NA,3,3,NA,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,20187.172902,0,2,100,4,4,1.29,2,2,0,0,2,1,65,1,3,1,3 +64189,7,2,1,2,NA,5,6,2,2,33,NA,NA,2,2,2,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6208.192797,6963.167461,1,91,10,10,3.22,4,4,1,1,0,1,38,2,5,1,5 +64190,7,2,1,0,0,1,1,1,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7284.164858,7284.299119,2,98,4,4,0.67,4,4,1,0,0,2,40,1,3,3,NA +64191,7,2,1,72,NA,2,2,1,NA,NA,2,NA,2,1,8,NA,3,1,NA,2,2,2,1,2,2,2,2,1,NA,14159.984279,14406.82491,2,93,4,4,0.99,2,2,0,0,2,1,72,2,3,1,4 +64192,7,2,1,42,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,116464.874823,118336.754883,2,92,15,15,5,6,6,2,0,0,1,18,1,4,NA,NA +64193,7,2,1,37,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,16058.989596,16964.610342,2,97,6,6,1.02,6,6,1,2,0,1,37,1,3,1,3 +64194,7,2,2,63,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,10346.035773,10598.2543,1,99,15,15,5,2,2,0,0,2,1,67,1,5,1,5 +64195,7,2,1,33,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,19008.083201,19399.303007,2,97,12,12,NA,3,3,0,0,0,1,33,1,4,5,NA +64196,7,2,2,9,NA,5,6,1,9,115,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9211.293091,9657.799007,1,92,14,14,3.47,4,4,0,2,0,1,37,1,5,1,5 +64197,7,2,2,80,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,1,2,1,2,2,1,1,2,NA,7360.303891,7756.453804,3,90,15,15,4.2,6,6,1,0,2,1,60,1,5,1,4 +64198,7,2,2,76,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,12863.404053,14275.35524,2,90,3,3,0.92,1,1,0,0,1,2,76,1,3,2,NA +64199,7,2,2,2,NA,2,2,2,2,35,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8512.480199,8626.96297,2,90,3,3,0.68,2,2,1,0,0,2,23,1,1,5,NA +64200,7,2,2,3,NA,2,2,2,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15233.991221,16407.076559,1,98,3,3,0.4,7,7,2,3,0,2,31,2,5,1,2 +64201,7,2,1,20,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,9177.295801,9548.31812,2,92,77,77,NA,4,4,0,0,1,1,20,1,2,5,NA +64202,7,2,1,10,NA,4,4,2,10,127,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9298.536372,9483.411197,2,97,6,6,0.92,7,7,1,4,0,2,29,1,3,5,NA +64203,7,2,1,35,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,15262.313583,16475.41377,1,101,2,2,0.47,3,3,1,0,0,1,35,1,2,6,NA +64204,7,2,2,0,7,3,3,2,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16547.193167,16560.896108,1,97,12,12,NA,5,5,3,0,0,2,33,1,5,1,5 +64205,7,2,2,1,12,4,4,2,NA,12,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7556.585831,7751.634132,1,96,77,77,NA,3,3,1,0,0,2,39,1,7,5,NA +64206,7,2,2,69,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,1,12886.419545,13879.729659,2,101,3,3,1.19,1,1,0,0,1,2,69,1,2,2,NA +64207,7,2,2,28,NA,2,2,2,NA,NA,2,NA,2,2,2,NA,2,1,2,1,2,2,1,2,2,1,2,1,NA,45798.520132,47350.399021,2,91,14,14,4.71,3,3,0,0,0,1,28,2,1,1,2 +64208,7,2,1,15,NA,1,1,1,15,182,NA,NA,2,2,4,8,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,14432.845547,14415.592261,2,103,10,10,1.63,7,7,1,4,0,1,31,NA,NA,1,4 +64209,7,2,1,11,NA,2,2,1,11,133,NA,NA,1,1,NA,4,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,14820.807433,14943.02937,2,102,5,5,0.89,4,4,0,3,0,2,44,2,2,4,NA +64210,7,2,1,3,NA,4,4,2,3,45,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8414.846149,8934.299427,1,90,7,7,1.3,5,5,1,2,1,2,62,1,2,2,NA +64211,7,2,2,1,20,1,1,1,NA,22,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,11582.174418,11621.723611,2,102,8,8,1.28,7,7,1,3,0,1,39,2,1,1,3 +64212,7,2,2,8,NA,5,7,1,8,107,NA,NA,2,1,3,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8128.755281,8532.236543,1,98,9,9,2.39,4,4,0,2,0,2,48,1,5,1,5 +64213,7,2,1,37,NA,1,1,2,NA,NA,2,NA,2,2,77,NA,2,6,NA,2,2,2,2,2,2,2,2,2,2,34887.439952,38610.51698,2,94,77,77,NA,3,3,0,1,0,2,42,2,2,6,NA +64214,7,2,1,18,NA,1,1,1,18,227,2,NA,2,2,3,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,2,24228.858782,24599.205366,2,102,5,5,1.3,3,3,0,0,0,1,42,NA,NA,1,NA +64215,7,2,2,80,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,16494.288293,17728.004854,2,101,2,2,0.77,1,1,0,0,1,2,80,1,1,2,NA +64216,7,2,2,2,24,1,1,1,2,24,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11512.764389,12710.400836,2,98,7,7,2.16,3,3,1,0,0,2,26,1,3,1,3 +64217,7,2,1,53,NA,1,1,1,NA,NA,2,NA,2,2,7,NA,1,1,NA,2,2,1,2,2,2,2,2,2,2,20592.227875,20667.110628,2,96,6,6,0.77,7,7,2,1,0,1,53,2,1,1,1 +64218,7,2,1,53,NA,4,4,2,NA,NA,1,2,2,1,7,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,14699.320127,15747.67742,2,90,15,15,5,4,4,1,1,0,1,53,2,5,1,5 +64219,7,2,2,80,NA,4,4,2,NA,NA,2,NA,2,1,7,NA,1,5,NA,1,2,2,1,2,2,1,2,2,NA,12863.404053,13555.744544,2,90,14,14,4.25,4,4,0,2,1,2,45,2,5,5,NA +64220,7,2,2,24,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,99381.891022,101559.2006,2,92,15,6,2.3,4,1,0,0,0,1,27,NA,NA,5,NA +64221,7,2,1,19,NA,1,1,1,19,239,2,NA,1,1,NA,66,NA,NA,NA,1,2,2,2,2,2,1,2,2,1,20634.3158,20949.718537,2,96,6,6,0.77,7,7,2,1,0,1,53,2,1,1,1 +64222,7,2,1,39,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,105902.251482,110971.270582,3,91,10,10,3.51,3,3,0,1,0,1,39,1,5,1,3 +64223,7,2,2,0,1,3,3,2,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,20239.765739,19690.008753,2,94,9,9,2.51,4,4,2,0,0,1,30,2,4,1,4 +64224,7,2,2,22,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,30275.274308,33292.204257,2,101,2,2,0.64,1,1,0,0,0,2,22,1,4,5,NA +64225,7,2,1,8,NA,3,3,2,8,104,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,50571.965712,52018.055374,2,95,15,15,4.63,5,5,1,2,0,2,36,1,5,1,3 +64226,7,2,1,73,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,NA,73758.836891,83728.230941,2,91,3,3,1.25,1,1,0,0,1,1,73,1,3,5,NA +64227,7,2,2,59,NA,2,2,1,NA,NA,2,NA,2,1,6,NA,4,5,NA,2,2,2,2,2,2,1,2,1,2,24553.193015,24681.235828,2,93,3,3,0.9,1,1,0,0,0,2,59,2,4,5,NA +64228,7,2,1,44,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,146181.198007,184923.777793,2,91,15,15,5,2,1,0,0,0,1,44,1,3,5,NA +64229,7,2,2,50,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,32609.153024,32528.629595,1,98,3,3,0.73,3,3,0,0,0,1,52,1,4,1,3 +64230,7,2,2,2,NA,4,4,1,2,27,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8296.101892,8926.698178,2,96,7,7,1.49,5,5,2,1,0,1,51,1,5,1,3 +64231,7,2,1,68,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,7820.017944,8252.409456,2,98,7,7,2.1,3,3,0,0,1,1,68,1,2,1,9 +64232,7,2,1,0,6,3,3,1,NA,7,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,23912.171644,25599.009772,1,94,9,9,3.14,3,3,1,0,0,1,28,1,5,1,5 +64233,7,2,1,14,NA,4,4,1,15,180,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13731.625553,14361.066702,1,100,6,6,1.13,4,4,0,3,0,2,32,1,3,5,NA +64234,7,2,1,29,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,59682.963348,63262.110969,2,102,15,15,3.92,5,5,0,0,0,1,19,1,4,NA,NA +64235,7,2,2,56,NA,1,1,2,NA,NA,2,NA,1,1,NA,NA,1,6,NA,1,2,2,1,2,2,2,2,2,2,22224.73066,22874.201587,2,94,12,12,NA,2,2,0,0,0,1,46,1,3,1,1 +64236,7,2,1,5,NA,1,1,1,5,62,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,11388.091908,11522.723578,1,103,8,8,1.85,5,5,2,1,0,2,25,2,2,1,2 +64237,7,2,2,16,NA,3,3,2,16,200,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,38400.791741,38900.548719,1,92,4,4,0.5,6,6,0,3,0,2,41,1,4,1,NA +64238,7,2,1,0,2,5,6,1,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,5024.464768,5303.683185,2,92,99,77,NA,7,3,3,3,1,1,61,2,1,1,3 +64239,7,2,1,2,NA,4,4,2,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5396.442999,5408.183432,1,99,4,4,0.53,7,7,3,1,0,2,26,1,1,5,NA +64240,7,2,1,19,NA,1,1,1,19,233,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,23389.620035,23146.524434,1,94,10,10,2.94,4,4,0,2,0,2,52,1,5,2,NA +64241,7,2,2,0,9,3,3,1,NA,10,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6423.658168,6554.989142,2,96,3,3,0.53,5,5,3,0,0,2,26,1,4,1,4 +64242,7,2,2,16,NA,3,3,1,16,199,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,82145.180523,84080.796514,1,98,15,15,5,5,5,0,3,0,2,44,1,5,1,5 +64243,7,2,2,7,NA,3,3,2,7,85,NA,NA,2,1,1,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,52455.416493,51758.830416,1,93,15,15,5,4,4,0,2,0,2,42,1,5,1,NA +64244,7,2,2,40,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,30888.99461,30919.326232,1,99,2,2,0.61,2,2,0,0,0,1,46,1,5,5,NA +64245,7,2,1,51,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,120041.937453,119895.563372,1,98,9,9,2.88,6,3,1,3,0,1,51,1,2,1,3 +64246,7,2,1,14,NA,2,2,2,14,172,NA,NA,2,1,2,7,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,26616.794908,27940.371621,2,91,7,7,2.64,2,2,0,1,0,1,33,2,3,1,NA +64247,7,2,1,42,NA,1,1,1,NA,NA,2,NA,2,2,3,NA,1,1,NA,2,2,2,1,2,2,2,2,2,2,43470.92932,47764.563168,1,92,5,5,0.87,4,4,0,2,0,1,42,2,1,1,4 +64248,7,2,2,38,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,NA,NA,NA,NA,67727.881967,67936.122757,2,99,15,15,5,1,1,0,0,0,2,38,1,5,5,NA +64249,7,1,1,11,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,57057.523607,0,1,101,15,15,5,4,4,0,2,0,2,40,1,4,1,3 +64250,7,2,2,3,NA,1,1,2,3,44,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,13366.393396,13791.68675,2,94,7,7,1.79,4,4,1,1,0,2,32,1,4,1,4 +64251,7,1,1,4,NA,5,6,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7232.559351,0,2,103,14,14,3.86,4,4,2,0,0,2,37,2,5,1,NA +64252,7,2,1,61,NA,2,2,1,NA,NA,2,NA,2,2,5,NA,3,1,NA,2,2,2,1,2,2,1,2,2,2,11019.434708,11234.197915,3,91,5,5,0.89,4,4,0,2,2,1,61,2,3,1,4 +64253,7,2,1,13,NA,5,7,2,13,167,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,5388.361335,5758.757236,3,91,15,15,4.47,4,4,0,3,0,2,44,2,5,1,NA +64254,7,2,1,0,8,1,1,1,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,6910.953528,6911.08091,2,96,4,4,0.81,3,3,1,0,0,2,37,2,5,1,3 +64255,7,2,1,23,NA,5,6,1,NA,NA,2,NA,2,2,1,NA,4,5,NA,1,2,2,1,2,2,1,2,2,3,13859.220514,14321.474311,1,98,12,14,5,3,1,0,0,0,1,24,1,4,5,NA +64256,7,2,2,67,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,1,11523.037911,11989.050618,2,97,6,6,2.31,2,2,0,0,1,2,67,1,3,2,NA +64257,7,2,2,23,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,53047.531099,53521.812192,1,99,2,1,0.18,2,1,0,0,0,2,24,1,5,5,NA +64258,7,2,2,13,NA,5,6,1,13,163,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12918.122917,13476.480232,1,92,10,10,2.82,4,4,0,2,0,2,48,2,5,1,5 +64259,7,2,2,35,NA,1,1,2,NA,NA,2,NA,2,2,5,NA,2,1,2,2,2,2,1,2,2,2,2,2,2,35353.005268,36099.35979,2,94,6,6,1.34,4,4,0,2,0,1,37,2,4,1,2 +64260,7,2,2,17,NA,4,4,2,17,214,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11438.127668,11466.298034,2,97,6,6,1.02,6,6,1,2,0,1,37,1,3,1,3 +64261,7,2,1,67,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,1,NA,1,2,1,1,2,2,1,2,1,NA,13639.016686,14339.363246,2,102,15,15,5,5,5,1,0,2,1,30,1,4,1,5 +64262,7,2,2,6,NA,4,4,2,6,79,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10225.297464,10592.094499,1,93,2,2,0.32,3,3,0,1,0,1,25,1,3,6,NA +64263,7,2,2,62,NA,1,1,1,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,2,2,2,2,9203.46153,9587.572248,2,97,6,6,1.7,2,2,0,0,1,2,62,2,5,1,2 +64264,7,2,1,14,NA,4,4,2,15,180,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8364.097643,8526.060452,2,90,6,6,0.96,5,5,0,1,0,1,55,1,4,6,NA +64265,7,2,1,48,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,27087.386131,27212.215064,1,101,6,6,1.43,4,4,0,1,2,2,72,1,2,1,NA +64266,7,2,1,31,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,90274.900586,93718.683628,2,99,15,15,5,2,1,0,0,0,1,31,1,5,6,NA +64267,7,2,2,10,NA,4,4,2,10,129,NA,NA,2,2,3,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7136.421849,7524.490259,1,90,4,4,0.58,6,6,0,3,0,2,21,2,5,5,NA +64268,7,2,2,11,NA,4,4,1,11,135,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12476.900945,13434.365665,2,101,2,2,0.38,3,3,0,2,0,2,56,1,3,2,NA +64269,7,1,1,61,NA,1,1,NA,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,9611.684527,0,1,98,7,7,1.52,4,4,0,1,2,1,61,1,4,1,2 +64270,7,2,2,47,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,27934.372045,28667.797605,1,101,5,5,1.15,3,3,0,1,0,1,49,1,3,1,4 +64271,7,2,2,24,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,45549.853584,49025.946555,3,91,3,3,0.76,3,3,0,1,0,2,24,1,4,6,NA +64272,7,2,2,19,NA,4,4,2,19,239,2,NA,2,2,2,12,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12209.74498,12386.615954,2,90,6,6,1.34,4,4,1,0,0,1,38,2,4,6,NA +64273,7,2,1,5,NA,4,4,2,5,62,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9242.457181,9624.356732,2,97,5,5,0.76,5,5,1,2,0,1,32,1,4,6,NA +64274,7,2,1,0,3,1,1,1,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,1,1,2,1,NA,NA,NA,NA,7757.493251,7980.837709,2,98,3,3,0.4,6,6,1,2,0,2,29,2,1,4,NA +64275,7,1,1,62,NA,5,6,NA,NA,NA,2,NA,2,1,6,NA,4,4,NA,1,2,2,1,2,2,NA,NA,NA,NA,10288.337394,0,3,91,8,8,4.13,1,1,0,0,1,1,62,2,4,4,NA +64276,7,2,1,50,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,23857.322871,23507.253435,1,103,1,1,0.03,3,3,0,0,0,1,50,1,2,3,NA +64277,7,2,2,48,NA,1,1,1,NA,NA,2,NA,2,2,3,NA,2,6,NA,2,2,2,2,2,2,2,2,2,2,36924.381422,39366.592716,2,102,7,7,1.89,3,3,0,1,0,1,41,2,2,6,NA +64278,7,2,2,18,NA,2,2,2,18,226,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13824.001771,14551.102227,2,90,5,5,1.19,3,3,0,0,0,2,50,2,4,4,NA +64279,7,2,1,11,NA,3,3,2,11,137,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,52386.010737,55389.865547,3,91,14,14,3.4,4,4,0,2,0,1,40,1,4,1,4 +64280,7,2,1,3,NA,4,4,2,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7014.280192,7545.08247,2,99,15,15,4.9,7,7,1,4,0,2,53,1,5,1,5 +64281,7,2,1,44,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,34000.722046,33736.711001,2,93,14,14,3.52,5,5,1,2,0,1,44,1,5,1,5 +64282,7,2,1,2,NA,4,4,2,2,26,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6074.284591,6449.253661,2,99,3,3,0.32,6,6,2,1,1,2,59,1,4,1,NA +64283,7,2,1,5,NA,4,4,1,5,69,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9016.053035,9035.668246,2,100,3,3,0.31,7,7,3,2,0,2,28,1,3,1,3 +64284,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,35434.580514,38808.357492,1,101,1,1,0.18,1,1,0,0,1,2,80,1,4,2,NA +64285,7,2,1,7,NA,1,1,2,7,92,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16334.967392,17408.274993,1,95,5,5,1.5,2,2,0,1,0,1,47,1,4,2,NA +64286,7,2,2,56,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,16109.317112,16194.502254,1,103,15,15,5,2,2,0,0,1,2,56,2,5,1,5 +64287,7,2,1,7,NA,3,3,2,7,89,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,24713.905595,26080.214484,1,98,6,6,0.97,7,7,1,2,0,1,49,1,2,1,2 +64288,7,2,2,41,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,31809.199771,32336.174545,2,103,9,9,3.97,2,2,0,0,1,1,61,1,5,1,3 +64289,7,2,2,0,3,3,3,1,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,23207.538828,22577.170535,1,94,6,6,1.21,4,4,2,0,0,1,27,1,4,1,3 +64290,7,2,2,65,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,10346.035773,10598.2543,1,99,10,10,2.07,7,7,2,3,1,2,35,1,5,4,NA +64291,7,2,1,50,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,22238.49412,25006.164622,2,90,4,4,1.38,1,1,0,0,0,1,50,1,3,3,NA +64292,7,2,1,45,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,4,NA,1,2,2,1,2,2,1,2,2,1,21924.03349,22615.591521,3,92,2,2,0.65,2,2,0,0,1,2,80,NA,NA,2,NA +64293,7,2,2,4,NA,3,3,1,4,52,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,53166.229434,56500.79967,1,101,7,7,1.55,5,5,1,2,0,2,31,1,4,1,2 +64294,7,2,1,19,NA,2,2,2,19,234,2,NA,2,1,4,15,NA,NA,NA,1,2,2,2,2,2,1,2,2,1,17149.002427,17445.048827,3,90,77,77,NA,4,3,0,0,0,1,45,2,3,3,NA +64295,7,2,1,10,NA,3,3,1,11,133,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,NA,NA,NA,1,2,2,1,69959.431608,85622.357277,2,100,NA,NA,NA,5,5,1,2,0,1,36,NA,NA,3,NA +64296,7,2,2,40,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,2,1,2,1,2,2,1,2,2,NA,NA,NA,NA,33716.655399,36032.83001,1,100,8,8,2.17,4,4,1,1,0,2,40,2,2,1,2 +64297,7,1,2,9,NA,1,1,NA,NA,NA,NA,NA,1,1,NA,3,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,15002.25457,0,1,91,7,7,2.72,2,2,0,1,0,2,31,1,2,5,NA +64298,7,2,2,68,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,10991.458112,11482.21496,2,99,10,10,4.76,2,2,0,0,2,1,80,1,2,2,NA +64299,7,2,1,65,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,95606.814645,96503.477057,2,98,15,15,5,2,2,0,0,1,2,52,1,4,1,4 +64300,7,1,2,6,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11035.074625,0,2,100,1,1,0.04,4,4,0,2,0,1,34,NA,NA,6,NA +64301,7,2,2,73,NA,5,7,1,NA,NA,2,NA,2,1,8,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,12813.709202,13258.116643,2,103,12,12,NA,2,2,0,0,2,1,73,2,5,1,4 +64302,7,2,1,45,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,136880.768184,139080.782402,1,94,15,15,4.95,4,4,0,0,2,1,72,1,3,1,3 +64303,7,1,2,77,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,81395.297807,0,1,92,4,4,1.61,1,1,0,0,1,2,77,1,3,2,NA +64304,7,2,2,0,5,1,1,1,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8359.077295,8583.668456,3,92,5,5,0.81,5,5,3,0,0,2,23,1,4,5,NA +64305,7,2,2,41,NA,4,4,2,NA,NA,2,NA,2,1,6,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,14831.744106,14468.205243,3,90,10,10,3.67,3,3,0,1,0,2,52,2,3,5,NA +64306,7,2,2,2,NA,4,4,2,2,28,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7826.463896,8746.031629,1,96,6,6,1.21,4,4,2,0,0,1,24,1,4,1,3 +64307,7,2,2,24,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,102855.726146,106395.504024,1,101,7,7,1.74,4,4,1,0,0,1,24,NA,NA,1,4 +64308,7,2,2,31,NA,2,2,1,NA,NA,2,NA,2,2,77,NA,1,6,2,2,2,2,1,2,2,2,2,2,2,32097.38481,33124.257579,2,100,3,3,0.76,3,3,1,0,0,2,31,2,1,6,NA +64309,7,2,2,78,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,53541.401974,54961.757487,1,99,13,13,NA,2,2,0,0,2,1,80,1,2,1,3 +64310,7,2,2,49,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,163194.688032,170363.320524,1,97,15,15,5,2,2,0,0,1,2,49,1,5,1,3 +64311,7,2,1,54,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,17636.923031,18334.929229,2,97,15,14,5,2,1,0,0,0,1,54,1,4,5,NA +64312,7,2,1,80,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,42993.150248,46481.579201,1,92,7,7,2.64,2,2,0,0,2,2,68,1,4,1,4 +64313,7,2,1,65,NA,1,1,1,NA,NA,2,NA,2,1,8,NA,3,6,NA,2,2,2,2,2,2,2,2,2,2,14067.170863,14736.245577,2,102,14,8,4.59,2,1,0,0,2,1,65,2,3,6,NA +64314,7,2,1,6,NA,1,1,2,6,73,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,13285.093011,13495.322435,2,94,6,6,1.5,4,4,0,2,0,1,44,2,2,1,2 +64315,7,2,2,52,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,147501.330925,150787.451601,1,101,6,6,1.31,3,3,0,0,1,2,80,1,1,2,NA +64316,7,2,2,12,NA,4,4,1,12,155,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18163.985724,18749.311901,2,101,6,6,1.16,4,4,0,3,0,2,36,1,4,4,NA +64317,7,2,2,18,NA,3,3,1,18,222,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,32725.110579,34226.88515,2,92,3,2,0.64,2,1,0,0,0,2,18,1,4,NA,NA +64318,7,2,2,14,NA,4,4,2,14,176,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13790.410898,14648.625582,1,93,7,7,1.79,4,4,0,2,0,1,53,2,4,1,4 +64319,7,2,2,14,NA,5,6,2,14,174,NA,NA,2,1,4,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8675.8731,8857.654394,1,96,15,15,5,4,4,0,2,0,2,41,2,5,1,5 +64320,7,2,1,14,NA,4,4,2,14,171,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17606.165994,18413.211403,2,101,13,3,0.64,5,4,0,3,1,2,62,1,1,2,NA +64321,7,2,1,12,NA,3,3,1,13,156,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,90320.117415,93226.168932,1,100,15,15,5,4,4,0,2,0,2,47,1,5,1,5 +64322,7,2,1,8,NA,3,3,1,8,107,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,41342.668304,42524.849071,1,102,8,8,2.42,4,4,0,2,0,2,34,1,4,1,3 +64323,7,2,1,3,NA,1,1,1,3,44,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,17865.135763,18076.339981,3,92,1,1,0,5,5,3,0,0,1,26,1,2,1,2 +64324,7,2,2,28,NA,1,1,2,NA,NA,2,NA,2,2,4,NA,1,1,2,2,2,2,2,2,2,2,2,2,2,38364.674202,40512.730459,2,97,13,13,NA,3,3,0,1,0,1,28,2,2,1,1 +64325,7,2,1,44,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,1,2,1,2,2,1,2,2,NA,108408.375382,111473.582646,2,98,14,14,4.16,3,3,0,0,0,1,49,1,5,1,4 +64326,7,2,1,29,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,90303.174138,94631.352733,2,92,14,9,5,2,1,0,0,0,1,29,1,5,6,NA +64327,7,2,1,9,NA,3,3,2,9,113,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,30554.050397,31755.009616,1,97,3,3,0.93,2,2,0,1,0,2,34,1,4,5,NA +64328,7,2,1,78,NA,1,1,2,NA,NA,2,NA,2,2,4,NA,1,1,NA,2,2,2,2,2,2,NA,NA,NA,NA,13523.396212,13874.942566,2,94,2,2,0.56,2,2,0,0,2,2,71,2,2,1,1 +64329,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,34049.658577,35975.208577,1,91,9,9,4.27,2,2,0,0,2,1,80,1,4,1,3 +64330,7,2,1,43,NA,5,7,2,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,126789.52929,129656.862785,1,101,15,15,5,4,4,0,2,0,1,43,1,4,1,5 +64331,7,2,1,16,NA,3,3,1,16,197,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,59545.101745,58762.542429,1,102,8,8,1.6,7,7,0,4,0,2,39,1,4,1,4 +64332,7,2,1,20,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,17579.006909,17715.920575,2,103,2,1,0.43,2,1,0,0,0,1,20,1,3,6,NA +64333,7,2,1,46,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,3,3,NA,1,2,2,1,2,2,1,2,2,3,20197.354438,20825.605262,2,96,5,5,1.84,2,1,0,0,1,1,46,2,3,3,NA +64334,7,2,1,6,NA,2,2,2,6,80,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,11477.372934,11658.996164,1,93,9,9,2.46,4,4,0,2,0,1,35,2,1,1,1 +64335,7,2,2,27,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,6,2,1,2,2,NA,NA,NA,1,2,2,1,43813.24867,46884.227528,1,98,NA,NA,NA,4,4,0,2,0,1,31,NA,NA,1,2 +64336,7,2,1,31,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,19869.518693,21796.765593,1,94,7,7,1.21,6,6,2,2,0,1,31,1,2,6,NA +64337,7,2,1,21,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,42894.724338,43561.362107,1,98,3,3,0.93,2,2,0,0,0,1,21,1,4,5,NA +64338,7,1,2,46,NA,1,1,NA,NA,NA,2,NA,2,2,6,NA,1,6,NA,2,2,2,1,2,2,NA,NA,NA,NA,40337.933888,0,2,94,5,5,0.65,6,6,0,2,0,1,53,NA,NA,6,NA +64339,7,2,1,6,NA,2,2,1,6,76,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,12604.990052,13551.632975,1,103,7,7,1.03,7,7,0,3,0,1,50,2,1,1,1 +64340,7,1,1,80,NA,3,3,NA,NA,NA,1,1,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,9443.12441,0,1,99,77,77,NA,2,2,0,0,2,1,80,1,5,1,4 +64341,7,2,2,51,NA,2,2,1,NA,NA,2,NA,2,1,7,NA,2,1,NA,2,2,2,1,2,2,2,2,1,2,23200.373382,24548.135184,2,93,7,7,2.1,3,3,0,1,0,2,51,2,2,1,NA +64342,7,2,1,12,NA,3,3,2,12,146,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,103364.662244,103614.262032,1,98,14,14,3.15,5,5,0,3,0,1,34,1,4,1,4 +64343,7,2,1,63,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,1,84821.217572,87190.888968,2,91,15,15,4.2,6,6,2,0,2,1,63,1,1,1,3 +64344,7,2,1,37,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,28213.419452,30402.035877,1,100,14,5,1.79,2,1,0,0,0,1,37,1,2,6,NA +64345,7,2,1,21,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,21763.209029,22385.504537,2,92,4,1,0.18,4,1,0,0,0,1,21,1,4,5,NA +64346,7,2,1,3,NA,5,7,1,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8402.098771,9423.873047,3,91,14,14,4.32,3,3,1,0,0,1,31,2,3,1,4 +64347,7,2,1,50,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,32720.69734,32838.149884,1,95,1,1,0,1,1,0,0,0,1,50,1,3,5,NA +64348,7,2,2,13,NA,3,3,1,13,158,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,105891.533689,107879.366927,1,101,8,8,1.85,5,5,0,3,0,1,41,1,3,1,4 +64349,7,2,2,24,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,NA,NA,NA,1,2,2,1,11475.373333,11965.391974,2,92,12,NA,NA,7,1,0,0,2,1,53,2,3,1,3 +64350,7,2,1,12,NA,4,4,2,12,145,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11351.725436,12116.15399,2,95,7,7,1.55,5,5,0,3,0,1,30,1,4,1,4 +64351,7,2,1,32,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,18353.275855,19744.388768,1,91,4,4,0.81,4,4,1,1,0,1,32,1,4,6,NA +64352,7,2,2,2,NA,4,4,2,2,27,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6085.457443,6422.142601,1,99,7,7,1.53,5,5,2,0,0,2,37,1,4,1,3 +64353,7,2,1,0,11,2,2,2,NA,12,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7973.737542,8118.415368,1,91,7,7,1.66,4,4,2,0,0,1,32,2,5,1,4 +64354,7,2,2,80,NA,2,2,1,NA,NA,2,NA,2,1,4,NA,1,2,NA,2,2,2,1,2,2,1,2,2,NA,21122.17432,23417.039872,2,93,6,6,0.64,7,7,2,1,3,2,60,2,3,2,NA +64355,7,1,2,27,NA,2,2,NA,NA,NA,2,NA,1,1,NA,NA,4,6,3,1,2,2,2,2,2,NA,NA,NA,NA,42583.505439,0,2,91,6,6,1.3,4,4,1,1,0,2,27,1,4,6,NA +64356,7,2,1,20,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,39915.513053,41236.907607,2,98,7,7,1.33,6,6,0,3,0,1,31,1,3,6,NA +64357,7,1,2,1,22,2,2,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9670.78354,0,2,93,15,15,5,4,4,2,0,0,1,34,1,5,1,5 +64358,7,2,1,5,NA,4,4,2,5,67,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,NA,NA,NA,NA,NA,NA,NA,8005.528865,8250.049428,1,99,NA,NA,NA,4,4,1,1,0,1,42,NA,NA,1,NA +64359,7,2,1,24,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,25815.880139,26556.735732,2,101,99,2,0.73,2,1,0,0,0,1,24,1,4,5,NA +64360,7,2,2,54,NA,1,1,1,NA,NA,2,NA,2,2,99,NA,1,1,NA,2,2,2,2,2,2,2,2,2,2,21939.007884,22053.417944,1,100,99,99,NA,7,7,2,3,0,2,35,2,1,1,NA +64361,7,2,2,16,NA,5,6,2,16,199,NA,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,8301.172828,8662.397073,1,91,15,15,5,3,3,0,1,0,2,47,2,5,1,5 +64362,7,2,1,68,NA,4,4,2,NA,NA,2,NA,2,2,8,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,8491.292032,8823.40317,1,96,6,6,2.06,2,2,0,0,2,1,68,2,3,1,2 +64363,7,2,1,22,NA,5,6,2,NA,NA,2,NA,2,1,3,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,14313.345971,17701.114982,3,91,14,14,3.53,5,5,0,1,1,1,69,1,4,3,NA +64364,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,NA,38976.947883,43357.400647,1,99,12,12,NA,1,1,0,0,1,2,80,1,3,3,NA +64365,7,2,2,5,NA,2,2,1,5,63,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,14852.990935,14903.708855,3,92,7,7,0.93,7,7,1,3,0,2,20,1,3,1,1 +64366,7,2,1,4,NA,4,4,2,4,59,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10234.881417,10547.495238,2,97,2,2,0.33,4,4,2,1,0,2,34,1,2,5,NA +64367,7,2,2,39,NA,5,6,2,NA,NA,2,NA,2,1,4,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,20039.469886,21581.359058,1,97,15,15,5,4,4,1,0,0,2,39,2,5,1,5 +64368,7,2,1,70,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,1,3,NA,1,2,2,1,2,2,1,2,2,NA,8497.912951,8999.288803,2,100,2,2,0.77,1,1,0,0,1,1,70,1,1,3,NA +64369,7,2,1,51,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,17824.805721,17767.952896,2,95,4,2,0.55,2,1,0,0,0,2,47,1,3,4,NA +64370,7,2,1,25,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,25890.025676,30408.154535,2,93,3,3,1.25,1,1,0,0,0,1,25,1,4,5,NA +64371,7,2,2,51,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,18441.731082,18102.807884,1,96,15,9,4.92,2,1,0,0,0,2,55,1,4,5,NA +64372,7,2,2,19,NA,4,4,2,19,232,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13176.946531,13078.313981,2,99,9,9,1.78,6,6,1,1,0,1,46,1,3,6,NA +64373,7,2,2,6,NA,3,3,2,6,78,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,41790.228676,44382.642913,2,94,7,7,1.17,6,6,0,3,0,1,40,1,3,1,5 +64374,7,2,2,52,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,10700.939986,11250.682738,1,99,15,15,4.47,4,4,0,2,0,2,52,2,5,1,5 +64375,7,2,2,14,NA,2,2,2,14,175,NA,NA,1,1,NA,9,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,14437.97544,15197.369043,2,90,5,5,0.8,5,5,0,3,0,2,40,2,1,5,NA +64376,7,2,1,58,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,32720.69734,34296.120763,1,95,3,3,0.65,3,3,1,0,0,1,58,1,3,3,NA +64377,7,2,2,54,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,1,19060.786733,19867.822877,2,97,5,5,0.92,5,5,0,3,0,2,54,1,3,2,NA +64378,7,2,1,27,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,115391.113177,120921.742093,1,102,14,7,3.31,2,1,0,0,0,1,27,1,4,5,NA +64379,7,2,2,20,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,30275.274308,30320.430859,2,101,4,3,1.15,2,1,0,0,0,2,22,1,4,5,NA +64380,7,2,2,22,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,NA,NA,NA,NA,114993.808573,116714.079488,1,98,7,3,0.9,4,1,0,0,0,2,20,NA,NA,5,NA +64381,7,2,2,61,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,148725.079159,151155.002758,2,94,15,15,5,2,2,0,0,2,1,63,1,5,1,5 +64382,7,2,1,24,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,4,6,NA,1,2,2,1,2,2,1,2,2,3,14385.653726,15533.829525,2,101,6,1,0.22,2,1,0,0,0,2,26,2,4,6,NA +64383,7,2,2,26,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,4,2,1,2,2,1,2,2,1,2,2,1,19658.218913,18995.471706,1,99,13,13,NA,4,4,1,0,0,2,26,1,4,4,NA +64384,7,2,1,0,5,3,3,1,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,24315.386145,24328.135897,1,102,6,6,1.23,4,4,2,0,0,2,25,1,5,1,5 +64385,7,2,2,13,NA,5,6,1,13,160,NA,NA,2,1,3,6,NA,NA,NA,1,1,2,1,2,1,1,2,2,1,8878.081187,9740.503961,3,92,77,77,NA,7,7,2,4,1,1,62,NA,NA,1,NA +64386,7,2,2,9,NA,1,1,1,10,121,NA,NA,2,2,3,2,NA,NA,NA,2,1,1,1,2,1,1,2,2,1,16397.644545,16823.243233,1,91,7,7,2.1,3,3,0,1,0,2,29,2,3,6,NA +64387,7,2,1,71,NA,5,6,2,NA,NA,2,NA,2,2,7,NA,5,1,NA,1,2,1,1,2,1,1,2,1,NA,9748.579573,10638.31203,3,90,9,9,2.93,3,3,0,0,2,1,71,2,5,1,4 +64388,7,2,1,69,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,8232.241159,8296.636338,2,98,5,5,2.2,1,1,0,0,1,1,69,1,4,3,NA +64389,7,2,1,10,NA,1,1,1,10,128,NA,NA,1,1,NA,4,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,9485.228453,10197.575258,1,103,10,10,2.82,4,4,0,2,0,1,41,2,1,1,1 +64390,7,2,2,45,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,18494.181242,18934.264494,2,99,4,4,0.78,4,4,0,2,0,2,45,1,3,5,NA +64391,7,2,2,26,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,5,6,2,1,2,2,1,2,2,1,2,2,1,36731.516901,42296.380247,1,99,10,6,2.75,2,1,0,0,0,1,31,1,4,6,NA +64392,7,2,1,10,NA,3,3,2,10,126,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,46228.073505,48314.890943,2,94,5,5,0.89,4,4,0,2,0,2,51,1,2,3,NA +64393,7,2,2,16,NA,4,4,1,17,204,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,14166.687432,14623.20249,1,100,15,15,3.87,6,6,1,3,0,2,39,1,4,1,4 +64394,7,2,2,2,NA,1,1,2,2,35,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,8082.096138,8109.693752,1,90,4,4,0.46,7,7,2,3,0,2,34,2,1,6,NA +64395,7,2,1,6,NA,3,3,2,6,78,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,58159.917125,59822.981903,3,92,15,15,5,4,4,0,2,0,2,38,1,5,1,5 +64396,7,2,2,51,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,162038.12624,162493.980108,1,94,77,77,NA,1,1,0,0,0,2,51,1,3,3,NA +64397,7,2,2,54,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,15714.689474,15797.787849,2,99,15,15,5,1,1,0,0,0,2,54,1,5,5,NA +64398,7,2,1,4,NA,4,4,1,4,55,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14467.4421,15952.720644,2,101,5,5,1.19,3,3,1,0,0,2,32,1,4,1,3 +64399,7,2,2,45,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,26763.110196,36351.891896,2,94,3,3,0.95,2,2,0,1,0,2,45,1,5,3,NA +64400,7,2,2,61,NA,1,1,1,NA,NA,2,NA,2,2,6,NA,1,1,NA,2,2,2,2,2,2,2,2,2,2,11623.354795,12210.370942,1,94,6,6,1.98,2,2,0,0,2,1,65,2,1,1,1 +64401,7,2,1,29,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,29537.209125,29019.340657,1,95,12,3,1.19,4,1,0,0,0,1,29,1,3,6,NA +64402,7,2,1,48,NA,1,1,2,NA,NA,2,NA,2,2,6,NA,5,1,NA,2,2,2,2,2,2,1,2,2,2,27776.016947,27368.446715,2,90,6,6,1.15,5,5,0,2,0,2,47,2,1,1,5 +64403,7,2,1,40,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,1,22685.373982,24056.024455,1,98,4,4,1,3,3,0,1,1,1,65,1,2,1,NA +64404,7,2,1,33,NA,3,3,2,NA,NA,2,NA,2,2,2,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,99283.360764,105383.970589,3,91,8,8,3.4,2,2,0,0,0,1,33,2,5,1,4 +64405,7,2,1,78,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,1,1,NA,1,2,1,1,2,1,1,2,1,NA,11550.158096,12480.92393,2,92,3,3,0.4,6,6,0,1,2,1,78,2,1,1,1 +64406,7,2,1,18,NA,5,6,2,18,219,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,6999.347953,8045.308483,3,90,6,6,1.3,4,4,0,0,0,1,55,2,1,1,1 +64407,7,2,1,54,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,17801.655316,18085.793361,2,95,6,6,0.97,6,6,2,1,0,1,54,1,3,6,NA +64408,7,2,2,15,NA,4,4,2,15,184,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13124.737024,13087.755238,2,101,5,5,1.08,3,3,0,1,1,2,62,1,4,2,NA +64409,7,2,1,7,NA,4,4,2,7,88,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7886.48532,7943.675078,1,99,8,8,1.76,5,5,0,2,1,1,37,1,4,1,3 +64410,7,2,2,13,NA,2,2,2,13,160,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,16360.434077,17220.943159,1,94,14,14,3.4,5,5,0,3,0,2,41,1,4,1,4 +64411,7,2,1,37,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,18745.208345,19348.815401,1,92,7,7,2.1,3,3,0,0,2,1,37,2,5,5,NA +64412,7,2,2,54,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,27553.988486,28260.692091,2,98,3,3,0.93,1,1,0,0,0,2,54,1,3,3,NA +64413,7,2,2,48,NA,2,2,2,NA,NA,2,NA,2,1,7,NA,2,5,NA,2,2,2,2,2,2,1,2,2,2,25778.164795,26907.837256,2,90,1,1,0.22,3,3,0,1,0,2,48,2,2,5,NA +64414,7,2,2,1,23,3,3,1,NA,23,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,17516.090261,18614.694278,1,98,2,2,0.36,5,5,3,0,0,1,25,1,3,1,3 +64415,7,2,2,55,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,18525.3583,18971.375925,1,92,14,14,3.9,4,4,0,0,0,2,55,2,5,1,5 +64416,7,2,1,6,NA,5,6,2,6,81,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10810.913614,11522.32071,1,97,7,7,1.48,5,5,1,2,0,1,40,2,5,1,4 +64417,7,2,2,20,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,135384.418391,141422.067719,1,98,15,15,5,3,3,0,0,0,1,48,1,4,1,4 +64418,7,2,2,17,NA,3,3,1,17,211,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,80091.55101,82618.226829,1,98,6,6,1.11,5,5,0,2,1,2,37,1,1,1,1 +64419,7,2,2,63,NA,1,1,1,NA,NA,2,NA,2,1,7,NA,1,1,NA,2,2,2,2,2,2,1,2,2,2,16352.915834,17178.789759,3,92,5,5,1.26,3,3,0,0,2,1,76,2,1,1,1 +64420,7,2,2,54,NA,4,4,2,NA,NA,2,NA,2,2,6,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,17928.412795,17976.980061,1,90,15,15,4.34,4,4,0,0,1,1,62,2,5,1,3 +64421,7,2,2,2,NA,4,4,1,2,27,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8754.193667,9419.610037,2,98,8,8,1.8,5,5,2,1,0,1,32,1,4,1,5 +64422,7,2,1,16,NA,2,2,2,16,197,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,2,2,2,1,2,2,1,15351.501195,16874.029415,2,90,1,1,0.22,3,3,0,1,0,2,48,2,2,5,NA +64423,7,2,2,12,NA,4,4,1,12,151,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12826.497818,12890.123626,2,96,3,3,0.38,5,5,1,2,0,2,30,1,3,5,NA +64424,7,2,1,0,6,3,3,2,NA,7,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,25469.602005,25029.287945,2,91,15,15,5,3,3,1,0,0,1,35,1,5,1,5 +64425,7,2,2,7,NA,5,6,2,7,92,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7722.982971,8635.133042,1,93,8,8,2.24,4,4,0,2,0,1,44,2,5,1,4 +64426,7,2,2,0,1,4,4,2,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4412.61884,4541.653777,1,93,7,7,1.97,4,4,1,2,0,2,33,1,4,3,NA +64427,7,2,1,37,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,105412.227726,111169.022023,2,101,15,15,5,3,3,1,0,0,1,37,1,5,1,5 +64428,7,2,1,7,NA,5,6,1,7,86,NA,NA,2,1,2,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9101.455527,9700.372536,2,102,8,8,1.72,5,5,0,2,1,1,63,2,5,1,5 +64429,7,2,1,4,NA,5,6,2,4,52,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6185.185728,6767.562311,1,97,14,14,2.29,7,7,1,2,2,1,40,2,1,1,1 +64430,7,2,1,65,NA,5,7,2,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,7415.090784,7473.093956,2,95,12,12,NA,3,3,0,0,2,1,65,1,4,1,4 +64431,7,2,2,32,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,42468.064168,43146.583227,2,101,5,5,1.19,3,3,1,0,0,2,32,1,4,1,3 +64432,7,2,2,12,NA,4,4,1,12,146,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,16598.888685,16552.117725,2,102,5,5,0.76,5,5,1,3,0,2,30,1,4,4,NA +64433,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,1,2,NA,6882.452425,7271.66356,1,99,6,6,1.12,4,4,0,0,2,1,51,1,4,3,NA +64434,7,2,2,7,NA,3,3,2,7,86,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,56541.371473,55790.525616,2,94,3,3,0.82,2,2,0,1,0,2,38,1,5,3,NA +64435,7,2,1,16,NA,5,7,2,16,196,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,9136.388281,9719.077424,3,91,8,8,2.24,4,4,0,2,0,1,45,1,4,1,4 +64436,7,2,2,34,NA,2,2,2,NA,NA,2,NA,2,1,6,NA,5,6,2,1,2,2,1,2,2,1,2,2,1,27127.983961,27837.333201,2,90,14,14,3.45,4,4,1,1,0,2,34,2,5,6,NA +64437,7,2,2,21,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,1,5,2,1,2,2,1,2,2,1,2,2,1,19520.240895,25185.107635,2,95,2,2,0.33,2,2,1,0,0,2,21,1,1,5,NA +64438,7,2,2,44,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,4,3,2,1,2,2,1,2,2,1,2,2,1,25774.834017,34018.000767,1,100,8,8,3.3,2,2,0,1,0,2,44,1,4,3,NA +64439,7,2,1,53,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,148039.171547,149225.244125,2,98,15,15,5,2,2,0,0,0,2,52,1,3,1,4 +64440,7,2,1,40,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,24506.160629,24417.630409,1,92,77,77,NA,2,2,0,0,1,1,40,2,5,5,NA +64441,7,2,1,0,1,4,4,1,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7867.225786,8217.805417,3,92,6,6,0.93,5,5,2,1,0,2,37,1,5,1,3 +64442,7,1,1,61,NA,1,1,NA,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,8390.796678,0,3,92,7,7,2.45,2,2,0,0,1,2,55,1,1,1,1 +64443,7,2,2,2,NA,4,4,2,2,29,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7567.81858,8250.001805,2,97,7,7,1.06,7,7,1,2,0,2,40,1,4,5,NA +64444,7,2,1,18,NA,3,3,2,18,223,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,74123.161671,78732.269389,1,93,15,15,4.59,4,4,0,1,0,1,57,1,5,1,5 +64445,7,1,2,3,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11353.600279,0,1,98,15,15,5,6,6,3,0,0,1,37,2,5,1,4 +64446,7,2,1,47,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,105141.812429,104871.724763,1,98,7,7,1.66,5,5,2,1,0,2,37,1,5,1,3 +64447,7,2,2,41,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,27934.372045,33663.467631,1,101,4,4,0.58,6,6,0,4,0,2,41,1,3,5,NA +64448,7,2,1,0,0,3,3,1,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,22215.410216,21831.35406,2,98,14,14,4.32,3,3,1,0,0,1,26,1,4,6,NA +64449,7,2,2,18,NA,5,6,1,18,217,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,10312.363668,10584.186706,2,102,10,10,3.62,3,3,0,0,0,1,51,2,5,1,5 +64450,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,9845.894687,11807.30791,2,94,14,14,3.58,4,4,1,0,1,1,80,1,3,2,NA +64451,7,2,1,32,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,18464.039593,21965.968723,1,101,6,6,2.51,2,1,0,0,0,1,32,1,4,6,NA +64452,7,2,1,0,10,2,2,1,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7284.164858,7284.299119,1,92,6,6,1.67,3,3,1,0,0,1,27,1,3,6,NA +64453,7,2,2,5,NA,4,4,1,5,66,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15449.848607,17265.123353,2,102,1,1,0.16,3,3,1,0,1,2,63,1,2,4,NA +64454,7,2,2,4,NA,5,7,1,4,55,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13130.790087,14128.876607,2,102,14,14,3.25,5,5,1,1,0,2,32,1,4,1,3 +64455,7,2,1,6,NA,4,4,1,6,77,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12399.014378,12645.533348,2,96,6,6,1.35,3,3,1,1,0,2,25,1,3,5,NA +64456,7,2,2,31,NA,2,2,1,NA,NA,2,NA,2,1,6,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,32097.38481,32019.876048,2,100,14,14,3.58,4,4,1,1,0,1,33,1,4,1,5 +64457,7,1,2,14,NA,2,2,NA,NA,NA,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,20322.312754,0,2,91,6,6,0.93,5,5,1,2,0,2,50,2,1,5,NA +64458,7,2,1,4,NA,2,2,1,4,59,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16775.083123,17533.373205,2,98,6,6,0.78,7,7,1,3,1,2,63,1,2,4,NA +64459,7,2,2,55,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,129553.609875,132943.624501,2,95,10,10,4.49,2,2,0,0,1,1,62,NA,NA,1,3 +64460,7,2,1,10,NA,3,3,2,10,122,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,46081.129115,48091.57352,2,95,5,5,0.87,4,4,1,1,0,1,34,1,3,6,NA +64461,7,2,2,34,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,24919.497762,25578.256222,1,101,1,1,0.1,4,4,1,1,0,2,52,1,4,3,NA +64462,7,2,1,12,NA,4,4,1,13,157,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12147.046136,12703.852077,2,100,4,4,0.85,4,4,0,2,0,2,39,1,3,6,NA +64463,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,52209.836905,57180.809983,1,98,13,13,NA,2,2,0,0,2,2,80,1,2,2,NA +64464,7,2,1,0,7,5,6,1,NA,7,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7997.590655,8653.844084,3,91,15,15,5,4,4,2,0,0,2,33,2,5,1,5 +64465,7,2,2,32,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,4,6,2,2,2,2,1,2,2,1,2,2,1,38184.257672,37153.966183,2,91,7,7,1.29,6,6,2,2,0,1,33,2,3,6,NA +64466,7,2,2,23,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,2,6,2,1,2,2,1,2,2,1,2,2,1,18723.98095,18882.01405,2,95,1,1,0.03,3,3,1,0,0,1,23,1,3,6,NA +64467,7,2,1,4,NA,4,4,1,4,51,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10510.490567,11159.309176,1,92,77,77,NA,5,5,1,2,0,2,41,1,3,5,NA +64468,7,2,2,12,NA,5,7,2,12,147,NA,NA,2,1,4,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8301.172828,8622.168806,1,94,15,15,4.2,5,5,1,2,0,1,47,1,5,1,5 +64469,7,2,1,47,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,17787.524589,17730.790674,2,100,8,8,4.96,1,1,0,0,0,1,47,1,5,5,NA +64470,7,2,2,20,NA,5,7,2,NA,NA,2,NA,2,2,3,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,55392.206282,55887.450369,3,91,6,6,2.04,2,2,0,0,0,1,24,2,4,5,NA +64471,7,2,2,37,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,61994.231866,64386.409549,2,92,15,15,5,3,3,1,0,0,1,48,1,5,1,5 +64472,7,2,2,50,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,31460.11615,32394.500316,1,97,3,3,0.73,3,3,0,0,0,2,50,1,4,1,3 +64473,7,2,1,79,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,11869.786782,12478.026352,2,101,6,6,2.04,2,2,0,0,2,2,74,1,3,1,3 +64474,7,2,1,40,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,23594.223469,25276.966347,1,97,15,15,5,4,4,0,1,0,1,40,1,4,1,4 +64475,7,2,1,62,NA,2,2,2,NA,NA,2,NA,2,1,8,NA,3,1,NA,2,2,2,2,2,2,1,2,2,1,8197.936864,8932.691175,3,90,8,8,3.21,2,2,0,0,2,2,80,2,3,2,NA +64476,7,2,2,58,NA,1,1,1,NA,NA,2,NA,2,2,77,NA,1,4,NA,2,2,2,2,2,2,NA,NA,NA,NA,26272.35217,26409.360251,2,102,4,4,0.65,5,5,1,0,0,2,58,2,1,4,NA +64477,7,2,1,49,NA,4,4,2,NA,NA,2,NA,2,2,4,NA,4,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,19895.710643,19832.252596,1,90,4,4,0.58,6,6,0,3,0,2,21,2,5,5,NA +64478,7,2,1,10,NA,4,4,2,10,130,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8655.162127,8668.652185,2,95,6,6,1.36,3,3,0,1,1,2,62,1,4,5,NA +64479,7,2,2,17,NA,1,1,1,17,205,2,NA,2,2,5,10,NA,NA,NA,2,2,2,2,2,2,1,2,2,1,20117.170449,20520.192725,1,94,2,2,0.27,5,5,0,4,0,2,47,2,1,4,NA +64480,7,2,1,4,NA,5,6,2,4,51,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10276.262805,11525.953064,1,97,15,15,5,4,4,2,0,0,1,40,2,5,1,5 +64481,7,2,2,19,NA,3,3,2,19,236,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,35205.804094,37301.699975,2,101,2,1,0.32,3,1,0,0,0,2,19,NA,NA,NA,NA +64482,7,2,1,2,NA,5,6,1,2,29,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10498.222836,11004.769407,1,100,15,15,5,4,4,2,0,0,1,39,2,5,1,5 +64483,7,2,2,5,NA,1,1,1,5,61,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16462.187772,17500.018071,3,92,5,5,0.81,5,5,3,0,0,2,23,1,4,5,NA +64484,7,2,2,26,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,5,1,1,1,2,2,1,2,2,1,2,2,1,15265.136017,16765.388266,1,93,15,15,5,2,2,0,0,0,1,29,2,5,1,5 +64485,7,2,1,32,NA,2,2,1,NA,NA,2,NA,2,2,4,NA,1,6,NA,2,2,2,2,2,2,2,2,2,2,37658.482129,37374.26166,1,100,3,3,0.39,5,5,1,2,0,1,32,2,1,6,NA +64486,7,2,1,9,NA,4,4,1,9,110,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11443.206518,11526.18825,1,100,12,12,NA,5,5,0,3,0,1,39,1,5,1,3 +64487,7,2,1,7,NA,3,3,1,7,86,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,18812.486733,19704.440218,1,98,6,6,0.81,6,6,0,4,0,2,34,NA,NA,1,2 +64488,7,2,2,39,NA,4,4,2,NA,NA,2,NA,2,2,5,NA,3,4,2,1,2,2,1,2,2,NA,NA,NA,NA,35601.750356,47964.629837,1,93,4,4,1.09,2,2,1,0,0,2,39,2,3,4,NA +64489,7,2,2,65,NA,5,6,2,NA,NA,2,NA,2,2,7,NA,4,1,NA,1,2,1,1,2,1,1,2,1,3,9991.888445,10532.363744,3,90,9,9,2.93,3,3,0,0,2,1,71,2,5,1,4 +64490,7,2,1,8,NA,1,1,1,8,104,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17882.621856,18280.794545,3,92,12,12,NA,6,6,1,3,0,2,33,1,5,1,4 +64491,7,2,1,29,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,87028.709207,89819.695129,1,98,8,8,2.46,3,3,1,0,0,1,29,1,4,6,NA +64492,7,2,1,0,5,3,3,2,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,20854.290322,20493.76497,2,94,14,14,4.05,3,3,1,0,0,2,37,1,5,1,5 +64493,7,2,1,17,NA,4,4,2,17,213,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13416.172328,13513.882801,1,96,15,15,4.9,4,4,0,1,0,1,47,1,3,1,5 +64494,7,2,2,39,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,28546.083602,28843.236835,2,95,9,9,4.1,2,2,0,0,0,2,19,1,4,NA,NA +64495,7,2,2,55,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,160743.928829,166234.629208,1,95,10,10,4.76,2,2,0,0,0,1,53,1,2,1,3 +64496,7,1,1,30,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,25120.174741,0,2,102,14,14,4.86,3,3,1,0,0,1,30,1,5,1,5 +64497,7,2,1,60,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,5,NA,1,2,2,1,2,2,1,2,2,1,25495.045769,28642.112646,1,94,5,5,1.39,2,2,0,0,2,1,60,1,1,5,NA +64498,7,2,2,47,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,15747.833197,16088.766331,3,91,15,15,5,3,3,0,1,0,1,47,2,5,1,5 +64499,7,2,1,63,NA,1,1,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,10004.038848,10164.290775,2,102,9,9,3.24,3,3,0,0,1,1,63,1,4,1,4 +64500,7,2,2,29,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,6,2,1,2,2,1,2,2,1,2,2,1,105593.259211,109935.078529,2,92,15,9,5,2,1,0,0,0,2,29,1,5,6,NA +64501,7,2,1,66,NA,2,2,1,NA,NA,2,NA,2,1,9,NA,4,1,NA,2,2,2,2,2,2,2,2,1,2,9068.437099,9213.701881,2,93,15,15,4.84,6,6,1,1,2,1,66,2,4,1,3 +64502,7,2,1,14,NA,4,4,2,14,177,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10366.393886,10567.129261,1,90,9,9,1.65,7,7,0,4,0,1,36,1,4,1,4 +64503,7,2,2,70,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,12863.404053,13555.744544,2,90,9,9,3.02,3,3,0,0,2,2,70,1,4,1,2 +64504,7,2,2,57,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,1,16165.962054,15723.538094,2,99,12,4,1.34,6,1,0,0,0,2,57,1,5,2,NA +64505,7,2,1,18,NA,4,4,1,18,218,2,NA,1,1,NA,12,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13731.625553,14361.066702,1,100,1,1,0.04,4,4,1,1,0,2,51,1,3,3,NA +64506,7,2,1,9,NA,3,3,2,9,119,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,21087.869274,22686.932895,1,101,4,4,1.16,2,2,0,1,0,2,51,1,4,3,NA +64507,7,2,1,70,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,46023.826844,47769.922841,1,91,9,9,3.24,3,3,0,0,1,1,70,1,1,2,NA +64508,7,2,1,14,NA,4,4,2,14,171,NA,NA,2,2,2,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9987.254512,10059.992052,1,96,10,10,1.8,7,7,1,1,0,1,57,2,1,1,3 +64509,7,2,2,24,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,36283.627734,36608.028102,1,102,5,4,1.74,5,1,1,1,0,2,24,1,4,5,NA +64510,7,2,2,10,NA,1,1,1,10,123,NA,NA,1,1,NA,2,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,13028.403003,13395.598637,2,96,6,6,1.11,5,5,0,3,0,2,32,2,3,1,2 +64511,7,2,2,64,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,118611.064701,118209.809508,1,91,9,9,4.15,2,2,0,0,2,2,64,1,4,1,5 +64512,7,2,1,7,NA,4,4,2,7,85,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7886.48532,7943.675078,1,99,14,14,3.8,4,4,1,1,0,1,48,2,5,1,5 +64513,7,1,2,80,NA,2,2,NA,NA,NA,2,NA,2,1,9,NA,1,2,NA,2,2,2,2,2,2,NA,NA,NA,NA,17318.187297,0,2,90,77,77,NA,1,1,0,0,1,2,80,2,1,2,NA +64514,7,2,2,31,NA,2,2,2,NA,NA,2,NA,2,2,6,NA,2,6,2,2,2,2,2,2,2,1,2,2,1,29176.121289,29479.238307,2,90,4,4,0.81,3,3,0,0,0,1,39,2,3,5,NA +64515,7,2,2,41,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,5,3,2,1,2,2,1,2,2,NA,NA,NA,NA,36924.381422,38397.364281,2,102,7,7,2.16,3,3,0,2,0,2,41,1,5,3,NA +64516,7,2,2,2,NA,3,3,2,2,26,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,37236.564417,41097.653079,2,95,7,7,2.91,2,2,1,0,0,1,32,1,5,2,NA +64517,7,2,2,4,NA,3,3,2,4,58,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,51483.624552,52160.136719,1,91,8,8,3.57,2,2,1,0,0,2,33,1,5,3,NA +64518,7,2,1,14,NA,1,1,1,14,178,NA,NA,1,1,NA,8,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,24805.109913,25184.264697,1,94,5,5,0.57,7,7,2,1,0,1,58,2,1,1,1 +64519,7,1,2,1,18,3,3,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,37915.354974,0,2,94,12,12,NA,5,5,1,0,2,2,39,1,5,3,NA +64520,7,2,2,64,NA,2,2,2,NA,NA,2,NA,2,1,NA,NA,3,1,NA,1,1,2,1,2,2,1,2,2,NA,12026.225854,13435.778737,1,90,14,14,5,2,2,0,0,2,1,65,2,2,1,3 +64521,7,2,1,15,NA,4,4,2,15,182,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11351.725436,11256.943498,2,95,5,5,1.18,3,3,0,1,0,2,55,1,4,5,NA +64522,7,2,1,13,NA,5,7,1,13,163,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,5535.564809,5914.423708,2,92,15,15,4.59,4,4,0,2,0,2,45,2,5,1,5 +64523,7,2,2,8,NA,4,4,2,8,105,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10888.493631,11627.08662,1,101,1,1,0.21,3,3,0,2,0,2,32,1,4,5,NA +64524,7,2,1,28,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,25372.225163,26225.545107,2,93,6,2,0.72,4,1,0,0,1,1,69,NA,NA,1,NA +64525,7,2,2,21,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,45673.879644,47551.913663,1,94,5,5,1.47,2,2,0,0,0,1,24,1,4,1,4 +64526,7,2,2,49,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,139800.409559,143196.722449,1,100,8,8,1.95,4,4,0,2,1,2,49,1,5,6,NA +64527,7,1,2,42,NA,2,2,NA,NA,NA,2,NA,1,1,NA,NA,5,1,3,1,2,2,NA,NA,NA,NA,NA,NA,NA,29650.79971,0,2,90,NA,NA,NA,2,2,0,0,0,1,40,NA,NA,1,5 +64528,7,2,2,7,NA,4,4,2,7,89,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8579.490652,8729.153641,2,97,13,13,NA,6,6,2,2,0,2,24,1,2,6,NA +64529,7,2,1,18,NA,3,3,1,18,219,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,112494.70924,119489.826838,1,94,5,5,1.04,4,4,1,1,0,1,18,1,2,NA,NA +64530,7,2,1,53,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,174520.785302,181786.280703,1,95,10,10,4.76,2,2,0,0,0,1,53,1,2,1,3 +64531,7,2,2,2,NA,5,6,2,2,27,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5248.47937,5499.505789,3,91,14,14,2.5,6,6,1,1,1,2,37,2,2,1,5 +64532,7,2,2,43,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,14340.013944,13947.561844,2,99,15,15,4.9,7,7,1,4,0,2,53,1,5,1,5 +64533,7,2,1,13,NA,4,4,2,13,157,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12418.38217,12987.625827,2,99,6,6,1.57,3,3,0,2,0,2,31,1,3,77,NA +64534,7,2,2,28,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,3,1,2,2,1,2,2,1,2,2,1,19658.218913,19871.634013,1,99,2,2,0.31,4,4,1,0,1,2,67,1,3,3,NA +64535,7,2,2,7,NA,4,4,2,7,86,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6491.294105,6989.429429,2,99,6,6,1.11,5,5,1,2,0,2,41,1,2,5,NA +64536,7,2,2,75,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,68852.695662,70965.028494,1,101,15,15,5,3,3,0,0,2,1,75,1,2,1,2 +64537,7,1,1,7,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8749.381325,0,2,100,15,15,5,4,3,0,2,0,1,42,1,3,5,NA +64538,7,2,2,11,NA,1,1,1,11,137,NA,NA,1,1,NA,5,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,16986.005478,17733.622754,2,102,6,6,1,6,6,1,3,0,1,35,2,3,1,3 +64539,7,2,2,7,NA,3,3,2,7,90,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,80369.555824,80552.420473,1,97,15,15,4.07,5,5,0,3,0,1,36,1,5,1,5 +64540,7,2,1,69,NA,2,2,1,NA,NA,2,NA,2,1,8,NA,5,1,NA,1,1,2,1,2,2,1,2,2,NA,11992.012141,12184.108862,2,102,99,99,NA,2,2,0,0,2,2,67,2,5,1,5 +64541,7,2,2,0,10,3,3,2,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,27492.029044,26745.284482,1,97,10,10,2.95,4,4,2,0,0,1,28,1,5,1,4 +64542,7,2,2,5,NA,1,1,2,5,67,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,13366.393396,13791.68675,2,94,77,77,NA,4,4,2,0,0,1,26,2,2,1,4 +64543,7,2,2,0,7,3,3,2,NA,8,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12997.670925,13008.434462,1,99,10,10,2.48,5,5,2,1,0,1,33,1,5,1,5 +64544,7,2,1,69,NA,5,6,2,NA,NA,2,NA,2,1,8,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,7688.593855,7926.541218,2,100,14,14,4.59,3,3,0,0,2,1,69,2,5,1,5 +64545,7,2,1,15,NA,2,2,1,15,184,NA,NA,2,2,4,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17555.907575,18699.509115,2,93,8,8,2,4,4,1,1,0,1,50,2,4,1,4 +64546,7,1,2,6,NA,1,1,NA,NA,NA,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,14300.71869,0,2,94,4,4,0.72,4,4,1,1,0,1,30,2,1,1,3 +64547,7,2,1,2,NA,1,1,2,2,27,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,10803.555682,10931.27688,2,94,9,9,2.1,5,5,1,2,0,1,31,2,4,1,4 +64548,7,2,2,59,NA,5,6,1,NA,NA,2,NA,2,1,3,NA,5,2,NA,1,2,2,1,2,2,1,2,2,1,17950.494975,18045.41616,1,92,2,2,0.24,5,5,0,2,0,1,35,2,4,1,3 +64549,7,2,1,44,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,4,4,NA,1,2,2,1,2,2,1,2,2,1,42123.732489,42281.342391,1,102,7,7,1.7,4,4,0,0,2,1,44,1,4,4,NA +64550,7,2,2,62,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,1,2,2,3,12449.239856,12885.71781,1,96,7,7,2.64,2,2,0,0,2,1,64,2,5,1,5 +64551,7,2,2,10,NA,2,2,1,10,131,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14414.529053,14504.545241,2,96,14,14,3.36,4,4,1,1,0,2,28,1,2,6,NA +64552,7,2,1,76,NA,2,2,2,NA,NA,1,2,2,1,9,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,13725.398968,14221.420409,2,90,7,7,2.52,2,2,0,0,2,2,71,1,4,1,4 +64553,7,2,2,65,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,13422.679076,14021.98734,2,92,6,6,2.31,2,2,0,0,2,2,65,1,4,5,NA +64554,7,2,2,1,17,3,3,2,NA,18,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,43715.161102,44289.593043,1,98,15,15,5,3,3,1,0,0,1,33,1,5,1,5 +64555,7,2,2,1,20,3,3,2,NA,20,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,20272.436775,20538.823422,2,94,77,77,NA,2,2,1,0,0,1,24,1,4,77,NA +64556,7,2,2,0,4,1,1,1,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9767.083234,10416.172562,3,92,2,2,0.4,3,3,1,0,0,1,21,1,2,6,NA +64557,7,2,1,3,NA,4,4,1,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11324.865632,11670.771889,2,96,5,5,1.13,3,3,1,1,0,2,31,1,3,5,NA +64558,7,2,1,62,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,11764.405491,12074.424659,1,97,14,14,3.93,3,3,0,1,2,2,63,1,4,1,4 +64559,7,2,2,70,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,72551.269339,74475.92188,1,95,7,7,2.45,2,2,0,0,2,2,70,1,3,1,3 +64560,7,1,2,13,NA,2,2,NA,NA,NA,NA,NA,1,1,NA,6,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,21282.11341,0,1,90,6,6,1.44,3,3,0,1,0,1,44,2,1,1,3 +64561,7,2,1,6,NA,2,2,2,6,83,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8927.426533,9245.241527,2,99,13,13,NA,6,6,2,1,0,2,31,1,4,6,NA +64562,7,2,1,20,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,23235.97926,24326.785264,2,95,6,6,1.19,4,4,0,1,0,1,44,1,3,1,2 +64563,7,2,2,0,7,2,2,1,NA,8,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7849.042868,8059.930457,2,98,6,6,1.07,5,5,3,0,0,2,24,1,3,1,3 +64564,7,2,2,54,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,19302.748944,20091.820859,3,92,15,15,5,3,3,0,1,0,1,55,2,5,1,4 +64565,7,1,1,54,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,20286.317046,0,2,99,99,99,NA,1,1,0,0,0,1,54,1,3,5,NA +64566,7,2,1,7,NA,4,4,1,7,93,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8294.996898,8761.908989,1,96,5,5,0.53,7,7,2,2,0,2,38,1,9,6,NA +64567,7,2,1,37,NA,2,2,1,NA,NA,2,NA,2,1,4,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,38835.309696,39871.800261,1,100,15,15,4.34,4,4,2,0,0,2,35,1,5,1,5 +64568,7,2,2,5,NA,1,1,1,6,72,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10493.785765,10940.90082,1,103,5,5,0.71,6,6,2,2,0,2,31,2,2,1,2 +64569,7,2,1,14,NA,4,4,1,14,177,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9188.45337,9407.445906,2,95,15,15,3.85,7,7,0,3,1,2,62,1,4,2,NA +64570,7,2,2,65,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,49428.481088,50236.061312,1,101,2,2,0.72,1,1,0,0,1,2,65,1,4,2,NA +64571,7,2,1,26,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,124091.929364,132249.317489,1,95,15,15,5,3,3,1,0,0,1,26,1,3,1,4 +64572,7,2,1,50,NA,5,6,2,NA,NA,2,NA,2,1,5,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,15693.68983,16353.841376,1,91,77,77,NA,4,4,0,2,0,1,50,2,5,1,5 +64573,7,2,1,7,NA,4,4,1,7,86,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9022.8939,9451.941588,2,100,5,5,0.88,5,5,2,1,0,2,30,1,4,6,NA +64574,7,2,1,17,NA,4,4,2,17,207,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11834.781205,12063.950506,2,90,6,6,1.12,4,4,0,1,1,1,63,2,1,1,1 +64575,7,2,2,6,NA,2,2,2,6,72,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,13895.77426,15584.232002,2,91,99,99,NA,6,6,1,3,0,2,20,2,2,5,NA +64576,7,2,1,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,38666.703155,42427.769217,2,94,15,15,5,1,1,0,0,1,1,80,1,5,2,NA +64577,7,2,1,0,4,3,3,1,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12008.205501,11800.609728,1,92,4,4,1.22,2,2,1,0,0,2,30,1,4,5,NA +64578,7,2,1,1,12,1,1,2,NA,12,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12567.081957,12360.030976,1,97,7,7,2.31,2,2,1,0,0,1,22,1,4,5,NA +64579,7,2,2,3,NA,4,4,2,3,45,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10683.855206,11939.151167,1,96,3,3,0.43,4,4,1,1,0,2,39,2,4,1,3 +64580,7,2,1,7,NA,1,1,1,7,88,NA,NA,2,7,77,0,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,11367.678664,11216.859778,2,96,77,77,NA,7,7,3,2,0,2,33,2,2,6,NA +64581,7,2,2,31,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,14179.938483,16215.179647,3,90,10,10,4.63,2,2,0,0,0,2,31,1,5,1,4 +64582,7,2,1,59,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,4,1,NA,1,2,1,1,2,2,1,2,2,1,16628.326744,17078.450103,2,102,8,8,2.01,4,4,0,0,0,1,59,2,4,1,4 +64583,7,2,1,16,NA,5,6,2,16,199,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,8305.829479,8595.334823,1,93,15,15,5,3,3,0,2,0,2,48,2,5,3,NA +64584,7,2,1,41,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,12471.410981,12474.00514,2,103,77,77,NA,5,5,0,2,0,2,39,2,5,1,5 +64585,7,2,2,42,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,3,1,2,2,1,2,2,NA,NA,NA,NA,25189.042335,25118.259708,1,100,8,8,1.95,4,4,0,2,0,2,42,1,4,1,4 +64586,7,2,2,25,NA,1,1,1,NA,NA,2,NA,2,2,77,NA,1,1,2,2,2,2,2,2,2,NA,NA,NA,NA,50177.882654,49959.335916,1,100,4,4,0.78,4,4,0,0,1,1,33,2,1,1,1 +64587,7,2,1,19,NA,4,4,1,19,239,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,17606.165994,17558.40257,2,101,2,1,0.18,2,1,0,0,0,1,19,NA,NA,NA,NA +64588,7,2,2,3,NA,5,6,1,3,40,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8171.700571,8311.029296,1,92,7,7,1.65,4,4,2,0,0,1,24,1,4,1,3 +64589,7,2,1,13,NA,2,2,2,13,158,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14081.782012,14782.02856,2,90,7,7,0.89,7,7,1,3,3,1,60,2,3,1,3 +64590,7,2,1,6,NA,4,4,1,6,77,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13423.881856,14062.200951,2,97,7,7,1.38,5,5,0,1,1,2,79,1,5,5,NA +64591,7,2,1,51,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,20075.522681,20011.491118,3,92,4,4,1.22,2,2,0,0,0,1,51,1,2,1,3 +64592,7,2,2,29,NA,1,1,1,NA,NA,2,NA,2,2,3,NA,3,6,2,2,2,1,1,2,1,1,2,2,NA,45207.136555,47234.971464,1,91,7,7,2.1,3,3,0,1,0,2,29,2,3,6,NA +64593,7,2,1,47,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,19686.178677,19752.591494,2,94,15,15,5,5,5,0,2,1,1,47,2,5,1,5 +64594,7,2,1,24,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,21399.459455,20960.973241,1,90,15,15,4.34,4,4,0,0,1,1,62,2,5,1,3 +64595,7,2,1,4,NA,3,3,2,4,57,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,27813.351627,32589.867729,2,97,1,1,0.21,4,4,2,0,0,2,34,2,1,1,2 +64596,7,2,2,12,NA,1,1,1,12,150,NA,NA,2,2,4,6,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,20419.465237,21192.774678,2,102,6,3,0.54,6,4,0,4,0,2,43,2,1,5,NA +64597,7,2,2,16,NA,3,3,2,16,203,NA,NA,1,1,NA,11,NA,NA,NA,1,2,1,1,2,1,1,2,2,1,23708.623398,23934.71279,2,97,2,2,0.38,4,4,0,2,2,2,64,2,1,1,NA +64598,7,2,2,60,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,98514.948291,98181.677236,1,99,15,15,5,2,2,0,0,2,1,62,1,5,1,4 +64599,7,2,1,35,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,29756.291619,30015.261296,2,101,8,8,2.43,3,3,0,1,0,1,35,1,4,6,NA +64600,7,2,2,14,NA,4,4,2,14,169,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11478.437608,11446.094627,1,96,10,10,3.04,4,4,0,1,0,2,43,1,5,1,4 +64601,7,2,1,6,NA,5,6,1,6,75,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8556.838894,9269.764719,2,95,15,15,5,3,3,0,1,0,2,34,2,5,1,NA +64602,7,2,2,59,NA,1,1,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,22224.73066,22340.630739,2,94,14,14,5,1,1,0,0,0,2,59,1,4,2,NA +64603,7,2,2,40,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,20303.639991,21936.687597,1,97,15,15,4.77,4,4,1,1,0,2,40,1,5,1,5 +64604,7,2,2,50,NA,2,2,1,NA,NA,2,NA,2,2,4,NA,2,3,NA,2,2,2,1,2,2,2,2,2,2,23200.373382,24548.135184,2,93,5,5,0.89,4,4,0,2,0,1,42,NA,NA,6,NA +64605,7,2,2,0,6,3,3,1,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,21671.775435,21083.121886,1,98,6,6,1.34,4,4,2,0,0,2,25,1,3,1,4 +64606,7,2,2,59,NA,2,2,1,NA,NA,2,NA,2,1,8,NA,4,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,23644.678283,24188.238174,2,93,5,5,1.32,2,2,0,0,0,2,59,2,4,2,NA +64607,7,2,2,42,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,14447.262849,14051.875602,3,90,15,15,5,5,5,1,0,1,1,38,2,3,1,4 +64608,7,2,1,22,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,104371.641146,109271.336207,1,90,15,15,5,3,3,0,0,0,1,59,1,5,1,5 +64609,7,2,1,64,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,8385.499814,8451.09383,2,92,12,12,NA,2,1,0,0,1,2,58,1,3,5,NA +64610,7,2,1,54,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,141773.363283,145979.183499,1,97,15,15,5,4,4,0,0,1,1,67,NA,NA,2,NA +64611,7,2,1,50,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,17206.320427,17271.69718,2,100,14,14,3.06,5,5,1,0,0,1,50,1,5,1,5 +64612,7,2,2,11,NA,4,4,2,11,139,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9013.911777,9371.113947,1,97,4,4,0.46,7,7,3,3,0,2,31,1,3,1,NA +64613,7,2,1,25,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,49741.714519,50662.492276,2,91,7,7,3.76,1,1,0,0,0,1,25,1,5,5,NA +64614,7,2,1,7,NA,3,3,1,8,96,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,71470.369236,87471.572436,2,101,8,8,2.81,3,3,0,2,0,1,48,1,3,3,NA +64615,7,2,2,14,NA,3,3,2,14,179,NA,NA,1,1,NA,9,NA,NA,NA,1,1,1,NA,NA,NA,1,2,2,1,23708.623398,23934.71279,2,97,2,2,0.38,4,4,0,2,2,2,64,2,1,1,NA +64616,7,2,1,21,NA,2,2,1,NA,NA,2,NA,2,1,5,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,32384.468407,33958.290597,2,100,14,14,3.58,4,4,0,1,0,1,46,2,5,1,5 +64617,7,2,1,60,NA,2,2,2,NA,NA,2,NA,2,1,7,NA,4,1,NA,2,2,2,2,2,2,2,2,2,2,9053.837749,9198.868668,2,99,77,77,NA,4,4,1,1,1,2,38,2,4,1,4 +64618,7,2,1,1,21,1,1,1,NA,23,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,8481.734412,8750.218705,1,103,5,5,0.74,5,5,1,1,0,2,40,99,3,1,1 +64619,7,2,1,16,NA,4,4,2,16,198,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13969.457688,14694.403205,1,90,14,14,3.25,4,4,0,2,0,2,33,2,3,1,3 +64620,7,2,1,36,NA,5,6,2,NA,NA,2,NA,2,1,4,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,14221.330587,14963.406508,3,90,12,12,NA,4,4,0,0,1,1,62,2,4,3,NA +64621,7,2,1,38,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,39053.240727,39737.089727,1,100,14,14,4.71,3,3,0,1,0,1,38,1,5,1,5 +64622,7,2,1,13,NA,1,1,2,13,165,NA,NA,1,1,NA,7,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,20398.562455,20710.36162,2,94,13,13,NA,5,5,0,3,0,1,32,2,2,1,1 +64623,7,2,1,2,NA,2,2,2,3,36,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,8488.185756,9094.478438,2,99,77,77,NA,4,4,1,1,1,2,38,2,4,1,4 +64624,7,2,1,1,15,1,1,2,NA,15,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10078.126531,10467.748183,2,97,NA,2,0.36,6,4,3,1,0,2,25,1,4,6,NA +64625,7,2,1,69,NA,4,4,2,NA,NA,2,NA,2,1,7,NA,2,1,NA,1,2,2,1,2,2,2,2,2,1,8491.292032,8823.40317,1,96,7,7,1.39,5,5,0,2,2,1,69,2,2,1,2 +64626,7,2,1,0,4,3,3,2,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9081.731172,9425.042696,1,101,5,5,0.74,6,6,1,3,0,1,38,1,4,1,4 +64627,7,2,2,17,NA,5,6,1,18,216,2,NA,2,2,5,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,9269.277563,9333.801929,2,102,5,5,1.08,3,3,0,1,0,2,46,2,1,5,NA +64628,7,2,2,45,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,27524.153939,27114.967247,3,92,12,12,NA,3,2,0,0,0,1,45,1,3,1,3 +64629,7,2,1,14,NA,3,3,2,14,175,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,119111.433099,126517.990149,2,94,7,7,2.38,2,2,0,1,0,1,39,1,4,3,NA +64630,7,2,1,0,3,3,3,2,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,20370.716701,21140.779334,1,91,15,15,5,5,5,3,0,0,1,45,1,5,1,5 +64631,7,2,2,1,17,5,6,1,NA,17,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7029.864692,7462.832472,3,92,8,8,0.91,7,7,3,3,1,1,61,NA,NA,1,4 +64632,7,2,1,21,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,51858.383222,54820.448996,2,91,10,10,4.63,2,2,0,0,0,1,55,2,3,3,NA +64633,7,2,1,27,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,108410.783716,110095.623149,1,94,10,10,4.3,2,2,0,0,0,1,27,1,5,1,5 +64634,7,2,2,74,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,16361.152596,17584.911061,1,100,1,1,0.36,1,1,0,0,1,2,74,1,2,2,NA +64635,7,2,1,29,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,19510.698389,19365.075974,1,102,7,7,1.9,4,4,1,1,0,1,29,1,4,1,3 +64636,7,2,1,20,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,25815.880139,26556.735732,2,101,2,1,0.02,2,1,0,0,0,1,20,1,4,5,NA +64637,7,2,1,77,NA,2,2,2,NA,NA,2,NA,2,2,6,NA,2,1,NA,2,2,2,1,2,2,2,2,2,NA,16591.871479,16938.772121,3,91,77,77,NA,4,4,0,0,2,1,54,1,4,1,2 +64638,7,2,1,8,NA,4,4,1,8,99,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10410.106675,10617.081899,2,96,5,5,1.08,3,3,0,1,0,2,41,1,3,1,NA +64639,7,2,1,58,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,25963.141347,26172.595903,1,92,9,9,3.7,2,2,0,0,0,1,58,1,2,1,4 +64640,7,2,1,80,NA,1,1,1,NA,NA,1,2,1,1,NA,NA,1,1,NA,2,2,2,2,2,2,1,2,2,NA,18949.267372,20024.848444,2,98,4,4,1.15,2,2,0,0,2,1,80,1,1,1,1 +64641,7,2,1,4,NA,2,2,1,4,57,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16775.083123,17533.373205,2,98,8,8,1.48,7,7,3,0,0,1,26,1,3,1,3 +64642,7,2,1,15,NA,2,2,1,15,183,NA,NA,2,2,4,8,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,24585.624844,25010.051033,3,91,5,5,0.89,4,4,0,2,2,1,61,2,3,1,4 +64643,7,2,2,52,NA,5,6,2,NA,NA,2,NA,2,2,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,22560.963402,22680.264479,1,98,6,6,1.65,2,2,0,1,0,2,52,2,5,1,NA +64644,7,2,2,35,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,4,2,1,2,2,1,2,2,1,2,2,1,93796.829073,95761.252302,1,100,6,6,1.78,3,3,1,1,0,2,35,1,5,4,NA +64645,7,2,1,2,NA,4,4,2,2,25,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5942.817425,6352.518414,2,97,5,5,0.84,5,5,2,1,0,2,27,1,3,1,3 +64646,7,2,1,80,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,32860.812334,35527.111698,1,91,7,7,2.68,2,2,0,0,2,1,80,1,4,1,4 +64647,7,2,1,4,NA,2,2,1,4,57,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13504.027725,14468.59111,2,93,8,8,2,4,4,1,1,0,1,50,2,4,1,4 +64648,7,2,1,36,NA,1,1,1,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,37080.526463,37974.333878,1,103,15,15,5,2,2,0,0,0,1,36,2,5,1,5 +64649,7,2,2,4,NA,1,1,1,4,52,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,1,1,2,2,NA,NA,NA,NA,15326.318384,16292.539752,3,91,7,7,1.42,6,6,1,3,0,1,37,2,1,1,1 +64650,7,2,2,10,NA,3,3,2,10,127,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,22371.648216,23759.450609,1,95,5,5,1.08,3,3,0,1,0,1,53,1,4,1,4 +64651,7,2,1,58,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,28454.541725,29098.608791,3,91,3,3,1.24,1,1,0,0,0,1,58,1,4,5,NA +64652,7,2,2,10,NA,5,6,1,10,125,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7905.246022,8589.222558,1,100,3,3,0.73,2,2,0,1,0,2,38,2,5,3,NA +64653,7,2,2,1,18,4,4,1,NA,19,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9287.278834,9993.215624,2,102,5,3,0.63,5,4,2,1,0,1,24,1,4,6,NA +64654,7,2,1,44,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,151649.038926,165350.159672,1,101,7,7,2.31,2,2,0,0,0,1,44,1,3,1,2 +64655,7,2,2,9,NA,1,1,1,9,118,NA,NA,1,1,NA,3,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,15510.382876,18634.445505,1,100,13,13,NA,4,4,1,1,0,1,28,2,1,1,1 +64656,7,2,2,54,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,14314.968597,14503.241546,1,96,15,15,5,4,3,0,0,1,2,54,2,4,1,5 +64657,7,2,2,4,NA,3,3,1,4,55,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,71121.657525,76575.027332,1,92,9,4,1,7,3,2,1,0,1,45,1,4,2,NA +64658,7,2,2,51,NA,1,1,1,NA,NA,2,NA,2,2,6,NA,1,1,NA,2,2,2,2,2,2,2,2,1,2,25483.560748,27318.705448,1,94,5,5,0.57,7,7,2,1,0,1,58,2,1,1,1 +64659,7,2,2,11,NA,4,4,2,11,142,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7646.649777,8233.445923,2,99,4,4,1,3,3,0,1,0,2,38,1,3,5,NA +64660,7,2,2,4,NA,2,2,2,4,52,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,13366.393396,14209.054666,2,94,7,7,1.34,5,5,2,1,0,1,32,2,1,1,NA +64661,7,2,1,29,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,31312.870743,38059.589922,2,90,8,8,2.24,4,4,1,1,0,2,29,1,4,6,NA +64662,7,2,1,10,NA,3,3,1,10,130,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,66003.625505,68276.88064,1,101,8,8,1.85,5,5,0,3,0,1,41,1,3,1,4 +64663,7,2,2,33,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,NA,NA,NA,NA,21522.871343,21589.047039,3,92,7,7,0.81,7,7,2,4,0,1,40,NA,NA,1,4 +64664,7,2,2,48,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,40760.712736,41570.695949,1,98,4,4,1.26,2,2,0,0,1,2,80,1,4,2,NA +64665,7,2,2,6,NA,3,3,2,6,82,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,24070.467912,23750.822126,1,92,4,4,0.5,6,6,0,3,0,2,41,1,4,1,NA +64666,7,2,2,11,NA,4,4,1,11,139,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10332.067017,10608.478853,1,100,12,12,NA,5,5,0,3,0,1,39,1,5,1,3 +64667,7,2,1,58,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,1,6,NA,1,2,2,1,2,2,1,2,2,1,26135.885159,26052.523863,2,101,3,3,0.68,2,2,0,0,0,1,58,1,1,6,NA +64668,7,1,1,21,NA,1,1,NA,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,52698.05363,0,3,92,2,2,0.4,3,3,1,0,0,1,21,1,2,6,NA +64669,7,2,2,60,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,35475.142583,37174.132552,2,95,6,6,2.95,1,1,0,0,1,2,60,1,3,3,NA +64670,7,2,2,2,NA,3,3,1,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,55441.113009,61189.845638,1,92,6,6,1.62,3,3,1,0,0,2,26,1,5,1,5 +64671,7,2,2,13,NA,3,3,1,13,164,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,117872.104347,120084.841085,2,101,10,10,2.33,6,6,1,3,0,1,39,1,2,1,4 +64672,7,2,1,22,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,16995.648055,16715.026676,2,100,7,7,1.38,5,5,1,0,0,2,45,1,2,3,NA +64673,7,2,1,12,NA,5,6,1,12,148,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,5388.361335,5758.757236,3,91,6,6,1.22,5,5,1,2,0,2,37,1,4,1,2 +64674,7,2,2,39,NA,1,1,1,NA,NA,2,NA,2,2,5,NA,1,1,2,2,2,2,2,2,2,NA,NA,NA,NA,38161.026403,39476.245254,1,100,7,7,1.74,4,4,0,2,0,2,39,2,1,1,3 +64675,7,2,1,46,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,152858.509804,159455.333031,1,95,15,15,5,4,4,0,2,0,2,42,1,5,1,5 +64676,7,2,2,56,NA,2,2,1,NA,NA,2,NA,2,1,6,NA,4,6,NA,2,2,2,2,2,2,1,2,1,2,19969.163208,20990.960204,2,93,10,10,3.67,3,3,0,0,0,2,56,2,4,6,NA +64677,7,2,2,56,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,19210.136544,18684.400763,1,96,12,12,NA,1,1,0,0,0,2,56,1,4,3,NA +64678,7,2,2,0,4,4,4,1,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7333.056164,7413.124496,2,101,5,5,1.08,3,3,1,0,0,1,31,1,4,6,NA +64679,7,2,2,38,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,2,3,2,1,2,2,1,2,2,1,2,2,1,17978.142628,18905.276914,1,91,7,7,1.57,4,4,0,3,0,2,38,2,2,3,NA +64680,7,2,2,35,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,21116.677917,21908.928919,1,92,14,14,3.47,4,4,0,2,0,1,37,1,5,1,5 +64681,7,2,1,15,NA,3,3,2,15,185,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,68148.957861,67253.324127,1,93,7,7,2.16,3,3,0,1,0,2,50,1,5,3,NA +64682,7,2,1,42,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,133542.212862,160359.69013,1,94,14,14,2.96,5,5,0,3,0,2,39,1,4,1,3 +64683,7,1,2,26,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,5,6,3,1,2,2,1,2,2,NA,NA,NA,NA,109522.19868,0,1,90,9,1,0,2,1,0,0,0,2,26,1,5,6,NA +64684,7,2,1,25,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,1,2,1,2,2,1,2,2,1,16995.648055,19983.260181,1,96,12,12,NA,7,7,1,0,1,2,59,1,3,1,1 +64685,7,2,1,12,NA,2,2,2,12,146,NA,NA,1,1,NA,6,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,13752.835112,15116.811136,3,90,7,7,1.48,5,5,0,1,0,1,43,2,1,6,NA +64686,7,2,2,2,NA,4,4,2,2,29,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6226.488588,6570.976462,2,99,6,6,1.03,6,6,3,0,0,1,33,1,3,6,NA +64687,7,2,2,24,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,20247.768461,19251.812222,2,93,4,4,0.56,5,5,2,1,0,1,27,1,2,6,NA +64688,7,2,1,1,18,1,1,1,NA,19,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,11853.772636,11869.789876,2,96,4,4,0.81,4,4,1,1,0,1,36,2,1,6,NA +64689,7,2,2,42,NA,1,1,1,NA,NA,2,NA,2,2,6,NA,2,5,2,2,2,2,1,2,2,2,2,2,2,27654.660303,28156.17371,2,103,4,4,0.79,3,3,0,0,0,2,42,2,2,5,NA +64690,7,2,2,11,NA,4,4,2,11,140,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8147.287486,8590.325322,2,90,2,2,0.38,4,4,1,2,0,2,32,1,4,5,NA +64691,7,2,1,0,10,2,2,1,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,1,2,2,1,NA,NA,NA,NA,5357.080288,5657.49929,1,103,12,12,NA,6,6,2,1,0,2,27,2,2,1,3 +64692,7,1,2,59,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,13728.308948,0,2,90,10,10,3.51,3,3,0,0,1,2,59,1,4,1,NA +64693,7,1,2,46,NA,2,2,NA,NA,NA,2,NA,2,2,4,NA,2,4,NA,2,2,2,2,2,2,NA,NA,NA,NA,23968.560941,0,2,90,6,6,0.66,7,7,2,2,0,2,24,2,4,6,NA +64694,7,2,1,23,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,44887.234615,46900.157613,2,93,9,9,2.6,4,4,0,0,0,2,58,2,4,4,NA +64695,7,2,2,38,NA,5,6,2,NA,NA,2,NA,2,2,4,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,11608.998717,12267.891619,3,90,14,14,3.47,4,4,1,1,0,2,38,2,5,1,5 +64696,7,2,1,11,NA,4,4,2,11,143,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8579.422451,8641.637123,1,99,14,14,4.86,3,3,0,1,0,1,42,1,5,1,5 +64697,7,2,1,8,NA,4,4,1,8,98,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11443.206518,11987.342507,1,100,6,6,1.65,2,2,0,1,0,2,42,1,4,5,NA +64698,7,2,1,13,NA,3,3,1,13,166,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,23685.067681,25157.846578,1,94,7,7,1.21,6,6,2,2,0,1,31,1,2,6,NA +64699,7,2,1,16,NA,4,4,1,16,197,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,18123.994406,21384.995218,2,101,8,8,2.81,3,3,0,1,0,1,35,1,1,1,2 +64700,7,1,1,24,NA,3,3,NA,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,108410.783716,0,1,91,8,8,2.51,3,3,1,0,0,2,24,1,4,1,3 +64701,7,2,1,57,NA,2,2,1,NA,NA,2,NA,2,2,2,NA,3,3,NA,2,2,2,1,2,2,2,2,1,2,27131.416371,32184.468102,2,93,6,6,0.64,7,7,2,1,3,2,60,2,3,2,NA +64702,7,2,2,4,NA,3,3,2,4,49,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,31376.988784,34630.493438,1,101,7,7,1.82,4,4,2,0,0,2,27,1,2,1,3 +64703,7,2,2,22,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,32537.532358,33640.063825,2,90,5,5,1.19,3,3,0,0,0,2,50,2,4,4,NA +64704,7,2,1,62,NA,1,1,1,NA,NA,2,NA,2,1,6,NA,1,1,NA,2,2,2,2,2,2,2,2,2,2,11937.570805,12597.633777,2,96,8,8,1.33,7,7,2,1,1,1,62,2,1,1,1 +64705,7,2,2,72,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,13242.661868,13437.555164,1,99,5,5,1.69,2,2,0,0,2,1,79,1,1,1,4 +64706,7,2,2,20,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,20332.409486,19927.598485,2,93,6,6,1.47,3,3,0,0,0,2,47,1,4,5,NA +64707,7,2,1,10,NA,1,1,1,10,128,NA,NA,1,1,NA,4,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,17882.621856,17720.218058,3,92,4,4,0.67,4,4,0,3,0,2,36,2,1,5,NA +64708,7,2,2,11,NA,1,1,2,11,136,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15002.25457,15643.939501,1,91,6,6,1.35,3,3,0,2,0,2,38,1,4,3,NA +64709,7,2,1,60,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,9221.19173,9652.555988,2,95,3,3,0.75,2,2,0,0,2,1,60,1,2,1,2 +64710,7,2,1,3,NA,5,7,2,3,42,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8981.553859,10073.795326,3,91,15,15,4.47,4,4,2,0,0,1,33,1,5,1,5 +64711,7,2,2,35,NA,5,7,1,NA,NA,2,NA,2,1,6,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,18346.384255,19018.034723,2,96,15,15,5,4,4,1,1,0,2,35,2,5,1,5 +64712,7,2,1,6,NA,1,1,1,6,76,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14820.807433,14827.373008,2,102,5,5,0.89,4,4,1,2,0,2,36,2,5,3,NA +64713,7,2,2,50,NA,2,2,2,NA,NA,2,NA,2,2,4,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,22224.73066,22340.630739,2,94,15,15,5,2,2,0,0,1,1,77,1,5,1,4 +64714,7,2,2,17,NA,4,4,2,17,204,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13661.047334,13622.554377,2,97,5,5,0.76,5,5,1,1,0,2,47,1,4,5,NA +64715,7,2,1,24,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,25815.880139,26556.735732,2,101,4,2,0.83,2,1,0,0,0,1,24,1,4,5,NA +64716,7,2,1,1,19,3,3,2,NA,19,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,46257.816906,54201.886729,2,94,14,14,3.36,4,4,2,0,0,1,31,1,3,1,5 +64717,7,2,1,1,13,4,4,1,NA,13,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10232.679671,11283.202594,2,101,5,5,0.89,4,4,1,1,1,2,38,1,4,77,NA +64718,7,2,1,18,NA,4,4,1,19,228,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,14848.504688,14956.646891,1,98,2,2,0.45,2,1,0,0,0,1,19,1,4,NA,NA +64719,7,2,2,39,NA,5,6,2,NA,NA,1,2,2,1,7,NA,5,3,2,1,2,2,1,2,2,1,2,2,1,18480.909695,18518.646173,1,93,9,9,5,1,1,0,0,0,2,39,2,5,3,NA +64720,7,2,1,29,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,21548.249649,21044.90278,1,100,8,8,1.61,6,6,1,3,0,1,29,1,5,6,NA +64721,7,2,1,56,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,17206.320427,17151.440282,2,100,5,5,1.08,3,3,0,0,0,1,38,1,2,5,NA +64722,7,2,2,33,NA,1,1,1,NA,NA,2,NA,2,2,2,NA,1,1,2,2,2,2,2,2,2,1,2,2,NA,38218.668882,37187.448906,2,102,7,7,1.33,6,6,1,3,0,1,34,2,2,1,1 +64723,7,2,2,6,NA,4,4,1,6,75,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8292.876947,8466.609309,1,102,1,1,0,5,5,0,3,0,2,41,1,4,1,4 +64724,7,2,2,3,NA,3,3,2,3,47,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,50908.326714,52512.144621,1,99,15,15,5,4,4,1,1,0,2,42,1,5,1,5 +64725,7,2,2,39,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,6,2,1,2,2,1,2,2,1,2,2,1,101005.054511,105662.333954,2,91,15,8,4.48,2,1,0,0,0,2,55,1,5,6,NA +64726,7,2,1,55,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,18486.334367,18427.371573,2,95,8,8,1.85,5,5,1,2,0,1,55,1,2,1,3 +64727,7,2,1,50,NA,1,1,2,NA,NA,2,NA,2,2,6,NA,1,1,NA,2,2,2,2,2,2,2,2,1,2,22446.308035,22401.210337,2,94,77,77,NA,4,4,0,0,0,1,28,2,1,3,NA +64728,7,2,1,23,NA,2,2,1,NA,NA,2,NA,2,2,4,NA,3,5,NA,2,2,2,1,2,2,2,2,2,2,38474.772527,42632.210531,2,93,7,5,1.79,3,1,0,0,0,1,25,2,4,5,NA +64729,7,2,2,80,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,1,2,NA,1,2,1,NA,NA,NA,NA,NA,NA,NA,14314.616082,14811.078253,2,92,NA,NA,NA,2,1,0,0,1,2,58,2,4,5,NA +64730,7,2,1,9,NA,2,2,2,9,111,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9390.522479,10327.334743,2,90,1,1,0.19,4,4,0,1,0,2,44,1,2,5,NA +64731,7,2,2,34,NA,2,2,1,NA,NA,2,NA,2,1,6,NA,5,3,2,1,2,2,1,2,2,1,2,2,1,36904.965687,36815.84758,2,93,9,9,3.14,3,3,0,2,0,2,34,2,5,3,NA +64732,7,2,1,17,NA,4,4,1,17,215,2,NA,2,1,4,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,16261.995423,16380.43213,2,96,6,6,1.7,2,2,0,1,0,1,25,2,4,5,NA +64733,7,2,2,30,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,51753.495707,50822.503524,1,100,8,8,3.17,2,2,0,0,0,1,31,2,4,1,5 +64734,7,2,2,68,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,12331.419303,12882.003985,2,95,5,5,1.32,2,2,0,0,2,1,66,1,2,1,4 +64735,7,2,2,6,NA,3,3,1,6,79,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,49543.011606,52616.361829,1,94,15,15,5,6,6,0,4,0,1,38,1,5,1,4 +64736,7,2,1,6,NA,5,6,1,6,74,NA,NA,1,1,NA,0,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,8376.521179,8870.870608,1,92,12,12,NA,4,4,1,1,0,1,33,2,4,1,4 +64737,7,2,1,19,NA,4,4,1,19,236,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,17606.165994,17558.40257,2,101,2,2,0.73,2,1,0,0,0,1,20,1,4,5,NA +64738,7,2,1,15,NA,3,3,2,15,183,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,71458.892941,70519.759062,2,91,15,15,5,4,4,0,2,0,2,48,1,5,1,5 +64739,7,2,2,21,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,25026.664203,25574.319716,1,97,15,15,5,4,4,0,1,0,1,40,1,4,1,4 +64740,7,2,1,45,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,3,1,NA,1,2,1,1,2,2,1,2,1,3,16903.372311,16842.307696,1,97,9,9,1.78,6,6,0,1,1,1,45,2,3,1,3 +64741,7,2,2,44,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,25189.042335,25070.255719,1,100,14,14,5,3,3,0,1,1,2,44,1,4,5,NA +64742,7,2,1,56,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,16287.780872,16419.180608,2,100,4,4,1.74,1,1,0,0,0,1,56,1,3,3,NA +64743,7,2,1,10,NA,4,4,2,10,126,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8017.552697,8398.795399,1,99,10,10,2.07,7,7,2,3,1,2,35,1,5,4,NA +64744,7,2,2,5,NA,3,3,1,5,66,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,29420.847299,31676.739048,3,92,7,7,0.81,7,7,2,4,0,1,40,NA,NA,1,4 +64745,7,2,1,51,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,20820.576198,20899.685598,2,96,7,7,1.49,5,5,2,1,0,1,51,1,5,1,3 +64746,7,2,1,29,NA,4,4,2,NA,NA,2,NA,2,2,4,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,18523.956321,18232.779525,2,99,15,15,4.34,4,4,0,0,0,1,59,2,4,1,5 +64747,7,1,1,5,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9787.724348,0,1,96,10,10,3.51,3,3,1,0,0,1,25,1,4,1,5 +64748,7,2,2,0,4,4,4,1,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5576.185193,5739.245437,2,96,6,6,1.35,3,3,1,1,0,2,25,1,3,5,NA +64749,7,2,1,2,NA,5,6,2,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9239.758777,10363.400393,2,91,14,14,3.47,4,4,1,1,0,2,36,2,3,1,5 +64750,7,2,1,18,NA,1,1,1,18,226,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,1,1,2,2,1,32326.52031,34735.818434,2,98,13,13,NA,5,5,0,2,0,1,48,2,1,1,2 +64751,7,2,1,9,NA,3,3,2,9,118,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,61920.455064,68552.408117,2,94,12,12,NA,5,5,1,1,0,1,37,1,4,1,3 +64752,7,2,2,62,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,16352.915834,17093.606152,3,92,8,8,2.97,2,2,0,0,2,2,62,1,4,1,4 +64753,7,2,2,68,NA,2,2,2,NA,NA,2,NA,2,1,8,NA,1,4,NA,2,2,2,2,2,2,2,2,2,2,9716.805546,12994.252166,2,90,77,77,NA,1,1,0,0,1,2,68,2,1,4,NA +64754,7,2,1,36,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,14204.262514,14001.792163,1,99,6,6,0.6,7,7,2,1,1,2,69,1,3,2,NA +64755,7,2,1,3,NA,1,1,1,3,45,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,14415.164987,15444.808928,1,103,77,77,NA,4,4,1,0,1,1,20,1,3,6,NA +64756,7,2,1,72,NA,2,2,1,NA,NA,2,NA,2,1,6,NA,3,1,NA,2,2,2,1,2,2,2,2,2,NA,13654.270555,14323.606702,2,93,10,10,3.04,4,4,0,0,2,1,72,2,3,1,2 +64757,7,2,2,9,NA,5,7,2,10,121,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,67349.005531,67425.922822,1,95,8,8,1.28,7,7,1,4,0,1,32,1,3,1,3 +64758,7,2,1,33,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,20071.705576,20986.552878,3,91,14,14,5,2,2,0,0,0,2,27,2,5,1,5 +64759,7,2,1,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,1,2,1,2,2,1,1,2,NA,52279.532372,58506.425352,2,101,5,5,1.63,2,2,0,0,2,1,80,1,1,1,1 +64760,7,2,1,4,NA,3,3,2,4,56,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,77702.196479,85091.48102,1,95,9,9,2.68,4,4,2,0,0,2,27,1,4,1,4 +64761,7,2,1,25,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,34099.599202,35276.751365,1,94,7,7,1.65,5,4,0,0,0,1,46,1,4,1,4 +64762,7,2,1,17,NA,4,4,1,17,214,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,17606.165994,18260.901254,2,101,10,10,3.89,3,3,0,1,0,2,49,1,4,1,3 +64763,7,2,1,27,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,17583.693727,17701.770315,2,95,5,2,0.63,3,1,0,0,0,1,31,1,4,5,NA +64764,7,2,1,36,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,24555.036413,24478.369844,2,94,8,8,3.4,2,2,0,0,0,1,36,1,2,1,5 +64765,7,2,1,32,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,78529.577822,80778.70531,1,101,7,7,1.55,5,5,1,2,0,2,31,1,4,1,2 +64766,7,2,2,3,NA,1,1,1,3,39,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,11859.546176,12772.78418,1,102,5,5,0.62,7,7,1,3,0,1,49,2,2,1,1 +64767,7,2,2,7,NA,2,2,1,7,85,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,15510.382876,16516.802792,1,100,5,5,0.78,6,5,1,2,0,2,40,2,1,5,NA +64768,7,2,1,27,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,34099.599202,38616.556866,1,94,6,6,1.21,4,4,2,0,0,1,27,1,2,1,2 +64769,7,2,1,51,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,19093.004278,19397.753966,2,99,2,2,0.19,6,6,0,1,0,1,59,1,2,5,NA +64770,7,2,1,11,NA,5,6,2,11,141,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,5855.595238,6345.238788,1,91,15,15,3.25,7,7,1,2,0,2,31,1,5,1,5 +64771,7,2,1,64,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,11937.570805,12505.355675,2,96,3,3,0.24,7,7,2,3,1,2,40,1,3,3,NA +64772,7,2,1,50,NA,1,1,1,NA,NA,2,NA,2,2,7,NA,1,2,NA,2,2,2,2,2,2,NA,NA,NA,NA,31872.125984,32482.275435,2,96,4,4,1.56,1,1,0,0,0,1,50,2,1,2,NA +64773,7,2,2,16,NA,1,1,1,16,203,NA,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,19836.724169,20428.617367,1,98,15,15,5,5,5,0,1,1,2,55,1,5,1,5 +64774,7,2,2,5,NA,1,1,1,5,70,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15457.736897,16648.051651,2,98,5,5,0.59,7,7,2,1,2,2,71,1,2,1,1 +64775,7,2,2,6,NA,5,6,1,7,84,NA,NA,1,1,NA,1,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,6402.995556,7222.354698,2,92,7,7,1.61,4,4,0,2,0,1,51,2,3,1,3 +64776,7,2,2,29,NA,1,1,1,NA,NA,2,NA,2,2,3,NA,1,1,2,2,2,2,2,2,2,NA,NA,NA,NA,50915.06085,54061.945895,3,92,3,3,0.52,5,5,2,1,0,2,29,2,1,1,3 +64777,7,2,2,52,NA,4,4,2,NA,NA,2,NA,2,1,4,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,15790.702799,16017.473382,2,90,14,14,5,2,2,0,0,1,2,52,2,5,1,NA +64778,7,1,1,22,NA,5,6,NA,NA,NA,2,NA,2,1,99,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,13367.406737,0,1,92,15,15,4.44,5,5,0,0,1,1,65,NA,NA,1,5 +64779,7,2,2,30,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,2,1,2,2,1,2,2,1,2,2,1,26465.930618,27659.054945,2,100,7,7,1.79,4,4,0,1,0,2,51,1,3,3,NA +64780,7,2,2,18,NA,4,4,1,18,221,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13697.127402,14256.437303,2,100,4,4,1.16,2,2,0,0,1,2,18,1,2,NA,NA +64781,7,2,1,15,NA,2,2,2,15,185,NA,NA,1,1,NA,9,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,19820.949231,20163.121943,2,91,7,7,1.29,6,6,2,2,0,1,33,2,3,6,NA +64782,7,2,1,50,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,29250.663295,29731.562834,1,94,2,2,0.81,1,1,0,0,0,1,50,1,4,3,NA +64783,7,2,1,0,1,1,1,1,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4461.618312,4741.503802,1,103,7,7,0.51,7,7,3,4,0,1,54,2,1,1,1 +64784,7,2,1,21,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,1,6,NA,1,2,2,1,2,2,1,2,2,1,20135.920214,21074.978603,2,97,5,5,0.76,5,5,1,1,0,2,47,1,4,5,NA +64785,7,2,1,76,NA,1,1,1,NA,NA,2,NA,2,1,99,NA,1,1,NA,2,2,2,2,2,2,2,2,2,NA,21815.897449,22383.010849,3,92,5,5,1.26,3,3,0,0,2,1,76,2,1,1,1 +64786,7,2,2,46,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,113128.964375,115356.428049,1,94,15,15,4.95,4,4,0,0,2,1,72,1,3,1,3 +64787,7,2,1,10,NA,2,2,2,10,129,NA,NA,1,1,NA,3,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,9390.522479,10327.334743,2,90,1,1,0.06,3,3,0,2,0,2,32,2,2,77,NA +64788,7,2,1,5,NA,4,4,1,5,62,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12996.965152,13155.4937,1,101,6,6,1.72,2,2,1,0,0,2,29,1,4,5,NA +64789,7,2,1,67,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,7736.56115,7645.782314,1,99,15,15,5,2,2,0,0,2,1,67,1,5,1,5 +64790,7,2,1,2,NA,3,3,2,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,46703.291366,50234.137371,1,93,15,15,5,3,3,1,0,0,1,39,NA,NA,1,NA +64791,7,2,2,26,NA,2,2,2,NA,NA,2,NA,2,2,3,NA,1,6,2,2,2,2,NA,NA,NA,NA,NA,NA,NA,31196.446669,31060.57243,2,99,12,3,0.52,5,3,0,1,0,1,30,2,2,4,NA +64792,7,2,2,40,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,35815.777398,37277.17285,1,91,14,14,3.9,4,4,0,1,0,1,41,1,2,1,4 +64793,7,2,2,14,NA,2,2,2,14,173,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,23968.380373,25111.880337,2,91,14,14,4.19,3,3,0,1,0,1,55,2,3,1,5 +64794,7,2,2,29,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,NA,NA,NA,NA,20443.961017,19891.057859,2,99,6,6,1.13,4,4,1,1,0,1,33,1,3,6,NA +64795,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,9772.038079,10324.658831,1,95,3,3,0.78,3,3,0,0,2,1,80,1,4,1,3 +64796,7,2,1,1,15,5,6,2,NA,15,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5492.796032,5818.035599,2,100,4,4,0.5,6,6,2,1,0,1,30,2,4,1,3 +64797,7,2,1,0,9,3,3,2,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,21055.122405,22540.415493,1,93,15,15,5,3,3,1,0,0,1,33,1,5,1,3 +64798,7,2,2,6,NA,3,3,2,6,75,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,62595.719575,66478.781231,1,95,6,6,1.35,3,3,0,1,0,1,42,1,4,1,4 +64799,7,2,1,28,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,1,1,NA,2,2,2,2,2,2,1,2,2,2,38502.344077,41392.592866,1,100,13,13,NA,4,4,1,1,0,1,28,2,1,1,1 +64800,7,2,2,52,NA,4,4,2,NA,NA,2,NA,2,1,7,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,12449.932013,12483.65832,3,90,10,10,3.67,3,3,0,1,0,2,52,2,3,5,NA +64801,7,2,2,50,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,29167.119125,32047.917266,1,101,6,6,1.52,3,3,0,1,1,1,62,1,2,1,3 +64802,7,2,1,42,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,24874.121286,25386.96888,1,102,8,8,4.78,1,1,0,0,0,1,42,1,3,5,NA +64803,7,2,1,35,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,19440.629552,20463.14283,1,93,6,6,1.16,4,4,2,0,0,2,33,1,5,1,4 +64804,7,2,2,9,NA,3,3,2,9,115,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,73810.484644,74865.697805,1,94,10,10,2.67,5,5,0,3,0,1,40,1,5,1,2 +64805,7,2,1,38,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,19008.083201,19380.210545,2,101,2,2,0.73,1,1,0,0,0,1,38,1,2,5,NA +64806,7,2,1,80,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,40157.007559,43267.510233,2,98,8,8,3.4,2,2,0,0,2,1,80,1,4,1,4 +64807,7,2,2,35,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,66503.043118,67175.236045,2,98,14,14,3.25,5,5,2,1,0,1,37,1,5,1,5 +64808,7,2,1,44,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,16651.742047,16721.380189,1,100,15,15,5,4,4,0,1,0,1,44,2,5,1,5 +64809,7,2,2,26,NA,4,4,2,NA,NA,2,NA,2,1,2,NA,4,1,3,1,2,2,1,2,2,NA,NA,NA,NA,20146.149642,19228.641128,1,98,15,15,5,6,6,3,0,0,1,37,2,5,1,4 +64810,7,1,1,28,NA,5,6,NA,NA,NA,2,NA,2,2,1,NA,5,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,11321.172632,0,1,96,3,3,0.54,4,4,0,1,0,1,28,2,5,5,NA +64811,7,2,2,16,NA,5,6,1,16,199,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,8663.507259,9422.028242,1,102,9,9,2.39,5,5,0,1,1,1,55,2,5,1,5 +64812,7,2,2,17,NA,4,4,2,17,215,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,16317.790515,16843.623891,1,101,6,6,1.43,4,4,0,1,2,2,72,1,2,1,NA +64813,7,2,2,55,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,19944.119297,19741.288195,2,98,2,2,0.52,1,1,0,0,0,2,55,1,4,3,NA +64814,7,2,2,1,22,4,4,2,NA,22,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7348.24433,7960.486003,2,95,9,9,1.78,6,6,2,0,0,2,48,1,3,1,2 +64815,7,2,2,11,NA,1,1,1,11,137,NA,NA,1,1,NA,4,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,15352.601806,16028.326912,2,102,4,4,0.61,5,5,0,3,0,1,34,2,3,1,3 +64816,7,2,1,21,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,21763.209029,22385.504537,2,92,4,1,0,4,1,0,0,0,1,21,1,4,5,NA +64817,7,2,1,1,20,4,4,1,NA,21,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6376.965739,6454.74783,2,100,14,1,0,3,1,1,0,1,1,62,1,5,1,5 +64818,7,2,1,8,NA,5,6,1,8,103,NA,NA,1,1,NA,2,NA,NA,NA,1,1,1,1,2,1,1,2,2,1,7030.880662,7583.419516,3,91,14,14,3.58,4,4,1,1,0,1,39,2,5,1,5 +64819,7,2,2,2,NA,4,4,1,2,25,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7382.686927,8250.113235,2,100,9,9,3.24,3,3,1,0,0,1,32,1,3,1,4 +64820,7,2,1,7,NA,1,1,1,7,91,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,19774.151841,21259.203461,3,92,7,7,1.65,4,4,1,1,0,1,27,1,3,1,3 +64821,7,2,1,62,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,4,NA,1,2,2,1,2,2,1,2,2,1,11281.447612,11722.687225,2,92,8,8,4.59,1,1,0,0,1,1,62,1,3,4,NA +64822,7,2,1,53,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,29181.414565,30161.390695,1,94,2,2,0.63,2,1,0,0,0,1,53,1,3,6,NA +64823,7,2,2,43,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,6,2,1,2,2,1,2,2,1,2,2,1,23799.136983,23147.811167,1,92,15,15,4.44,5,5,0,3,0,2,43,1,5,6,NA +64824,7,2,1,62,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,33364.852884,34296.975056,1,97,2,2,0.76,1,1,0,0,1,1,62,1,5,3,NA +64825,7,2,2,52,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,150482.742079,150600.121666,2,98,15,15,5,2,2,0,0,1,2,52,1,4,1,4 +64826,7,2,1,61,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,7800.5318,8105.625946,2,96,3,3,1.01,1,1,0,0,1,1,61,1,3,3,NA +64827,7,2,2,8,NA,4,4,1,8,107,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11334.095519,11753.9565,2,96,4,4,0.65,5,5,0,3,0,1,30,1,4,1,2 +64828,7,2,2,58,NA,1,1,1,NA,NA,2,NA,2,2,2,NA,1,1,NA,2,2,2,1,2,2,2,2,2,2,35505.352567,36934.11174,3,92,5,5,1.39,2,2,0,0,0,1,56,2,1,1,1 +64829,7,2,2,11,NA,2,2,2,11,134,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12985.951695,13541.394178,1,90,15,15,5,4,4,0,2,0,2,43,1,5,1,5 +64830,7,2,1,15,NA,1,1,1,15,181,NA,NA,1,1,NA,9,NA,NA,NA,2,1,1,2,2,1,1,2,2,1,15506.325263,15357.347514,2,103,2,2,0.42,3,3,0,2,0,2,51,2,2,5,NA +64831,7,2,1,24,NA,5,7,1,NA,NA,1,1,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,10559.047286,11105.574109,2,94,5,5,2.2,2,1,0,0,0,1,23,NA,NA,5,NA +64832,7,2,1,32,NA,1,1,1,NA,NA,2,NA,2,2,5,NA,3,6,NA,1,2,2,1,2,1,2,2,2,2,40003.013263,41663.413523,1,91,7,7,2.1,3,3,0,1,0,2,29,2,3,6,NA +64833,7,2,2,37,NA,1,1,1,NA,NA,2,NA,2,2,2,NA,4,1,2,2,2,2,1,2,2,2,2,2,2,42456.72357,44069.75885,1,92,5,5,0.87,4,4,0,2,0,1,42,2,1,1,4 +64834,7,2,1,0,3,2,2,2,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,5271.338128,5219.242818,2,99,12,6,0.9,7,6,1,3,0,2,20,2,2,5,NA +64835,7,2,1,39,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,1,2,1,2,2,1,2,2,NA,25120.174741,26325.85923,2,102,3,3,0.76,3,3,0,1,1,2,66,1,2,3,NA +64836,7,2,2,0,2,2,2,2,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5803.542897,5681.443153,2,90,5,5,0.94,4,4,2,1,0,2,33,1,3,3,NA +64837,7,2,2,11,NA,5,6,1,11,143,NA,NA,2,1,3,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,5710.045626,5965.417422,1,100,5,5,0.74,6,6,0,3,0,1,40,2,3,1,4 +64838,7,2,2,18,NA,4,4,1,18,218,2,NA,1,1,NA,12,NA,NA,NA,1,2,2,1,2,2,NA,NA,NA,NA,10128.026158,10853.158449,2,103,2,1,0.43,2,1,0,0,0,1,20,1,3,6,NA +64839,7,2,1,37,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,39040.678458,39017.692919,2,98,14,14,3.25,5,5,2,1,0,1,37,1,5,1,5 +64840,7,2,1,10,NA,4,4,2,10,131,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8655.162127,8668.652185,2,95,6,6,0.86,6,6,0,4,0,2,32,1,4,6,NA +64841,7,2,1,8,NA,1,1,1,8,101,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,2,2,2,1,2,2,1,12622.023337,12821.760042,2,96,6,6,0.77,7,7,2,1,0,1,53,2,1,1,1 +64842,7,2,1,2,NA,1,1,1,2,25,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13968.423539,13738.28453,2,102,7,7,1.57,4,4,2,0,0,2,34,2,2,1,5 +64843,7,2,2,50,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,12764.594076,12653.781126,2,90,6,6,0.96,5,5,0,1,0,1,55,1,4,6,NA +64844,7,2,1,4,NA,4,4,2,4,51,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7431.820906,7890.591472,1,99,6,6,0.96,5,5,1,2,0,2,35,1,4,1,2 +64845,7,2,1,0,3,1,1,2,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,6298.658963,6480.002411,2,94,9,9,2.29,5,5,2,1,0,2,33,2,3,1,1 +64846,7,2,2,43,NA,5,6,2,NA,NA,2,NA,2,1,3,NA,2,1,2,1,2,2,1,2,2,NA,NA,NA,NA,12977.791943,13288.853946,2,100,4,4,0.44,7,7,1,2,2,1,71,2,1,1,1 +64847,7,2,2,11,NA,4,4,1,11,136,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11784.279565,12220.817194,2,96,8,8,2.46,4,4,0,1,0,1,46,1,4,1,4 +64848,7,2,1,69,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,9535.353518,9981.414158,2,97,4,4,1.02,2,2,0,0,2,2,80,1,1,2,NA +64849,7,2,1,0,5,3,3,2,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,20370.716701,20998.185689,1,91,14,14,3.06,5,5,2,0,0,2,30,1,5,1,5 +64850,7,2,1,19,NA,3,3,1,19,232,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,99014.954203,98621.869511,1,92,10,10,3.4,3,3,0,0,0,1,56,1,4,1,5 +64851,7,2,2,47,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,4,NA,1,2,2,1,2,2,1,2,2,NA,20212.648666,20286.466668,2,95,4,3,1.1,2,1,0,0,0,2,47,1,3,4,NA +64852,7,2,1,2,NA,4,4,1,2,27,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8009.966208,8832.297541,2,96,7,7,1.79,4,4,2,0,0,2,49,1,3,1,3 +64853,7,2,1,0,11,1,1,1,NA,12,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,2,2,2,NA,NA,NA,NA,6999.189812,7438.261811,2,98,6,6,0.59,7,7,2,2,1,2,52,2,1,1,1 +64854,7,2,2,69,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,10561.745159,14124.187136,2,90,6,6,1.73,2,2,0,0,2,2,69,1,2,1,2 +64855,7,1,1,8,NA,5,6,NA,NA,NA,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9720.482616,0,2,91,4,4,0.65,5,5,1,3,0,1,43,2,3,5,NA +64856,7,2,1,34,NA,1,1,2,NA,NA,2,NA,2,2,5,NA,1,5,NA,2,2,2,2,2,2,NA,NA,NA,NA,30626.581617,30395.433124,2,90,6,6,0.96,5,5,1,1,0,1,39,2,2,1,NA +64857,7,2,2,54,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,189736.955264,189051.893543,1,98,4,4,1.34,1,1,0,0,0,2,54,1,5,3,NA +64858,7,2,2,65,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,36148.01469,38158.744241,1,101,3,3,0.66,2,2,0,0,1,2,65,1,2,3,NA +64859,7,2,2,46,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,133853.800452,138128.446231,1,94,8,8,2.43,3,3,0,0,0,2,46,1,3,1,NA +64860,7,2,1,50,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,23605.367258,23717.233847,2,97,7,7,1.89,3,3,0,0,0,1,50,1,2,1,2 +64861,7,2,2,26,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,3,2,1,2,2,1,2,2,NA,NA,NA,NA,19266.853809,20089.582382,2,102,8,8,1.72,5,5,0,2,1,1,63,2,5,1,5 +64862,7,2,1,34,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,22188.836739,22911.854766,1,95,5,5,0.92,5,5,1,2,0,2,30,1,4,1,4 +64863,7,1,2,34,NA,3,3,NA,NA,NA,2,NA,2,2,2,NA,5,5,3,1,2,2,1,2,2,NA,NA,NA,NA,81658.419251,0,2,99,15,15,5,2,1,0,0,0,2,34,2,5,5,NA +64864,7,2,1,12,NA,4,4,1,13,156,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17606.165994,18413.211403,2,101,3,3,0.54,3,3,0,2,0,2,36,1,3,5,NA +64865,7,2,2,2,NA,4,4,2,2,28,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6677.461889,6849.81851,2,90,5,1,0,3,1,1,1,0,2,48,1,5,5,NA +64866,7,2,2,25,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,2,1,2,2,1,2,2,1,2,2,1,17794.144581,16918.878285,2,96,4,4,0.4,7,7,3,2,0,2,25,1,2,5,NA +64867,7,2,1,78,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,12856.852517,14031.201295,2,98,5,5,1.24,3,3,0,0,1,2,58,1,2,5,NA +64868,7,2,1,5,NA,1,1,1,5,65,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16775.083123,17973.290893,3,92,3,3,0.54,4,4,3,0,0,2,22,1,3,5,NA +64869,7,2,2,11,NA,5,6,2,11,133,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7751.448366,8179.286646,1,96,15,15,4.34,4,4,1,1,0,1,36,2,5,1,5 +64870,7,2,2,80,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,3,2,NA,1,1,1,1,2,2,1,2,1,NA,18698.205673,19635.336647,1,97,9,9,1.78,6,6,0,1,1,1,45,2,3,1,3 +64871,7,2,2,49,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,141912.982157,152670.471787,1,97,14,14,3.36,4,4,0,2,0,2,49,1,5,1,5 +64872,7,2,2,2,NA,1,1,1,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12871.484115,13281.030392,2,102,5,5,0.89,4,4,1,2,0,2,36,2,5,3,NA +64873,7,2,2,41,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,111065.717962,115110.76456,2,91,15,15,5,4,4,0,2,0,1,53,1,5,1,4 +64874,7,1,1,80,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,8168.05279,0,2,98,3,3,0.56,4,4,0,0,2,2,79,1,1,1,1 +64875,7,2,2,34,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,99606.074294,100835.770786,1,93,15,15,5,2,2,0,0,0,2,34,1,5,1,5 +64876,7,2,1,47,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,28680.660607,28606.985896,3,91,6,3,1.33,2,1,0,0,0,1,40,1,3,5,NA +64877,7,2,1,46,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,19260.892847,19199.459573,2,97,1,1,0.09,2,1,0,0,0,1,46,1,3,5,NA +64878,7,2,1,12,NA,3,3,2,12,150,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,19197.94644,18945.641357,1,98,6,6,1.73,3,3,0,1,0,2,39,1,4,1,1 +64879,7,2,2,8,NA,4,4,1,8,103,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9153.600624,9398.485171,1,100,8,8,1.61,6,6,1,3,0,1,29,1,5,6,NA +64880,7,2,1,60,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,153565.050575,157855.235487,1,97,15,15,5,2,2,0,0,1,2,49,1,5,1,3 +64881,7,2,1,33,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,15014.015332,15213.152707,3,92,8,8,0.91,7,7,3,3,1,1,61,NA,NA,1,4 +64882,7,2,1,65,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,160284.827389,161788.081948,2,102,14,14,5,2,2,0,0,2,2,65,1,5,1,5 +64883,7,2,1,18,NA,2,2,2,18,218,2,NA,2,2,1,10,NA,NA,NA,2,2,2,1,2,2,2,2,2,2,13752.835112,15116.811136,3,90,7,7,1.48,5,5,0,1,0,1,43,2,1,6,NA +64884,7,2,1,8,NA,4,4,1,8,105,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7908.091112,7920.416775,2,93,8,8,1.67,5,5,1,1,0,2,31,1,4,5,NA +64885,7,2,1,0,7,4,4,1,NA,8,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6275.847063,6684.003207,2,100,10,10,2.75,5,5,1,1,1,1,27,1,3,1,5 +64886,7,2,2,59,NA,2,2,1,NA,NA,2,NA,2,2,5,NA,1,1,NA,2,2,2,2,2,2,2,2,2,2,23476.411085,23902.152524,3,91,4,4,0.81,3,3,0,0,1,1,64,2,1,1,1 +64887,7,2,1,13,NA,3,3,2,13,158,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,32477.57544,34497.087834,1,95,7,7,1.66,5,5,0,3,0,1,34,1,2,1,4 +64888,7,2,2,2,NA,4,4,1,2,26,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8072.012312,8280.364646,3,91,8,8,2.24,4,4,2,0,0,1,39,2,3,1,3 +64889,7,2,2,51,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,20933.43123,22068.787492,2,95,6,6,1.19,4,4,0,1,0,1,44,1,3,1,2 +64890,7,2,1,29,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,15173.157442,14818.726738,2,96,12,10,2.17,7,6,2,3,0,1,29,1,4,3,NA +64891,7,2,2,11,NA,2,2,1,11,138,NA,NA,1,1,NA,5,NA,NA,NA,2,1,2,2,2,2,1,2,2,NA,14446.475406,15838.541371,1,103,7,7,1.03,7,7,0,3,0,1,50,2,1,1,1 +64892,7,2,1,21,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,16995.648055,17171.250195,2,100,5,5,1.08,3,3,0,1,0,2,50,1,4,3,NA +64893,7,2,2,23,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,76027.409363,76707.146234,2,103,15,15,3.44,7,7,0,1,2,2,79,1,3,2,NA +64894,7,2,2,6,NA,2,2,2,6,82,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,15583.587534,16935.930722,1,93,14,14,3.06,5,5,0,2,0,1,46,2,1,1,4 +64895,7,2,1,67,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,7323.703412,7380.991723,2,100,14,14,3.58,4,4,0,1,1,2,55,1,5,1,4 +64896,7,2,2,0,0,4,4,2,NA,0,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4706.214557,5182.816301,1,96,6,6,1.21,4,4,2,0,0,1,24,1,4,1,3 +64897,7,2,1,42,NA,5,6,2,NA,NA,2,NA,2,2,5,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,12254.763576,14641.804715,2,90,4,4,0.81,3,3,0,1,0,2,41,2,2,6,NA +64898,7,2,1,45,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,17036.36313,16982.025069,1,99,2,2,0.48,2,2,0,0,0,2,44,1,3,1,3 +64899,7,2,2,13,NA,5,6,1,13,157,NA,NA,2,2,2,7,NA,NA,NA,1,1,1,1,2,1,1,2,1,NA,8868.843265,9252.179416,2,92,8,8,2.43,3,3,0,1,1,2,58,NA,5,1,5 +64900,7,2,1,25,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,42894.724338,43561.362107,1,98,3,3,0.93,2,2,0,0,0,1,21,1,4,5,NA +64901,7,2,2,18,NA,4,4,1,18,216,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,10143.901078,10335.966318,2,95,2,2,0.67,2,2,0,0,1,2,61,1,3,3,NA +64902,7,2,1,31,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,20891.980831,21490.337905,2,97,3,2,0.83,2,1,0,0,0,1,30,1,4,5,NA +64903,7,2,1,35,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,22188.836739,23530.130278,1,95,5,5,1.84,3,1,0,0,0,1,35,1,3,6,NA +64904,7,2,2,52,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,34802.051557,36349.694696,1,95,6,4,1.7,2,1,0,0,0,1,53,1,2,6,NA +64905,7,2,2,1,12,3,3,2,NA,12,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,41219.757096,41761.398587,1,93,15,15,5,3,3,1,0,0,1,35,1,5,1,5 +64906,7,2,1,80,NA,5,7,1,NA,NA,2,NA,2,1,6,NA,3,1,NA,1,2,2,1,2,2,1,2,1,NA,13312.080419,14392.211707,1,102,10,10,3.22,4,4,0,0,2,2,29,2,5,5,NA +64907,7,1,1,41,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,126789.52929,0,1,101,15,15,5,4,4,0,2,0,2,40,1,4,1,3 +64908,7,2,2,60,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,13057.178942,13648.591881,1,102,6,6,2.94,1,1,0,0,1,2,60,1,4,3,NA +64909,7,2,1,74,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,12468.859946,13204.521198,2,96,7,7,1.33,6,6,0,3,1,1,74,1,1,1,NA +64910,7,2,2,15,NA,3,3,2,15,182,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,71837.483011,75155.181458,1,91,14,14,3.06,5,5,0,3,0,2,46,1,5,1,5 +64911,7,2,2,15,NA,5,6,2,15,181,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,5956.736263,6113.749553,2,100,15,15,5,3,3,0,1,0,1,48,2,5,1,5 +64912,7,2,2,9,NA,4,4,2,9,114,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8226.044997,8398.377256,2,95,1,1,0,4,4,2,1,0,2,27,1,4,5,NA +64913,7,2,1,12,NA,3,3,2,13,156,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,26824.630008,26493.112081,1,95,1,1,0.17,2,2,0,1,0,2,47,1,2,3,NA +64914,7,2,1,31,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,5,NA,1,2,2,1,2,2,1,2,2,3,17165.91562,17929.203991,2,96,15,7,3.67,3,1,0,0,0,1,31,2,5,1,NA +64915,7,2,1,4,NA,4,4,2,4,51,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8626.000813,9278.769273,2,97,2,2,0.21,7,7,2,3,0,2,32,1,4,5,NA +64916,7,2,1,31,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,15787.238477,16796.740962,2,98,4,3,1.01,2,1,0,0,0,1,46,NA,NA,77,NA +64917,7,2,1,5,NA,5,6,2,5,67,NA,NA,2,2,2,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8197.191196,8439.736714,1,93,7,7,2.32,3,3,1,0,0,1,36,2,5,1,5 +64918,7,2,1,1,16,3,3,1,NA,16,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,24594.444896,28818.16319,1,98,5,5,1.05,3,3,1,0,0,1,24,1,3,1,3 +64919,7,2,1,10,NA,5,6,2,10,127,NA,NA,1,1,NA,3,NA,NA,NA,1,1,1,1,2,1,1,2,2,1,9720.482616,10818.978947,2,91,12,12,NA,7,6,0,4,2,2,72,2,1,2,NA +64920,7,2,2,8,NA,4,4,2,8,103,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8395.64512,8728.346696,2,97,6,6,0.92,7,7,1,4,0,2,29,1,3,5,NA +64921,7,2,2,16,NA,4,4,2,16,202,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12857.456314,12921.235691,2,97,5,5,0.92,5,5,0,3,0,2,54,1,3,2,NA +64922,7,2,1,9,NA,5,6,1,9,115,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8376.521179,8870.870608,1,92,15,15,5,4,4,0,2,0,1,55,1,5,1,5 +64923,7,2,2,64,NA,4,4,2,NA,NA,2,NA,2,2,5,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,9113.905743,12222.082956,3,90,8,8,3.3,2,2,0,0,1,2,64,2,2,1,NA +64924,7,2,2,10,NA,5,7,1,10,129,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12120.418061,12942.575479,2,101,7,7,1.88,4,4,0,2,0,2,36,1,4,1,5 +64925,7,2,2,0,4,2,2,1,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7534.765808,7789.750955,1,98,3,3,0.37,5,5,2,1,0,1,44,2,4,1,3 +64926,7,2,1,14,NA,4,4,2,14,169,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13352.786991,13379.186543,2,97,7,7,1.06,7,7,1,2,0,2,40,1,4,5,NA +64927,7,2,2,2,NA,4,4,1,2,33,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7382.686927,7498.263904,2,100,3,3,0.39,7,7,3,3,0,2,30,1,2,5,NA +64928,7,2,1,80,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,1,3,NA,1,2,2,1,2,2,1,1,2,NA,14073.595908,15970.731967,1,92,6,6,1.3,4,4,0,1,1,1,25,1,1,1,3 +64929,7,2,1,19,NA,4,4,2,19,228,2,NA,1,1,NA,14,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,10791.290138,11351.304534,3,91,2,2,0.25,4,4,0,2,0,2,35,1,3,5,NA +64930,7,2,1,74,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,NA,13219.758853,13936.470139,2,97,4,4,1.29,2,2,0,0,2,1,74,1,3,3,NA +64931,7,2,2,59,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,26668.458882,27266.525973,2,102,6,6,2.04,2,2,0,0,1,1,64,1,3,1,4 +64932,7,2,1,6,NA,3,3,1,6,74,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,86609.650237,90490.601456,2,102,14,14,4.93,3,3,0,1,0,1,37,1,5,1,5 +64933,7,2,2,41,NA,1,1,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,31301.615973,33816.788039,1,90,15,15,4.77,4,4,1,1,0,2,41,1,5,1,2 +64934,7,2,2,16,NA,5,6,2,16,192,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,1,1,2,2,1,5607.756021,6010.481547,3,91,6,6,1.81,3,3,0,1,0,2,47,2,3,1,3 +64935,7,2,2,25,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,73820.224093,75002.443492,2,95,9,9,2.22,5,5,1,0,0,1,55,1,4,1,5 +64936,7,2,2,6,NA,2,2,1,6,82,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,17458.526997,17628.076413,1,94,2,2,0.26,4,4,2,1,0,2,25,1,4,5,NA +64937,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,37456.985636,43452.233213,2,98,6,6,1.7,2,2,0,0,2,2,80,1,2,1,2 +64938,7,2,1,40,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,27938.918808,28342.234566,1,100,7,7,3.4,1,1,0,0,0,1,40,1,5,5,NA +64939,7,2,1,19,NA,4,4,2,19,236,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,17606.165994,17558.40257,2,101,1,1,0.04,2,1,0,0,0,1,19,1,4,NA,NA +64940,7,2,1,13,NA,3,3,2,14,168,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,91343.020442,91081.271456,1,98,7,7,1,7,7,2,2,0,2,34,1,4,3,NA +64941,7,2,2,2,NA,1,1,1,2,30,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11512.764389,12710.400836,2,98,2,2,0.27,4,4,2,1,0,2,32,2,2,5,NA +64942,7,2,1,69,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,7101.739553,7433.956549,2,100,3,3,1.19,1,1,0,0,1,1,69,1,2,2,NA +64943,7,2,1,1,20,5,6,2,NA,21,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7638.291796,7864.300119,1,93,14,14,4.86,3,3,1,0,0,1,30,2,5,1,5 +64944,7,2,2,18,NA,4,4,2,18,225,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,15259.822784,15553.106132,1,90,5,5,0.74,5,5,0,2,0,2,18,1,4,NA,NA +64945,7,1,1,37,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,105412.227726,0,2,101,8,8,1.72,5,5,0,3,0,1,37,1,3,1,3 +64946,7,2,1,60,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,5866.209951,5912.09729,2,95,5,5,1.05,3,3,0,0,2,1,60,1,1,1,4 +64947,7,2,1,6,NA,5,6,2,6,73,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7491.978458,7984.984584,2,100,15,15,5,4,4,1,1,0,1,36,2,5,1,5 +64948,7,2,2,61,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,8308.628726,8679.600111,2,95,5,5,1.92,1,1,0,0,1,2,61,1,4,2,NA +64949,7,2,2,26,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,110941.813533,112262.474161,1,97,15,15,4.77,4,4,0,0,0,1,56,1,4,1,4 +64950,7,2,2,6,NA,2,2,2,7,84,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11210.83392,12007.401767,2,90,6,6,1.34,4,4,1,2,0,2,36,2,3,77,NA +64951,7,2,1,22,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,107912.705683,113084.898879,3,91,4,4,1.02,2,2,0,0,0,1,22,1,5,1,5 +64952,7,2,2,8,NA,4,4,2,8,102,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7120.704736,7311.203604,1,99,8,8,1.76,5,5,0,2,1,1,37,1,4,1,3 +64953,7,2,2,44,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,30863.871606,31440.435679,1,101,3,3,1.12,1,1,0,0,0,2,44,1,4,1,NA +64954,7,2,2,54,NA,5,6,2,NA,NA,2,NA,2,2,5,NA,1,3,NA,1,2,1,1,2,2,NA,NA,NA,NA,10964.859884,11022.841433,3,90,7,7,1.82,4,4,1,0,0,2,54,2,1,3,NA +64955,7,2,1,3,NA,4,4,1,3,42,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11342.022131,11810.675983,2,102,15,15,3.82,5,5,1,2,0,1,34,1,3,1,4 +64956,7,2,1,35,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,27572.205373,28421.693812,1,100,15,15,5,3,3,0,0,0,2,33,1,5,1,4 +64957,7,1,2,3,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11623.462338,0,1,100,3,3,0.73,3,3,1,1,0,2,32,1,3,5,NA +64958,7,2,2,8,NA,1,1,1,8,107,NA,NA,1,1,NA,3,NA,NA,NA,2,1,1,1,2,2,1,2,2,1,16217.354723,16799.750785,3,91,7,7,1.42,6,6,1,3,0,1,37,2,1,1,1 +64959,7,2,2,6,NA,2,2,2,6,82,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,17962.96045,18326.284291,1,97,15,15,4.52,6,6,0,4,0,2,41,1,5,1,5 +64960,7,2,2,6,NA,3,3,2,6,83,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13450.606713,13706.553337,3,91,5,5,1.07,4,4,0,2,0,2,36,1,5,1,4 +64961,7,2,1,56,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,141773.363283,142016.391545,1,97,15,15,4.77,4,4,0,0,0,1,56,1,4,1,4 +64962,7,2,2,32,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,39483.840194,39476.565757,2,102,14,14,3.25,5,5,1,1,0,2,32,1,4,1,3 +64963,7,2,1,55,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,20666.038321,20600.123288,1,96,14,14,5,1,1,0,0,0,1,55,1,5,5,NA +64964,7,2,1,80,NA,3,3,1,NA,NA,2,NA,2,1,4,NA,3,1,NA,1,2,1,1,2,2,1,2,1,NA,35161.248998,42165.766203,3,91,15,15,3.33,6,6,0,2,2,1,80,2,3,1,3 +64965,7,2,1,26,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,71402.235366,73020.331081,2,97,15,15,4.97,5,5,1,0,0,1,48,1,4,1,3 +64966,7,2,1,6,NA,3,3,2,6,78,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,57305.501166,60591.443404,1,94,15,15,5,3,3,0,1,0,1,46,1,5,1,5 +64967,7,1,2,58,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,24905.670199,0,2,101,1,1,0.15,3,3,0,2,0,2,58,1,3,5,NA +64968,7,2,2,50,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,16567.527819,16240.172481,1,96,15,15,5,4,4,0,1,0,1,56,1,4,1,5 +64969,7,2,1,18,NA,3,3,1,18,224,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,24849.884345,24917.808193,3,91,5,5,0.87,4,4,0,2,0,2,38,1,2,3,NA +64970,7,2,1,12,NA,2,2,1,12,149,NA,NA,1,1,NA,6,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,15626.107676,15463.700675,2,93,9,9,1.94,6,6,0,3,0,2,37,NA,NA,3,NA +64971,7,2,1,60,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,6358.062034,6381.990744,1,99,8,8,3.4,2,2,0,0,1,1,60,1,3,3,NA +64972,7,2,1,61,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,7289.557268,8219.094942,3,90,1,1,0,2,2,0,0,1,1,61,2,3,1,3 +64973,7,2,1,64,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,35869.019314,36329.101667,3,92,4,4,1.13,2,2,0,0,2,1,64,1,3,1,4 +64974,7,2,2,42,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,27585.470618,27304.927199,2,102,7,7,2.65,2,2,1,0,0,2,42,1,4,5,NA +64975,7,2,2,48,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,23016.024704,24471.525432,1,96,7,7,2.78,2,2,0,0,0,1,48,1,2,6,NA +64976,7,2,1,69,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,7323.703412,7380.991723,2,100,10,10,2.33,6,6,0,2,2,2,35,1,2,5,NA +64977,7,2,2,63,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,15732.436891,17625.53878,1,97,2,2,0.72,1,1,0,0,1,2,63,1,3,5,NA +64978,7,2,2,56,NA,2,2,2,NA,NA,2,NA,2,2,3,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,24548.478709,25991.798892,1,93,5,5,1.43,2,2,0,0,1,1,60,2,5,1,4 +64979,7,2,2,47,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,18822.975485,18307.835382,2,99,2,2,0.19,6,6,0,1,0,1,59,1,2,5,NA +64980,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,33147.414266,37148.276517,2,94,99,99,NA,1,1,0,0,1,2,80,1,4,2,NA +64981,7,2,1,46,NA,3,3,2,NA,NA,2,NA,2,1,6,NA,4,1,NA,1,2,2,1,2,1,1,2,2,1,19436.026093,20775.484483,2,97,5,5,0.8,5,5,1,2,0,1,46,2,4,1,2 +64982,7,2,1,16,NA,3,3,2,16,200,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,66448.116716,66629.743791,2,94,14,14,2.83,6,6,0,4,0,2,38,1,2,1,2 +64983,7,2,2,76,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,17836.372654,19170.472552,2,96,6,6,1.77,2,2,0,0,2,1,77,1,2,1,2 +64984,7,2,2,17,NA,3,3,2,17,213,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,NA,NA,NA,1,2,2,1,76360.13568,92040.479005,1,99,NA,NA,NA,4,4,0,1,0,1,50,NA,NA,1,NA +64985,7,2,1,65,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,1,7410.50521,7700.344649,2,96,6,6,2.75,1,1,0,0,1,1,65,1,2,2,NA +64986,7,1,2,28,NA,5,6,NA,NA,NA,2,NA,2,1,4,NA,5,5,3,1,2,2,1,2,2,NA,NA,NA,NA,16937.04417,0,1,95,3,3,0.43,4,4,0,1,2,1,65,2,5,1,3 +64987,7,2,1,17,NA,4,4,1,17,210,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,17606.165994,18413.211403,2,101,1,1,0.27,3,3,0,2,0,2,36,1,3,5,NA +64988,7,2,2,5,NA,4,4,2,5,66,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8897.78821,9699.858422,1,96,7,7,1,7,7,2,1,1,2,53,1,4,1,3 +64989,7,2,1,11,NA,2,2,2,11,138,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13217.721247,13515.808466,2,91,8,8,2.97,3,2,0,2,0,2,33,2,4,5,NA +64990,7,1,1,2,NA,5,7,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7390.005875,0,1,91,15,15,5,5,5,2,1,0,1,40,1,5,1,5 +64991,7,2,2,10,NA,5,6,2,10,128,NA,NA,1,1,NA,5,NA,NA,NA,1,1,1,1,2,1,1,2,2,1,6198.268014,6618.822195,3,90,15,15,3.23,6,6,0,2,0,1,50,2,2,1,2 +64992,7,2,1,76,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,15176.622228,16064.120023,1,101,3,3,1.12,1,1,0,0,1,1,76,1,5,2,NA +64993,7,1,1,57,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,16287.780872,0,2,100,15,14,5,2,1,0,0,0,1,57,1,5,6,NA +64994,7,2,1,27,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,106239.028397,111331.003215,2,92,10,5,1.96,2,1,0,0,0,2,27,2,5,1,NA +64995,7,2,2,68,NA,3,3,2,NA,NA,2,NA,2,2,4,NA,1,1,NA,1,2,1,1,2,1,1,2,1,NA,35700.429895,37686.262589,1,93,2,2,0.41,2,2,0,0,2,2,68,2,1,1,1 +64996,7,2,1,0,6,3,3,2,NA,7,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,19091.539058,20438.314938,2,95,8,8,2.17,4,4,1,1,0,1,43,1,4,1,5 +64997,7,2,2,15,NA,2,2,2,15,184,NA,NA,1,1,NA,66,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,13824.001771,15649.805677,2,90,2,2,0.3,3,3,0,1,0,2,51,2,2,5,NA +64998,7,2,1,54,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,144858.963765,145378.942103,2,97,9,9,5,1,1,0,0,0,1,54,1,5,5,NA +64999,7,2,1,32,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,18544.003944,19434.054198,2,100,5,5,1.63,3,2,0,1,0,2,50,1,2,5,NA +65000,7,2,1,4,NA,2,2,2,4,50,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,12403.412256,12420.172189,2,90,3,3,0.54,4,4,1,2,0,2,33,2,1,4,NA +65001,7,2,2,13,NA,5,7,2,13,160,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8777.486283,9116.900706,1,91,15,15,5,5,5,0,3,0,1,40,1,5,1,5 +65002,7,2,1,68,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,3,6,NA,1,2,2,NA,NA,NA,1,2,2,1,140267.560043,144186.249663,2,91,12,NA,NA,2,1,0,0,2,2,68,1,4,6,NA +65003,7,2,1,9,NA,3,3,1,9,109,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17738.769196,18719.457495,1,98,4,4,1,3,3,0,1,1,1,65,1,2,1,NA +65004,7,2,2,25,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,1,1,2,2,2,2,2,2,2,NA,NA,NA,NA,42557.597671,44940.417695,1,100,13,13,NA,4,4,1,1,0,1,28,2,1,1,1 +65005,7,2,2,71,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,73204.401173,96856.987278,2,91,12,12,NA,2,2,0,0,2,2,71,1,2,1,NA +65006,7,2,2,47,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,4,NA,1,2,2,1,2,2,1,2,2,1,25221.447441,25652.65048,1,100,14,14,3.93,3,3,0,1,0,2,47,1,5,4,NA +65007,7,2,2,24,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,1,1,1,2,2,1,2,2,1,2,2,1,18801.993237,20649.846581,2,96,14,14,5,2,2,0,0,0,1,30,2,5,1,5 +65008,7,1,1,80,NA,3,3,NA,NA,NA,1,2,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,11740.600601,0,3,91,13,13,NA,3,3,0,0,2,2,80,1,3,1,1 +65009,7,2,2,51,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,21491.090123,20964.324934,1,97,6,6,1.41,3,3,0,1,0,2,51,1,4,5,NA +65010,7,2,1,6,NA,4,4,1,6,79,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10469.725162,10967.571132,1,100,15,15,3.87,6,6,1,3,0,2,39,1,4,1,4 +65011,7,2,1,33,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,18289.793332,19321.216647,1,99,6,6,0.96,5,5,1,2,0,2,35,1,4,1,2 +65012,7,2,2,68,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,2,2,NA,1,2,1,1,2,1,1,2,1,3,12312.400687,12851.340698,1,103,2,2,0.45,1,1,0,0,1,2,68,2,2,2,NA +65013,7,2,2,7,NA,2,2,2,7,87,NA,NA,2,1,1,0,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,9872.244853,10294.506103,2,90,6,6,0.66,7,7,2,2,0,2,24,2,4,6,NA +65014,7,2,2,59,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,160743.928829,166234.629208,1,95,9,9,4.01,2,2,0,0,1,1,60,1,3,1,3 +65015,7,2,1,19,NA,4,4,1,19,236,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,17606.165994,17558.40257,2,101,99,1,0.09,4,1,0,0,0,1,18,2,4,NA,NA +65016,7,2,1,11,NA,3,3,1,11,136,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,22651.436723,23515.701302,3,92,7,7,0.81,7,7,2,4,0,1,40,NA,NA,1,4 +65017,7,2,1,4,NA,4,4,1,4,54,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10859.969359,11974.89205,1,101,2,2,0.47,3,3,1,0,0,1,35,1,2,6,NA +65018,7,2,2,14,NA,2,2,2,14,176,NA,NA,2,1,1,8,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,18254.385443,19735.623608,2,91,12,12,NA,5,5,0,1,1,2,43,2,3,6,NA +65019,7,2,2,9,NA,4,4,1,9,118,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11076.064101,11269.278002,2,102,15,15,4.2,5,5,1,2,0,2,29,NA,NA,1,NA +65020,7,2,1,62,NA,2,2,2,NA,NA,2,NA,2,2,7,NA,1,4,NA,2,2,2,2,2,2,2,2,2,2,8609.250304,11228.904188,2,90,2,2,0.73,1,1,0,0,1,1,62,2,1,4,NA +65021,7,2,2,36,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,96524.78948,102108.384344,1,97,7,7,1.87,4,4,1,1,0,1,35,1,2,1,4 +65022,7,2,2,29,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,5,3,1,2,2,1,2,2,1,2,2,1,13358.458751,14155.588359,2,92,15,15,5,3,1,0,0,0,2,33,NA,NA,5,NA +65023,7,2,2,13,NA,4,4,2,13,164,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11711.384457,11558.024533,2,95,6,6,0.86,6,6,0,4,0,2,32,1,4,6,NA +65024,7,2,1,9,NA,2,2,1,9,109,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,16281.509392,17100.217351,2,91,6,6,0.93,5,5,1,2,0,1,34,1,2,1,3 +65025,7,2,1,38,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,20891.980831,22249.799905,2,97,5,5,1.08,3,3,0,0,0,1,38,1,4,5,NA +65026,7,2,2,0,11,4,4,1,NA,12,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5058.520291,5113.753371,1,100,7,7,1.65,4,4,2,0,0,2,24,1,4,1,3 +65027,7,2,2,23,NA,2,2,1,NA,NA,2,NA,2,2,3,NA,4,5,2,2,2,2,1,2,2,2,2,2,2,35424.746838,35270.456492,2,93,4,4,0.56,5,5,0,0,0,2,49,2,2,5,NA +65028,7,2,1,80,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,15682.233511,17550.107712,1,101,3,3,0.95,2,2,0,0,2,1,80,1,2,1,NA +65029,7,2,2,6,NA,2,2,2,6,79,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,19936.606751,20692.800636,1,94,7,7,1.74,4,4,0,2,0,1,44,1,5,1,5 +65030,7,2,2,5,NA,4,4,2,5,61,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8041.669581,8652.926173,2,90,6,6,0.84,6,6,1,3,1,2,43,1,2,5,NA +65031,7,2,1,16,NA,2,2,1,16,199,NA,NA,2,2,1,8,NA,NA,NA,2,2,2,2,2,2,1,2,2,2,22124.028915,23090.48094,1,100,5,1,0,6,1,1,2,0,2,40,2,1,5,NA +65032,7,2,2,76,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,72094.421241,74006.954437,2,95,6,6,1.95,2,2,0,0,2,1,80,1,1,1,3 +65033,7,2,2,7,NA,4,4,1,7,90,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9453.111053,10094.338553,1,100,8,8,1.95,4,4,0,2,0,2,42,1,4,1,4 +65034,7,2,2,16,NA,4,4,2,17,204,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12161.822321,12177.990347,2,95,5,5,1.05,3,3,0,1,1,1,63,1,2,1,3 +65035,7,1,1,19,NA,1,1,NA,NA,NA,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,NA,NA,NA,NA,18042.255087,0,1,102,14,14,2.83,6,6,1,2,0,1,36,1,2,1,3 +65036,7,2,2,49,NA,4,4,2,NA,NA,2,NA,2,2,2,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,14814.740715,14686.129879,1,96,10,10,1.8,7,7,1,1,0,1,57,2,1,1,3 +65037,7,1,1,18,NA,3,3,NA,NA,NA,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,NA,NA,NA,NA,26749.020961,0,1,101,4,4,0.79,3,3,0,0,0,2,47,1,5,3,NA +65038,7,2,1,13,NA,2,2,1,13,162,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,21898.969807,22012.999264,2,102,15,12,NA,5,4,0,3,0,1,42,2,4,6,NA +65039,7,2,2,6,NA,5,6,2,6,80,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8067.514021,8614.897055,1,90,14,14,3.33,5,5,1,2,0,1,41,1,5,1,5 +65040,7,2,2,58,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,18710.568399,18832.614147,2,92,12,12,NA,2,1,0,0,1,2,58,1,3,5,NA +65041,7,2,2,11,NA,5,6,1,11,139,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8290.163782,8692.019106,1,92,14,14,3.69,4,4,0,2,0,1,47,2,4,4,NA +65042,7,2,1,14,NA,5,7,2,15,180,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15861.375368,15958.829994,1,95,7,7,1.57,4,4,0,2,0,1,39,1,3,1,3 +65043,7,2,2,7,NA,1,1,1,7,92,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15841.451259,16252.614023,3,92,15,15,3.15,7,7,0,4,0,2,35,2,3,3,NA +65044,7,2,2,15,NA,5,6,1,15,188,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10142.281747,10534.471105,3,91,15,15,5,4,4,0,2,0,1,44,2,5,1,5 +65045,7,2,1,80,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,NA,10479.637868,11291.375185,1,92,2,2,0.87,1,1,0,0,1,1,80,1,4,5,NA +65046,7,2,1,74,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,13704.691347,15557.045236,1,90,15,15,5,2,2,0,0,2,1,74,1,3,1,3 +65047,7,2,1,42,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,126789.52929,140129.484883,1,101,14,14,3.3,4,4,0,2,0,2,42,1,4,1,3 +65048,7,2,1,61,NA,1,1,1,NA,NA,2,NA,2,2,9,NA,1,1,NA,1,2,2,1,2,2,1,2,2,1,10596.142548,10802.656005,1,94,7,7,1.52,4,4,0,2,2,1,61,2,1,1,5 +65049,7,2,1,24,NA,2,2,1,NA,NA,2,NA,2,2,2,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,37911.437415,38428.199561,2,103,7,7,2.64,2,2,0,0,0,2,21,2,3,1,3 +65050,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,39565.288792,43332.356399,1,99,10,10,4.89,2,2,0,0,2,2,63,1,5,5,NA +65051,7,2,2,80,NA,2,2,2,NA,NA,2,NA,2,1,9,NA,1,2,NA,2,2,2,1,2,2,1,2,2,NA,17318.187297,23904.945555,2,90,3,3,0.92,1,1,0,0,1,2,80,2,1,2,NA +65052,7,2,1,42,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,1,109309.268477,109028.475475,3,91,15,15,5,2,2,0,1,0,1,42,1,5,2,NA +65053,7,2,2,0,4,1,1,1,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7565.515117,7406.345541,1,100,6,6,1.57,3,3,1,0,0,1,39,1,3,1,5 +65054,7,2,1,10,NA,3,3,1,10,127,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,32654.748828,36152.216038,1,94,5,5,0.87,4,4,0,1,0,1,40,1,5,1,5 +65055,7,1,1,33,NA,5,6,NA,NA,NA,2,NA,2,1,5,NA,2,1,NA,1,2,2,1,2,1,NA,NA,NA,NA,15014.015332,0,3,92,77,77,NA,7,7,2,4,1,1,62,NA,NA,1,NA +65056,7,2,1,76,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,8992.410435,9337.125921,2,90,9,9,3.02,3,3,0,0,2,2,70,1,4,1,2 +65057,7,2,2,3,NA,5,6,2,3,44,NA,NA,2,2,2,NA,NA,NA,NA,1,1,2,1,2,1,NA,NA,NA,NA,3864.413878,4049.242646,1,99,6,6,1.07,6,6,2,1,2,1,44,2,5,4,NA +65058,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,23338.32018,25560.39495,1,99,77,77,NA,2,2,0,0,2,1,80,1,5,1,4 +65059,7,2,2,0,1,4,4,1,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4128.726485,4173.807313,2,93,6,6,1.08,4,4,2,0,0,1,25,1,3,6,NA +65060,7,2,1,0,6,4,4,1,NA,8,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6275.847063,6487.671462,2,93,9,9,2.86,4,4,1,1,0,1,30,1,4,6,NA +65061,7,2,1,38,NA,5,6,2,NA,NA,2,NA,2,2,2,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,19091.246741,19659.303383,1,91,10,10,3.22,4,4,1,1,0,1,38,2,5,1,5 +65062,7,2,1,10,NA,4,4,2,10,128,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8836.464036,8942.399437,1,96,15,15,5,5,5,0,3,0,2,47,1,5,1,5 +65063,7,2,1,28,NA,4,4,2,NA,NA,2,NA,2,2,6,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,19137.192683,18862.909907,1,96,14,14,5,2,2,0,0,0,2,47,2,4,5,NA +65064,7,2,1,7,NA,1,1,1,7,84,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,13665.416457,13541.311863,1,94,2,2,0.27,5,5,0,4,0,2,47,2,1,4,NA +65065,7,2,2,34,NA,3,3,1,NA,NA,2,NA,2,2,2,NA,5,1,1,1,2,2,1,2,2,1,2,2,1,77299.255327,80009.772488,2,92,10,10,4.89,2,2,0,0,0,2,34,2,5,1,5 +65066,7,2,1,45,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,32980.717958,33913.235726,1,95,7,7,2.16,3,3,0,0,1,1,45,1,3,1,4 +65067,7,2,2,42,NA,3,3,1,NA,NA,2,NA,2,2,2,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,118432.300444,124617.656629,2,93,9,9,3.77,2,2,0,0,0,2,42,2,4,1,5 +65068,7,2,1,0,8,4,4,2,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5572.446681,5657.975893,1,99,10,10,3.51,3,3,1,0,0,1,27,1,4,1,4 +65069,7,2,1,62,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,1,1,NA,2,2,2,1,2,2,2,2,2,2,11397.665899,11580.241952,1,101,3,3,0.41,5,5,0,2,1,2,36,2,4,4,NA +65070,7,2,1,3,NA,2,2,2,3,39,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11186.576454,11318.825779,2,90,3,3,0.46,5,5,3,0,0,2,22,1,2,5,NA +65071,7,2,2,79,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,55250.133125,58713.117248,1,91,14,14,3.25,4,4,0,0,1,1,50,1,2,1,3 +65072,7,2,2,27,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,48991.867549,51378.468052,1,93,14,14,5,2,2,0,0,0,2,59,2,5,5,NA +65073,7,2,2,4,NA,3,3,2,4,58,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,52402.97499,54053.880354,1,91,15,15,4.59,4,4,2,0,0,1,35,1,5,1,5 +65074,7,2,1,42,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,21924.03349,22615.591521,2,98,10,10,4.76,2,2,0,0,0,1,42,1,2,6,NA +65075,7,2,2,45,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,108335.731552,113413.419502,1,98,15,15,4.34,4,4,0,2,0,1,51,1,5,1,5 +65076,7,2,2,50,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,16859.368198,16397.96736,1,99,8,8,1.99,5,5,1,0,0,1,55,1,5,1,2 +65077,7,2,1,60,NA,2,2,1,NA,NA,2,NA,2,2,5,NA,5,1,NA,2,2,2,2,2,2,2,2,2,2,9068.437099,9213.701881,2,93,77,77,NA,2,2,0,0,1,2,50,NA,NA,1,5 +65078,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,51218.356583,59416.206008,2,98,2,2,0.77,1,1,0,0,1,2,80,1,1,2,NA +65079,7,2,2,35,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,29733.812317,30162.048345,1,101,4,4,0.99,2,2,0,1,0,2,35,1,3,5,NA +65080,7,2,1,74,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,7005.52791,7142.750358,2,99,6,6,2.24,1,1,0,0,1,1,74,1,4,2,NA +65081,7,2,1,8,NA,2,2,1,8,101,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,2,2,2,2,2,2,2,12577.115885,12876.06354,2,96,6,6,1.25,4,4,1,1,0,1,31,2,3,1,3 +65082,7,2,2,14,NA,1,1,1,14,173,NA,NA,1,1,NA,8,NA,NA,NA,2,1,1,1,2,2,1,2,2,1,20830.737445,21782.111761,3,91,7,7,1.42,6,6,1,3,0,1,37,2,1,1,1 +65083,7,2,2,0,2,1,1,1,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7798.643057,7634.568742,1,102,6,6,1.73,3,3,1,0,0,2,24,2,5,1,5 +65084,7,2,2,26,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,18299.168537,17535.171386,2,100,5,5,0.95,4,4,0,0,1,2,53,1,3,5,NA +65085,7,2,1,51,NA,4,4,1,NA,NA,2,NA,2,2,5,NA,3,1,NA,1,2,1,1,2,1,1,2,1,NA,18061.358948,18950.803173,2,93,4,4,0.69,4,4,0,0,0,1,23,2,3,5,NA +65086,7,2,1,46,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,98850.665857,102087.416196,1,103,15,15,5,3,3,0,1,0,1,46,1,5,1,5 +65087,7,2,2,74,NA,2,2,2,NA,NA,2,NA,2,2,5,NA,1,2,NA,2,2,2,1,2,2,1,2,2,NA,17318.187297,19970.708273,2,90,7,7,1.57,4,4,0,0,1,2,20,1,2,5,NA +65088,7,2,2,37,NA,3,3,2,NA,NA,2,NA,2,2,1,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,95214.22557,102645.939709,1,97,15,1,0.4,5,1,1,1,0,2,38,NA,NA,1,5 +65089,7,2,2,3,NA,4,4,2,3,37,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9630.497627,10362.522874,1,96,13,13,NA,5,5,1,1,0,1,42,1,3,5,NA +65090,7,2,2,18,NA,5,7,1,18,218,2,NA,2,2,2,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,6391.016092,6494.382638,1,100,99,99,NA,6,6,0,1,0,1,53,2,2,1,3 +65091,7,2,1,33,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,22188.836739,23952.480361,1,95,5,5,1.03,4,4,0,2,0,1,33,1,3,1,3 +65092,7,2,1,8,NA,2,2,2,8,101,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8613.834494,9046.977066,2,90,7,7,0.89,7,7,1,3,3,1,60,2,3,1,3 +65093,7,2,2,22,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,29040.300396,28462.118402,2,101,6,6,1.67,3,3,0,0,0,2,22,1,4,5,NA +65094,7,2,1,10,NA,4,4,1,10,129,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13423.881856,14062.200951,2,101,6,6,0.96,5,5,0,4,0,2,36,1,4,4,NA +65095,7,2,2,41,NA,1,1,1,NA,NA,2,NA,2,2,7,NA,4,1,1,2,2,2,2,2,2,2,2,1,2,33716.655399,34130.121207,1,100,7,7,1.3,5,5,0,3,0,1,43,2,2,1,4 +65096,7,2,2,7,NA,1,1,1,8,96,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,15962.145468,16535.37648,2,98,3,3,0.33,7,7,2,3,0,1,40,2,1,1,1 +65097,7,2,1,80,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,28280.669788,29879.976389,1,99,14,14,5,2,2,0,0,2,2,79,1,3,1,5 +65098,7,2,2,68,NA,4,4,2,NA,NA,2,NA,2,1,7,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,11355.3308,12230.621635,1,96,7,7,1.39,5,5,0,2,2,1,69,2,2,1,2 +65099,7,2,2,1,18,4,4,1,NA,18,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5987.067673,6442.151602,2,93,4,4,0.56,5,5,2,1,0,1,27,1,2,6,NA +65100,7,2,2,2,NA,5,6,2,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5520.445386,5614.569811,2,100,15,15,5,4,4,1,1,0,1,41,2,5,1,5 +65101,7,2,1,75,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,NA,10310.165525,10913.082896,1,93,3,3,0.92,1,1,0,0,1,1,75,1,5,3,NA +65102,7,2,2,35,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,17884.885732,18259.455804,2,95,3,3,0.52,3,3,1,0,0,1,37,1,4,1,4 +65103,7,2,1,12,NA,4,4,2,12,149,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10453.50644,10655.928666,1,90,14,14,2.96,5,5,1,2,0,1,31,1,5,1,4 +65104,7,2,2,8,NA,3,3,2,9,108,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,80369.555824,80552.420473,1,97,15,15,3.89,5,5,0,2,0,1,50,1,4,6,NA +65105,7,2,2,24,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,1,1,2,2,1,2,2,1,2,2,1,24654.107413,23441.410215,1,100,10,10,2.59,5,5,0,1,0,2,40,1,5,1,NA +65106,7,2,1,32,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,20880.649884,21300.208451,1,96,14,6,2.69,2,1,0,0,0,2,29,1,5,6,NA +65107,7,2,1,14,NA,1,1,2,14,174,NA,NA,1,1,NA,7,NA,NA,NA,2,1,2,1,2,2,1,2,2,2,20398.562455,21727.336109,2,94,5,5,0.67,6,6,1,3,0,1,37,2,3,1,4 +65108,7,2,2,8,NA,3,3,1,8,105,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,55469.656717,57246.428971,1,98,9,9,2.15,5,5,0,3,0,2,32,1,3,1,4 +65109,7,2,1,3,NA,5,6,1,3,40,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10273.602479,11522.969217,2,98,9,9,3.83,2,2,1,0,0,2,29,2,4,5,NA +65110,7,2,2,23,NA,5,6,1,NA,NA,2,NA,2,2,1,NA,4,5,2,1,2,2,1,2,2,NA,NA,NA,NA,16929.836231,18593.694637,2,101,4,2,0.55,2,1,0,0,0,2,23,2,4,5,NA +65111,7,2,1,14,NA,3,3,2,14,177,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18645.590959,18737.183314,2,97,9,9,1.45,7,7,1,2,2,2,45,1,3,5,NA +65112,7,2,2,60,NA,5,6,2,NA,NA,2,NA,2,1,8,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,12592.413049,13033.910742,1,93,8,8,4.13,1,1,0,0,1,2,60,2,4,3,NA +65113,7,2,1,43,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,3,1,NA,1,2,1,1,2,1,1,2,1,3,11558.146957,12085.615817,3,90,6,6,1.3,4,4,0,2,0,2,37,2,4,1,3 +65114,7,2,2,38,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,3,2,1,2,2,1,2,2,1,2,2,1,27375.405353,30621.081524,3,91,5,5,0.87,4,4,0,2,0,2,38,1,2,3,NA +65115,7,2,2,19,NA,4,4,1,19,232,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,18163.985724,18749.311901,2,101,2,1,0.23,4,1,0,0,0,2,19,1,4,NA,NA +65116,7,2,1,0,10,2,2,2,NA,10,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4884.343512,4884.433539,3,90,7,7,2.1,3,3,1,0,0,1,34,2,3,1,2 +65117,7,2,1,16,NA,4,4,2,16,203,NA,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11351.725436,12116.15399,2,95,14,14,4.58,3,3,0,1,1,1,61,1,4,1,5 +65118,7,2,1,8,NA,2,2,2,8,99,NA,NA,2,1,3,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10872.115681,10826.020253,1,99,77,77,NA,3,3,0,1,0,1,52,1,5,1,5 +65119,7,2,2,31,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,66503.043118,66707.517935,2,98,8,8,1.8,5,5,2,1,0,1,32,1,4,1,5 +65120,7,2,1,8,NA,2,2,1,8,100,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14570.588291,14577.04302,1,98,3,3,0.4,7,7,2,3,0,2,31,2,5,1,2 +65121,7,2,1,3,NA,2,2,1,3,46,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,2,2,2,NA,NA,NA,NA,15745.774489,15931.923312,2,91,2,2,0.19,5,5,3,0,0,1,24,2,1,1,3 +65122,7,2,2,24,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,114993.808573,120122.111367,1,98,8,8,2.62,3,3,0,0,0,1,50,NA,NA,3,NA +65123,7,2,2,13,NA,4,4,1,14,168,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,19222.393687,19147.000359,1,92,9,7,1.74,7,4,2,1,0,1,45,1,4,2,NA +65124,7,2,2,28,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,5,1,1,1,2,2,1,2,2,1,2,2,1,30253.427014,31766.413225,2,90,6,6,1.62,3,3,1,0,0,2,28,1,5,1,4 +65125,7,2,2,40,NA,2,2,1,NA,NA,2,NA,2,2,3,NA,2,3,2,2,2,2,2,2,2,2,2,2,2,25713.328161,27565.019075,2,103,5,5,0.65,6,6,1,0,1,2,61,2,1,2,NA +65126,7,2,2,63,NA,4,4,2,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,10346.035773,10598.2543,1,99,15,15,5,2,2,0,0,2,2,63,2,5,1,5 +65127,7,1,2,17,NA,2,2,NA,NA,NA,2,NA,2,1,3,12,NA,NA,NA,2,2,2,1,2,2,NA,NA,NA,NA,26657.121865,0,1,97,15,15,5,4,4,0,2,0,1,51,1,5,1,NA +65128,7,2,1,24,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,25815.880139,26503.609729,2,101,1,1,0.09,2,1,0,0,0,1,23,1,5,5,NA +65129,7,2,2,45,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,23759.65375,25262.180522,3,92,4,4,1.22,2,2,0,0,0,1,51,1,2,1,3 +65130,7,1,2,38,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,5,1,3,1,2,2,1,2,2,NA,NA,NA,NA,95214.22557,0,1,97,15,15,5,5,5,2,0,1,1,43,1,5,1,5 +65131,7,2,1,24,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,39031.957066,40864.300461,1,101,5,5,1.24,3,3,0,0,1,2,61,1,4,1,3 +65132,7,2,2,33,NA,1,1,2,NA,NA,2,NA,2,2,3,NA,1,6,2,2,2,2,2,2,2,2,2,2,2,38737.690941,37692.46666,1,97,4,4,0.72,5,5,2,1,0,2,33,2,1,6,NA +65133,7,2,2,47,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,99275.150567,104459.98751,2,95,3,3,0.93,2,2,0,0,0,1,45,1,4,1,5 +65134,7,2,2,2,NA,4,4,2,3,36,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6689.921427,7247.312894,1,96,15,15,4.81,5,5,1,1,0,2,35,1,5,1,5 +65135,7,2,1,55,NA,5,6,1,NA,NA,2,NA,2,1,8,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,16499.662173,16440.055989,3,91,15,15,5,2,2,0,0,0,2,46,1,5,1,5 +65136,7,2,1,7,NA,4,4,1,7,93,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10311.165779,10291.779514,2,98,3,3,0.54,3,3,1,1,0,2,29,1,2,1,NA +65137,7,2,2,8,NA,3,3,2,8,103,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,48532.852397,48387.04619,1,98,14,14,3.9,4,4,0,3,0,2,31,1,4,1,NA +65138,7,2,2,0,11,5,7,2,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4867.693222,4920.842696,2,97,2,2,0.43,4,4,3,0,0,2,25,1,4,5,NA +65139,7,2,1,61,NA,1,1,1,NA,NA,1,1,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,14488.953694,16384.525762,3,92,4,1,0.11,7,1,0,3,1,1,61,1,3,3,NA +65140,7,2,2,11,NA,5,6,2,11,136,NA,NA,2,2,4,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6198.268014,6649.703491,3,90,14,14,3.47,4,4,1,1,0,2,38,2,5,1,5 +65141,7,2,1,21,NA,1,1,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,39084.166385,39616.913732,1,97,4,4,0.65,4,4,0,1,0,2,45,2,2,3,NA +65142,7,2,1,23,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,17583.693727,18076.30431,2,95,1,1,0.03,3,3,1,0,0,1,23,1,3,6,NA +65143,7,2,1,62,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,10555.964373,11135.911352,2,92,6,5,2.2,3,1,0,0,2,1,80,NA,NA,2,NA +65144,7,2,1,48,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,87072.438071,86848.766907,1,102,8,8,1.91,5,5,1,2,0,2,38,1,5,1,4 +65145,7,2,2,57,NA,1,1,2,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,28713.036659,29755.292291,1,97,10,10,3.59,3,3,0,0,0,2,57,1,3,1,NA +65146,7,2,1,14,NA,2,2,2,14,176,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15991.147079,16786.340864,2,90,6,6,1.34,4,4,1,2,0,2,36,2,3,77,NA +65147,7,1,2,36,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,5,1,3,1,2,2,1,2,2,NA,NA,NA,NA,97803.500399,0,1,95,14,14,3.8,4,4,1,1,0,1,36,1,4,1,5 +65148,7,2,2,12,NA,1,1,1,12,145,NA,NA,2,2,3,5,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,18515.058419,19067.51542,2,96,5,5,0.89,4,4,1,1,0,2,36,2,4,6,NA +65149,7,2,1,31,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,19508.889464,19600.270833,2,102,5,5,0.67,6,6,0,4,0,2,33,1,2,6,NA +65150,7,2,2,53,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,25964.813959,25700.75257,2,101,7,7,2.52,2,2,0,0,0,2,53,1,4,1,2 +65151,7,2,2,26,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,44119.608456,48674.237788,2,98,7,7,2.16,3,3,1,0,0,2,26,1,3,1,3 +65152,7,2,1,13,NA,4,4,2,13,162,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,16890.963304,17218.04077,1,91,10,10,2.56,5,5,0,3,0,1,51,2,5,1,4 +65153,7,2,1,80,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,NA,40859.270352,44024.169267,2,101,14,14,5,1,1,0,0,1,1,80,1,5,5,NA +65154,7,2,1,22,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,104488.914565,106745.836574,1,98,4,1,0.4,4,1,0,0,0,1,22,1,5,5,NA +65155,7,2,2,8,NA,5,6,1,8,100,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6273.782555,6554.366499,2,94,15,15,5,5,5,0,2,1,1,47,2,5,1,5 +65156,7,2,1,44,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,31053.116279,31557.850777,2,97,5,5,1.84,2,1,0,0,0,2,45,1,2,4,NA +65157,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,NA,51644.110977,57877.507418,1,102,6,6,2.48,1,1,0,0,1,2,80,1,4,3,NA +65158,7,2,2,4,NA,5,6,2,4,57,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,6683.092466,6676.033575,3,91,13,13,NA,3,3,1,0,0,2,41,2,1,1,3 +65159,7,2,2,0,4,3,3,2,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10692.488346,11331.751026,1,95,1,1,0.21,4,4,1,0,1,2,75,1,1,2,NA +65160,7,2,2,17,NA,4,4,2,17,211,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12209.74498,12781.910285,2,90,5,5,1.08,3,3,1,1,0,2,23,1,2,5,NA +65161,7,2,2,80,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,18344.917534,19717.054857,2,101,3,3,0.9,2,2,0,0,1,1,57,1,2,5,NA +65162,7,2,1,32,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,83819.702285,89179.486894,1,99,9,9,5,1,1,0,0,0,1,32,1,3,5,NA +65163,7,2,1,70,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,69210.206708,72962.448849,1,98,12,12,NA,2,2,0,0,2,1,70,1,2,1,3 +65164,7,2,1,42,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,20953.00978,22152.088593,2,97,2,2,0.3,4,4,0,2,0,1,42,1,2,6,NA +65165,7,2,2,63,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,10561.526228,11375.629073,2,95,7,7,2.31,2,2,0,0,2,2,63,1,3,1,3 +65166,7,2,1,17,NA,4,4,2,17,205,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12462.601191,12584.643654,2,97,4,4,0.81,4,4,1,1,0,2,51,1,3,4,NA +65167,7,2,2,17,NA,4,4,2,17,208,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,9608.885901,9632.551122,1,96,77,77,NA,7,7,1,3,0,1,56,1,3,1,4 +65168,7,2,1,16,NA,2,2,1,17,204,NA,NA,2,2,4,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,15626.107676,15463.700675,2,93,9,9,1.94,6,6,0,3,0,2,37,NA,NA,3,NA +65169,7,2,2,59,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,12649.084278,13261.522577,3,90,1,1,0,2,2,0,0,1,1,61,2,3,1,3 +65170,7,2,1,4,NA,5,6,2,4,57,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7580.437211,8294.186048,2,92,12,12,NA,7,7,2,4,0,1,54,2,2,1,5 +65171,7,2,2,13,NA,3,3,2,13,157,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,99340.784743,108314.70799,2,91,15,15,5,4,4,0,2,0,1,53,1,5,1,4 +65172,7,2,2,34,NA,3,3,2,NA,NA,2,NA,2,1,6,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,89807.047643,91549.325071,3,91,7,7,1.74,4,4,0,2,0,1,45,2,2,1,4 +65173,7,2,2,41,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,5,1,2,1,2,2,NA,NA,NA,1,2,2,1,12969.776823,13038.360257,2,90,3,3,0.65,5,3,1,2,0,1,44,2,5,1,5 +65174,7,2,2,31,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,85610.546667,92292.669073,2,91,14,14,4.19,3,3,0,1,0,2,31,1,4,1,3 +65175,7,2,2,50,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,15521.115746,16049.689005,2,100,5,5,1.63,3,2,0,1,0,2,50,1,2,5,NA +65176,7,2,2,45,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,19130.246369,18737.157388,2,95,10,10,2.32,6,6,1,2,0,1,44,1,4,1,4 +65177,7,2,1,22,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,120604.496044,126250.391527,2,92,10,10,3.51,3,3,0,0,0,1,24,1,4,5,NA +65178,7,2,2,0,10,3,3,1,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7569.605114,7776.819156,2,102,6,6,1.01,5,5,2,0,0,2,18,1,3,NA,NA +65179,7,2,1,48,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,22433.902709,22559.455212,1,100,15,15,5,2,2,0,0,0,1,48,2,5,1,5 +65180,7,2,2,14,NA,4,4,2,14,172,NA,NA,2,2,3,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10694.834447,10900.381844,1,90,4,4,0.58,6,6,0,3,0,2,21,2,5,5,NA +65181,7,1,1,3,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,58618.419318,0,2,94,14,14,2.87,5,5,2,1,0,1,37,1,3,1,4 +65182,7,2,1,45,NA,2,2,1,NA,NA,2,NA,2,2,5,NA,2,6,NA,2,2,2,1,2,2,2,2,1,2,34128.967046,33628.177065,2,93,3,3,0.43,4,4,0,0,0,1,45,2,2,6,NA +65183,7,2,1,62,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,3,1,NA,1,2,1,1,2,1,1,2,1,3,8623.181934,10090.425838,2,103,4,4,1.34,3,1,0,0,1,1,62,2,3,1,NA +65184,7,2,2,50,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,1,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,11446.604914,11655.034159,2,92,77,77,NA,4,4,0,0,0,1,27,2,2,5,NA +65185,7,2,1,6,NA,5,7,2,6,80,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9502.15317,9616.069144,2,100,9,9,2.46,4,4,0,2,0,2,36,2,4,1,3 +65186,7,2,2,0,2,4,4,2,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4418.651245,4685.491283,2,95,7,7,1.41,5,5,2,0,0,2,53,1,3,3,NA +65187,7,2,1,11,NA,4,4,1,11,141,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9418.975084,9571.535533,2,93,5,5,0.92,4,4,1,1,0,1,27,2,2,5,NA +65188,7,2,2,59,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,14068.752668,14242.311751,1,93,15,15,5,5,5,1,0,1,1,61,2,4,1,4 +65189,7,2,1,63,NA,2,2,1,NA,NA,2,NA,77,NA,NA,NA,3,77,NA,1,2,2,1,2,2,1,2,2,1,9250.428657,10460.65091,2,92,99,99,NA,1,1,0,0,1,1,63,77,3,77,NA +65190,7,2,2,62,NA,3,3,2,NA,NA,2,NA,2,1,7,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,44636.780791,48652.73082,2,91,6,6,1.78,3,3,0,0,1,2,62,2,3,3,NA +65191,7,2,2,30,NA,5,6,2,NA,NA,2,NA,2,2,2,NA,5,6,2,1,2,2,1,2,2,1,2,2,1,13124.243834,13151.042447,1,93,15,6,2.3,6,1,0,0,0,1,34,2,5,5,NA +65192,7,2,2,52,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,16677.13986,16814.569762,1,97,15,15,5,4,4,0,0,0,1,51,2,5,1,5 +65193,7,2,2,3,NA,4,4,2,3,41,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16749.124902,17181.448234,2,101,4,4,1.16,2,2,1,0,0,2,28,1,4,5,NA +65194,7,2,1,31,NA,5,6,2,NA,NA,2,NA,2,2,2,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,13936.822202,14121.672299,1,93,15,5,1.84,6,1,0,0,0,1,34,2,5,5,NA +65195,7,2,1,43,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,13232.135,13189.930654,2,99,15,15,4.9,7,7,1,4,0,2,53,1,5,1,5 +65196,7,2,2,1,22,3,3,2,NA,23,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,41956.615141,45173.707461,1,91,14,14,2.44,7,7,2,4,0,1,33,1,5,1,5 +65197,7,2,1,6,NA,5,7,1,6,83,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15279.821652,15716.743409,1,102,6,6,1.34,4,4,2,1,0,2,27,1,4,3,NA +65198,7,2,1,32,NA,1,1,2,NA,NA,2,NA,2,2,5,NA,1,1,NA,2,2,2,2,2,2,2,2,2,2,34887.439952,34624.133414,2,94,7,7,1.34,5,5,2,1,0,1,32,2,1,1,NA +65199,7,2,2,51,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,17852.668137,18282.490034,3,91,7,7,1.33,6,6,0,0,2,2,51,2,5,1,5 +65200,7,2,1,10,NA,5,6,2,10,123,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7832.194045,8303.616222,1,96,15,15,5,4,4,0,2,0,2,41,2,5,1,5 +65201,7,2,2,77,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,56666.803206,58405.284869,1,101,15,15,5,3,3,0,0,2,1,79,1,4,1,4 +65202,7,2,1,45,NA,2,2,1,NA,NA,2,NA,2,2,4,NA,1,4,NA,2,2,2,2,2,2,2,2,2,2,52941.648658,52164.811575,2,102,5,5,1.08,3,3,0,0,0,1,55,2,1,5,NA +65203,7,2,2,7,NA,3,3,2,7,88,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,70999.269152,75403.63644,1,93,15,15,5,4,4,0,2,0,1,51,1,3,1,5 +65204,7,2,1,15,NA,4,4,2,15,188,NA,NA,1,1,NA,10,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12195.546462,12314.973739,2,97,6,6,0.92,7,7,1,4,0,2,29,1,3,5,NA +65205,7,2,1,56,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,166897.201244,171848.340208,2,91,7,7,1.61,4,4,0,0,3,1,65,1,3,6,NA +65206,7,2,2,6,NA,5,6,2,6,75,NA,NA,2,1,2,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10029.642884,10710.156898,2,91,14,14,3.69,4,4,1,1,0,1,53,1,4,1,5 +65207,7,2,2,11,NA,2,2,2,11,134,NA,NA,1,1,NA,4,NA,NA,NA,2,1,2,2,2,2,1,2,2,NA,15583.587534,16935.930722,1,93,14,14,3.06,5,5,0,2,0,1,46,2,1,1,4 +65208,7,2,2,5,NA,3,3,1,5,64,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,85197.465687,87881.529962,1,92,15,15,5,4,4,2,0,0,2,46,1,5,1,5 +65209,7,2,2,71,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,NA,28297.225791,31371.640749,2,102,14,14,2.44,7,7,0,2,1,2,71,1,3,3,NA +65210,7,2,2,48,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,1,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,19333.302971,19445.46438,1,99,3,3,0.88,2,2,0,1,0,2,48,1,1,3,NA +65211,7,2,2,2,NA,4,4,2,2,25,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6293.31819,6860.614572,1,96,7,7,1,7,7,2,1,1,2,53,1,4,1,3 +65212,7,2,1,14,NA,5,6,1,14,170,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7291.654281,7756.692286,3,91,9,9,3.24,3,3,0,1,1,1,64,2,2,1,5 +65213,7,2,2,64,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,15369.196003,16553.883322,1,100,15,15,5,2,2,0,0,2,2,64,1,3,1,3 +65214,7,2,2,38,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,74517.751389,77393.175383,2,94,10,10,2.91,4,4,0,2,0,2,38,1,4,1,4 +65215,7,2,1,1,14,3,3,2,NA,15,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,37534.976354,40372.682594,1,99,14,14,4.03,4,4,1,1,0,1,40,2,4,1,5 +65216,7,1,2,1,22,1,1,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,9955.153132,0,2,94,4,4,0.72,4,4,1,1,0,1,30,2,1,1,3 +65217,7,2,2,22,NA,2,2,1,NA,NA,2,NA,2,2,4,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,60461.427433,62051.800421,2,92,2,2,0.4,3,3,0,0,0,1,50,2,4,1,4 +65218,7,2,1,74,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,1,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,9748.579573,13410.055152,3,90,13,3,0.79,3,2,0,0,2,1,74,2,1,1,NA +65219,7,2,1,2,NA,4,4,1,2,33,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6936.347746,7414.543244,1,98,10,10,2.59,5,5,2,1,0,1,45,1,5,1,5 +65220,7,2,1,80,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,1,2,NA,NA,NA,NA,9850.66662,10431.854777,2,98,3,3,1.1,1,1,0,0,1,1,80,1,1,2,NA +65221,7,2,2,2,NA,3,3,1,2,28,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,45222.58045,46647.274385,1,98,15,15,4.56,4,4,2,0,0,2,33,1,4,1,4 +65222,7,2,2,7,NA,1,1,2,7,90,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12958.860039,13685.571339,1,99,15,15,5,3,3,0,1,0,2,34,1,4,1,4 +65223,7,2,1,20,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,25815.880139,26556.735732,2,101,99,99,NA,2,1,0,0,0,1,21,1,4,5,NA +65224,7,1,1,58,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,1,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,16851.334496,0,2,95,3,3,0.95,2,2,0,0,1,2,65,1,2,3,NA +65225,7,2,2,34,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,16411.593279,16969.580129,2,103,15,15,5,2,2,0,0,0,2,39,2,5,5,NA +65226,7,2,2,3,NA,3,3,1,3,39,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,71938.505792,79397.866058,3,91,8,8,1.95,4,4,2,0,0,2,30,1,5,1,4 +65227,7,2,2,30,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,19831.16853,19892.1428,1,103,3,3,0.37,5,5,1,2,0,2,30,1,4,5,NA +65228,7,2,2,44,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,16237.004863,17542.96783,1,90,15,15,5,5,5,0,2,0,1,47,2,5,1,5 +65229,7,2,1,31,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,109181.566304,112638.448741,2,91,14,14,3.93,3,3,0,0,2,1,70,NA,NA,1,NA +65230,7,2,1,43,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,25128.435397,27949.568291,2,94,5,5,1.3,3,3,0,1,0,1,43,1,3,6,NA +65231,7,2,1,31,NA,2,2,1,NA,NA,2,NA,2,2,2,NA,3,1,NA,2,2,2,2,2,2,2,2,2,2,34997.800447,36560.756135,2,96,6,6,1.25,4,4,1,1,0,1,31,2,3,1,3 +65232,7,2,2,0,4,1,1,1,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8775.375504,8590.751882,2,102,8,8,2.24,4,4,1,1,0,1,40,1,3,1,3 +65233,7,2,1,30,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,47932.213152,49254.617856,1,92,14,14,3.9,4,4,2,0,0,2,29,1,4,1,4 +65234,7,2,1,80,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,1,1,NA,1,1,2,1,2,2,NA,NA,NA,NA,26773.686592,29743.160504,2,98,99,99,NA,2,2,0,0,2,2,80,1,3,1,1 +65235,7,2,2,5,NA,2,2,1,5,66,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12541.254112,13845.88109,2,100,14,14,3.36,4,4,1,1,0,1,45,2,5,1,2 +65236,7,2,2,73,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,NA,12980.451176,13849.150613,1,96,7,7,3.58,1,1,0,0,1,2,73,1,2,3,NA +65237,7,2,2,25,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,6,2,1,2,2,1,2,2,1,2,2,1,53574.557692,55073.604958,1,90,4,1,0.27,2,1,0,0,0,2,25,1,5,6,NA +65238,7,2,1,19,NA,1,1,1,19,228,2,NA,2,2,4,15,NA,NA,NA,2,2,2,2,2,2,1,2,2,1,29234.272259,29869.33924,3,92,4,4,0.46,7,7,1,2,0,2,31,2,2,1,1 +65239,7,2,2,60,NA,4,4,2,NA,NA,2,NA,2,2,8,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,15732.436891,16737.04767,1,97,3,3,0.9,1,1,0,0,1,2,60,2,4,2,NA +65240,7,2,1,73,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,1,1,2,1,1,2,1,NA,11066.512629,11628.392246,1,99,9,9,4.08,2,2,0,0,2,1,73,2,5,1,5 +65241,7,2,2,42,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,15147.212851,15611.778104,1,96,6,6,1.34,3,3,1,0,0,2,42,2,4,6,NA +65242,7,2,1,5,NA,1,1,1,5,65,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,1,1,2,1,NA,NA,NA,NA,17865.135763,18076.339981,3,92,6,6,0.96,5,5,2,1,0,2,26,2,1,1,1 +65243,7,2,2,35,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,6,2,1,2,2,1,2,2,1,2,2,1,49102.007191,48391.207475,3,92,10,10,3.77,3,3,0,1,0,2,52,1,4,6,NA +65244,7,2,2,49,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,18490.479848,19120.175119,2,100,4,4,0.91,3,3,0,0,0,2,49,1,2,1,2 +65245,7,1,2,2,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9008.172545,0,1,97,15,15,5,3,3,1,0,0,1,28,1,3,6,NA +65246,7,2,1,3,NA,3,3,1,3,42,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,95119.048777,111454.284969,1,100,6,6,1.78,3,3,1,1,0,2,35,1,5,4,NA +65247,7,2,2,8,NA,4,4,1,8,97,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10221.991799,10600.655937,1,98,6,6,1.36,3,3,0,2,0,1,35,1,5,3,NA +65248,7,2,2,67,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,118611.064701,118209.809508,1,91,14,14,5,2,2,0,0,2,1,68,1,4,1,4 +65249,7,2,2,23,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,53401.089129,55537.639072,2,101,99,2,0.73,3,1,0,0,0,2,22,1,4,5,NA +65250,7,2,1,41,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,29413.309667,30038.439043,1,94,3,3,0.9,1,1,0,0,0,1,41,1,3,5,NA +65251,7,2,2,10,NA,4,4,2,10,129,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9565.802332,9920.158544,1,96,14,14,2.58,6,6,2,2,0,1,40,2,4,1,4 +65252,7,2,2,6,NA,4,4,2,6,80,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9089.153301,9279.567325,1,93,1,1,0,2,2,0,1,0,2,38,1,4,3,NA +65253,7,2,2,3,NA,5,6,2,3,44,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4919.743181,5055.947351,1,97,7,7,1.48,5,5,1,2,0,1,40,2,5,1,4 +65254,7,2,2,2,NA,4,4,1,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5899.406975,6225.79867,2,103,7,7,1.55,5,5,2,2,0,2,31,1,4,3,NA +65255,7,2,1,52,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,24022.668025,24108.898567,1,99,10,10,5,1,1,0,0,0,1,52,1,5,3,NA +65256,7,2,2,36,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,85610.546667,92292.669073,2,91,15,15,5,3,3,1,0,0,1,37,1,5,1,5 +65257,7,2,1,13,NA,3,3,2,13,163,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,30100.326038,35344.542616,1,101,6,6,1.52,3,3,0,1,1,1,62,1,2,1,3 +65258,7,2,2,16,NA,1,1,1,17,204,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,21818.047789,22469.060223,2,102,7,7,2.16,3,3,0,2,0,2,41,1,5,3,NA +65259,7,2,2,5,NA,3,3,2,5,65,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,23388.579221,24855.504015,2,91,7,7,1.29,6,6,2,2,0,1,33,2,3,6,NA +65260,7,2,2,58,NA,5,6,1,NA,NA,2,NA,2,2,5,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,13354.133365,13424.749254,3,92,8,8,0.91,7,7,3,3,1,1,61,NA,NA,1,4 +65261,7,2,2,41,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,30932.175051,34795.188535,2,101,7,7,3.21,1,1,0,0,0,2,41,1,5,5,NA +65262,7,2,1,35,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,4,5,NA,1,2,2,1,2,1,1,2,2,1,20463.181443,21839.784829,1,93,7,7,2.38,2,2,0,0,0,2,46,2,3,5,NA +65263,7,2,2,13,NA,2,2,1,13,165,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,20460.442471,21235.303768,2,102,14,14,2.44,7,7,0,2,1,2,71,1,3,3,NA +65264,7,2,1,40,NA,5,7,2,NA,NA,2,NA,2,2,3,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,26449.318243,30106.409363,1,90,77,77,NA,2,2,0,0,0,1,40,2,2,1,5 +65265,7,2,1,56,NA,1,1,2,NA,NA,2,NA,2,2,4,NA,2,6,NA,2,2,2,1,2,2,NA,NA,NA,NA,24595.31055,24234.412281,1,97,3,3,0.5,5,5,0,2,0,1,56,2,2,6,NA +65266,7,2,2,55,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,1,24870.513993,25871.320138,3,92,7,7,2.45,2,2,0,0,1,2,55,1,1,1,1 +65267,7,2,2,37,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,14553.261149,15099.267285,2,92,15,15,5,3,3,1,0,0,2,37,1,5,1,5 +65268,7,2,2,20,NA,5,6,1,NA,NA,2,NA,2,2,1,NA,4,5,2,1,2,2,1,2,2,1,2,2,3,16929.836231,17652.770039,2,101,12,8,4.82,2,1,0,0,0,2,21,NA,NA,5,NA +65269,7,2,1,24,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,22233.683089,22579.222386,1,102,5,1,0.21,5,4,1,1,0,2,24,1,4,5,NA +65270,7,2,1,24,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,34099.599202,34629.549705,1,94,5,5,1.47,2,2,0,0,0,1,24,1,4,1,4 +65271,7,2,2,27,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,36449.806171,39411.375474,1,91,6,6,1.07,6,6,3,1,0,2,27,1,4,6,NA +65272,7,2,2,1,19,4,4,2,NA,19,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7618.827213,8513.998744,2,97,2,2,0.34,2,2,1,0,0,2,20,1,3,5,NA +65273,7,2,1,5,NA,1,1,1,5,65,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14098.200143,14544.470341,1,102,4,4,0.61,5,5,2,2,0,2,27,2,2,5,NA +65274,7,1,1,25,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,15435.176007,0,2,99,4,4,0.78,4,4,0,2,0,2,45,1,3,5,NA +65275,7,1,1,80,NA,3,3,NA,NA,NA,1,2,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,20611.860643,0,1,99,7,7,3.9,1,1,0,0,1,1,80,1,4,2,NA +65276,7,2,2,11,NA,4,4,1,11,133,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11593.230877,12022.691286,2,96,8,8,1.72,5,5,0,3,0,1,39,1,5,1,4 +65277,7,2,2,2,NA,3,3,2,2,29,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,44626.8774,45213.2896,1,92,14,14,4.59,3,3,1,0,0,1,31,1,4,1,5 +65278,7,2,2,13,NA,1,1,2,13,157,NA,NA,1,1,NA,8,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,18368.872199,20151.001259,2,94,6,6,1.34,4,4,0,2,0,1,37,2,4,1,2 +65279,7,2,2,6,NA,5,7,2,6,78,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,19880.837381,19932.405693,1,95,3,3,0.45,4,4,2,1,0,2,26,1,3,4,NA +65280,7,2,1,62,NA,1,1,1,NA,NA,2,NA,2,1,8,NA,3,3,NA,2,2,2,1,2,2,NA,NA,NA,NA,14488.953694,16384.525762,3,92,1,1,0,6,6,0,3,1,1,62,2,3,3,NA +65281,7,2,2,8,NA,3,3,2,8,105,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,28912.545431,29050.529973,1,98,3,3,0.61,4,4,0,2,0,2,32,1,3,6,NA +65282,7,2,1,2,NA,1,1,1,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,12387.68972,12183.594345,1,94,6,6,1.78,3,3,1,0,0,2,31,2,5,1,1 +65283,7,2,2,31,NA,1,1,1,NA,NA,2,NA,2,2,6,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,29102.738194,28317.485179,2,103,10,10,1.63,7,7,1,4,0,1,31,NA,NA,1,4 +65284,7,2,2,6,NA,5,6,2,6,77,NA,NA,2,2,1,0,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,5795.227223,6217.308223,1,91,14,14,4.32,3,3,0,2,0,2,37,2,5,1,NA +65285,7,2,1,44,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,2,1,NA,1,2,2,1,2,2,1,2,2,2,34153.424332,35777.45113,1,100,8,8,2.17,4,4,1,1,0,2,40,2,2,1,2 +65286,7,2,1,30,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,4,1,NA,1,2,2,1,2,1,1,2,2,1,20228.224986,20656.862173,2,102,15,15,3.82,5,5,0,1,2,1,60,2,2,1,1 +65287,7,2,1,1,15,5,7,1,NA,16,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,26781.430467,29328.277521,1,102,6,6,1.34,4,4,2,1,0,2,27,1,4,3,NA +65288,7,2,2,41,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,5,3,2,1,2,2,1,2,2,1,2,2,1,37512.060155,37707.682357,1,92,14,14,5,2,2,0,1,0,2,41,1,5,3,NA +65289,7,2,2,73,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,17474.843163,17732.021804,1,98,6,6,1.57,3,3,0,0,2,1,66,2,2,1,4 +65290,7,2,2,0,8,4,4,1,NA,10,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4439.36229,4707.453058,2,100,5,5,0.88,5,5,2,1,0,2,30,1,4,6,NA +65291,7,2,1,29,NA,2,2,2,NA,NA,2,NA,2,2,4,NA,3,1,NA,2,2,2,2,2,2,2,2,2,2,35669.2076,37942.468331,2,94,9,9,2.51,4,4,2,0,0,2,34,2,3,1,3 +65292,7,2,1,3,NA,5,6,2,3,39,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7769.861689,8391.242047,1,101,8,8,1.81,5,5,2,0,1,2,37,2,4,1,2 +65293,7,2,2,64,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,1,10038.743429,10812.549167,1,96,6,6,1.83,2,2,0,0,1,2,64,1,3,2,NA +65294,7,2,2,15,NA,4,4,2,16,192,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11133.192774,11654.909373,3,91,2,2,0.25,4,4,0,2,0,2,35,1,3,5,NA +65295,7,2,2,17,NA,1,1,1,17,212,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,18674.868029,19048.995585,2,92,8,8,1.42,7,7,0,4,0,2,37,1,1,6,NA +65296,7,2,1,80,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,38666.703155,42427.769217,2,94,9,9,3.97,2,2,0,0,2,1,80,1,5,1,5 +65297,7,2,1,72,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,3,1,NA,1,2,1,1,2,1,1,2,2,NA,12375.169389,14759.280437,2,92,4,4,1.14,2,2,0,0,2,1,72,2,3,1,3 +65298,7,2,1,49,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,140932.152825,151077.472396,1,97,14,14,3.36,4,4,0,2,0,2,49,1,5,1,5 +65299,7,2,1,29,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,94547.245282,99078.839738,2,94,15,10,5,2,1,0,0,0,1,29,1,4,6,NA +65300,7,2,1,1,16,3,3,2,NA,17,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,50563.666669,55372.144903,1,95,9,9,2.68,4,4,2,0,0,2,27,1,4,1,4 +65301,7,2,2,62,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,10192.188896,10604.379638,1,99,8,8,4.13,1,1,0,0,1,2,62,1,2,3,NA +65302,7,2,1,11,NA,3,3,2,11,134,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,21767.839187,23123.409471,1,101,5,5,1.28,3,3,0,2,0,2,44,1,5,3,NA +65303,7,2,2,19,NA,5,6,2,19,239,2,NA,2,2,2,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,7588.544207,7881.983727,3,91,4,4,0.69,5,5,0,2,0,1,45,2,4,1,1 +65304,7,2,1,43,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,30596.964094,35273.693641,2,102,14,14,5,1,1,0,0,0,1,43,1,4,3,NA +65305,7,2,2,16,NA,5,7,2,16,197,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,6386.337576,6452.948976,1,93,15,15,4.59,4,4,0,2,0,2,45,1,5,1,5 +65306,7,2,2,30,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,30802.731848,31491.045952,1,100,6,6,1.18,5,5,1,2,0,2,30,1,3,1,4 +65307,7,2,1,3,NA,3,3,1,3,40,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,27608.061058,31148.453885,1,94,6,6,1.18,5,5,1,2,0,1,30,1,3,1,3 +65308,7,2,2,54,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,1,6,NA,2,2,2,2,2,2,2,2,1,2,25483.560748,25945.701567,1,94,12,3,1.07,4,1,0,0,1,2,37,NA,NA,6,NA +65309,7,1,1,77,NA,1,1,NA,NA,NA,1,1,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,14200.083364,0,2,98,3,3,1.1,1,1,0,0,1,1,77,1,2,2,NA +65310,7,2,1,40,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,27356.080541,28721.124083,1,101,6,6,1.21,4,4,0,2,0,2,33,1,2,6,NA +65311,7,2,2,7,NA,1,1,1,7,87,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15510.382876,16516.802792,1,100,8,8,2.17,4,4,1,1,0,2,40,2,2,1,2 +65312,7,2,1,2,NA,5,7,1,2,30,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,26781.430467,29328.277521,1,102,6,6,1.34,4,4,2,1,0,2,27,1,4,3,NA +65313,7,2,1,3,NA,4,4,2,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6946.177172,7233.19413,2,90,4,4,0.57,5,5,1,2,0,2,33,2,2,77,NA +65314,7,2,2,16,NA,4,4,1,17,204,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12208.965913,12707.508076,2,100,6,6,0.99,5,5,0,3,0,2,40,1,3,1,3 +65315,7,2,1,7,NA,2,2,2,7,85,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12049.155217,12263.670489,2,90,14,14,3.58,4,4,1,1,0,1,37,1,3,1,4 +65316,7,2,1,54,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,26127.59163,27234.881102,1,100,15,15,5,4,4,0,0,0,1,54,1,5,1,5 +65317,7,2,2,26,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,15267.012422,14516.051827,1,99,6,6,0.6,7,7,2,1,1,2,69,1,3,2,NA +65318,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,51433.469947,56330.524019,1,98,5,5,1.97,1,1,0,0,1,2,80,1,4,2,NA +65319,7,2,1,73,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,11849.199361,13959.374637,1,100,4,4,1.16,2,2,0,0,2,1,73,1,3,1,3 +65320,7,2,1,39,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,109181.566304,114466.270601,2,91,15,3,0.98,7,1,0,0,1,1,49,NA,NA,5,NA +65321,7,2,1,7,NA,2,2,1,7,90,NA,NA,1,1,NA,2,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,14820.807433,15173.085782,2,102,6,6,1.12,4,4,1,1,0,1,38,2,2,1,3 +65322,7,2,2,23,NA,2,2,2,NA,NA,2,NA,2,1,4,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,30253.427014,31766.413225,2,90,6,6,1.35,3,3,1,0,0,1,31,1,3,1,4 +65323,7,2,1,0,11,2,2,2,NA,12,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6266.985765,6267.101277,1,93,15,15,5,3,3,1,0,0,2,32,2,5,1,5 +65324,7,2,2,0,3,1,1,2,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7011.218293,6988.118839,2,97,8,8,2.01,4,4,2,0,0,2,24,1,4,1,1 +65325,7,2,2,73,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,72443.10981,74665.593008,2,102,7,7,2.72,2,2,0,0,1,2,73,1,4,2,NA +65326,7,2,2,44,NA,5,6,1,NA,NA,2,NA,2,2,6,NA,1,1,2,1,2,2,1,2,2,NA,NA,NA,NA,12544.244874,13448.569073,1,102,5,5,0.92,5,5,1,2,0,2,44,2,1,1,2 +65327,7,2,1,38,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,18544.003944,22007.065507,2,97,NA,99,NA,7,6,2,1,1,2,56,1,3,5,NA +65328,7,2,1,63,NA,2,2,2,NA,NA,2,NA,2,2,7,NA,4,5,NA,2,2,2,2,2,2,2,2,2,2,10903.483462,11078.143343,1,93,2,2,0.43,2,2,0,0,2,2,80,2,1,2,NA +65329,7,2,1,21,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,43287.255521,44006.168052,1,90,6,6,1.57,3,3,0,0,0,1,50,2,2,1,2 +65330,7,2,2,0,9,3,3,2,NA,10,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8814.114917,8994.318513,1,95,6,6,0.81,6,6,2,2,0,1,30,1,3,1,4 +65331,7,2,2,54,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,16741.034883,16282.872546,2,95,2,2,0.81,1,1,0,0,0,2,54,1,4,5,NA +65332,7,2,1,7,NA,1,1,1,7,95,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14880.007592,15211.324369,3,92,2,2,0.47,3,3,1,1,0,2,33,1,4,5,NA +65333,7,2,2,2,NA,5,6,1,2,28,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,1,NA,NA,NA,NA,7029.864692,7462.832472,3,92,77,77,NA,7,7,2,4,1,1,62,NA,NA,1,NA +65334,7,2,2,60,NA,2,2,2,NA,NA,2,NA,2,1,8,NA,2,3,NA,2,2,2,2,2,2,2,2,2,2,13676.984152,18290.186018,2,91,2,2,0.75,1,1,0,0,1,2,60,2,2,3,NA +65335,7,2,1,55,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,14288.99518,14503.461604,1,102,9,9,2.39,5,5,0,1,1,1,55,2,5,1,5 +65336,7,2,2,20,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,124037.944076,128061.498173,1,100,15,15,5,4,4,0,1,0,1,50,1,4,1,4 +65337,7,2,1,63,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,28478.57859,28745.66908,1,98,3,3,1.25,1,1,0,0,1,1,63,1,4,5,NA +65338,7,2,2,22,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,16239.242782,17454.103497,2,101,99,1,0.22,3,1,0,0,0,2,22,1,4,5,NA +65339,7,2,1,60,NA,2,2,1,NA,NA,2,NA,2,2,7,NA,4,6,NA,2,2,2,1,2,2,2,2,2,2,9911.173561,10104.337319,2,92,15,10,5,2,1,0,0,1,2,54,2,5,3,NA +65340,7,2,2,25,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,71351.478679,72494.161504,2,97,15,15,4.97,5,5,1,0,0,1,48,1,4,1,3 +65341,7,2,1,42,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,116464.874823,118336.754883,2,94,14,14,5,3,3,0,0,0,1,42,1,5,1,5 +65342,7,2,2,2,NA,4,4,2,2,26,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6306.491784,7047.470907,2,90,5,5,1.08,3,3,1,1,0,2,23,1,2,5,NA +65343,7,2,2,4,NA,3,3,2,4,54,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,40290.055403,42817.035801,1,99,15,15,5,5,5,3,0,0,2,34,1,5,1,5 +65344,7,2,1,60,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,9745.303498,10208.81789,2,98,6,6,0.63,7,7,2,2,1,1,60,1,3,1,2 +65345,7,2,2,1,13,4,4,2,NA,13,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7734.994032,8078.467013,2,95,1,1,0,4,4,2,1,0,2,27,1,4,5,NA +65346,7,2,2,49,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,18490.479848,18110.536811,2,100,14,14,3.06,5,5,1,0,0,1,50,1,5,1,5 +65347,7,2,2,30,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,17983.231494,18657.922524,3,91,10,10,3.67,3,3,1,0,0,2,30,2,4,1,4 +65348,7,2,2,45,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,99120.116925,101722.54619,2,98,15,15,5,3,3,0,1,0,1,56,1,5,1,5 +65349,7,2,1,19,NA,2,2,1,19,231,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,2,2,2,1,2,2,1,17555.907575,18699.509115,2,93,3,3,0.52,5,5,0,2,0,1,41,2,4,1,4 +65350,7,2,1,6,NA,4,4,1,6,77,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11321.293503,11517.688596,1,98,6,6,1.36,3,3,0,2,0,1,35,1,5,3,NA +65351,7,2,1,36,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,21171.267805,24852.610883,1,97,5,5,1.79,1,1,0,0,0,1,36,1,3,3,NA +65352,7,2,1,53,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,3,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,11240.290931,11199.684593,2,92,12,77,NA,7,2,0,0,2,1,53,2,3,1,3 +65353,7,2,2,42,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,18490.479848,18110.536811,2,100,15,15,4.97,5,5,0,2,1,2,42,1,5,1,5 +65354,7,2,1,13,NA,3,3,2,14,169,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,127790.772987,128099.355719,1,97,15,15,5,4,4,0,2,0,1,49,1,5,1,5 +65355,7,2,1,37,NA,4,4,2,NA,NA,2,NA,2,1,6,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,19799.565045,19517.338151,1,90,5,5,0.74,5,5,0,2,0,2,18,1,4,NA,NA +65356,7,2,1,8,NA,3,3,1,8,103,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,24713.905595,26080.214484,1,98,5,5,0.74,5,5,0,3,0,1,35,1,2,6,NA +65357,7,2,2,7,NA,4,4,1,7,94,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8504.389189,8822.229593,2,93,5,5,0.74,5,5,1,2,0,2,28,1,2,6,NA +65358,7,2,2,45,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,115926.402585,116948.004168,1,91,10,10,3.8,3,3,0,0,0,1,45,NA,NA,1,4 +65359,7,2,1,14,NA,2,2,2,14,175,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,25622.388537,25620.13505,1,97,15,15,4.52,6,6,0,4,0,2,41,1,5,1,5 +65360,7,2,2,17,NA,3,3,2,17,205,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,NA,NA,NA,1,2,2,1,111142.989658,114400.666347,1,95,NA,NA,NA,5,5,0,2,0,2,37,1,3,1,NA +65361,7,2,1,11,NA,4,4,1,11,138,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8447.917731,9106.89532,1,102,15,15,5,3,3,0,1,0,1,41,1,5,1,5 +65362,7,2,2,11,NA,2,2,2,11,142,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,15148.721588,15796.67129,2,91,2,2,0.22,4,4,0,3,0,2,45,2,5,4,NA +65363,7,2,1,4,NA,1,1,1,4,56,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16775.083123,16797.750213,2,98,14,14,3.91,4,4,1,1,0,1,36,2,3,1,5 +65364,7,2,2,8,NA,1,1,2,8,98,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,9872.244853,10294.506103,2,90,6,6,1.15,5,5,0,2,0,2,47,2,1,1,5 +65365,7,2,2,17,NA,4,4,1,17,205,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11078.202838,10933.134393,1,102,12,12,NA,7,7,3,2,0,2,52,1,4,5,NA +65366,7,2,1,60,NA,2,2,1,NA,NA,2,NA,2,2,4,NA,3,1,NA,2,2,2,1,2,2,2,2,2,2,6449.12882,6755.867756,2,93,8,8,2.97,2,2,0,0,1,1,60,2,3,1,3 +65367,7,2,1,10,NA,2,2,2,10,127,NA,NA,2,2,2,3,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,16281.509392,17100.217351,2,91,4,4,0.43,7,7,0,1,1,1,41,2,1,4,NA +65368,7,2,1,23,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,27681.749998,29590.732776,2,98,3,3,0.54,3,3,1,0,0,1,23,1,3,1,2 +65369,7,2,1,3,NA,3,3,2,3,41,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,71085.311148,83293.12191,2,94,14,14,3.36,4,4,2,0,0,1,31,1,3,1,5 +65370,7,2,2,28,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,112992.533921,121615.449738,1,94,6,6,1.57,3,3,0,1,0,2,28,1,4,1,4 +65371,7,2,1,10,NA,4,4,1,10,121,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12552.995979,12770.757918,2,96,4,4,0.65,5,5,0,3,0,1,30,1,4,1,2 +65372,7,2,2,31,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,4,3,1,2,2,1,2,2,1,2,2,1,27367.658704,37250.756368,1,91,6,6,2.04,2,2,1,0,0,2,31,1,5,4,NA +65373,7,2,2,45,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,154825.466557,160454.355913,1,91,15,15,5,4,4,0,1,0,1,45,1,5,1,5 +65374,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,32415.779658,36870.322177,2,91,4,4,1.02,2,2,0,0,2,1,80,1,4,1,2 +65375,7,2,2,52,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,150482.742079,154420.406935,2,98,15,15,5,2,2,0,0,0,2,52,1,3,1,4 +65376,7,1,1,2,24,1,1,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12493.910388,0,2,98,5,5,1.63,2,2,1,0,0,2,31,1,1,3,NA +65377,7,2,1,19,NA,4,4,1,19,232,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13276.485807,13770.209619,1,96,4,4,1.29,2,2,0,0,0,2,48,1,4,3,NA +65378,7,2,2,3,NA,5,6,2,3,41,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4938.043177,5022.237557,1,91,15,15,5,4,4,1,1,0,1,43,2,5,1,5 +65379,7,2,2,12,NA,3,3,1,12,155,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,39616.634313,40360.331753,2,101,3,3,0.6,3,3,0,2,0,1,39,1,4,4,NA +65380,7,2,2,17,NA,5,6,1,17,205,2,NA,2,2,1,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,9884.956101,9995.989819,1,94,99,1,0.32,6,1,0,3,0,2,45,NA,NA,6,NA +65381,7,2,2,9,NA,4,4,1,9,114,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9453.111053,10094.338553,1,100,6,6,1.39,4,4,0,3,0,2,29,1,4,5,NA +65382,7,1,1,4,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6946.177172,0,2,90,6,6,1.03,6,6,3,1,0,1,45,2,2,1,2 +65383,7,2,1,15,NA,1,1,2,16,193,NA,NA,2,2,2,9,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,20398.562455,20202.582308,2,94,77,77,NA,3,3,0,1,0,2,42,2,2,6,NA +65384,7,2,2,72,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,3,5,NA,1,2,2,1,2,2,1,2,2,NA,20267.042371,20898.557176,2,102,7,7,1.68,5,5,0,0,3,1,70,2,4,1,4 +65385,7,2,2,12,NA,5,6,2,12,149,NA,NA,2,1,99,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11975.458482,12414.350614,1,97,14,14,2.29,7,7,1,2,2,1,40,2,1,1,1 +65386,7,2,1,6,NA,1,1,1,6,83,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,19735.224235,20204.314213,2,102,8,8,2.24,4,4,1,1,0,1,35,2,3,1,1 +65387,7,1,2,34,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,4,3,3,1,2,2,1,2,2,NA,NA,NA,NA,71034.153987,0,1,98,7,7,1,7,7,2,2,0,2,34,1,4,3,NA +65388,7,2,1,33,NA,4,4,2,NA,NA,2,NA,2,1,3,NA,5,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,23454.081246,24179.640416,1,91,99,99,NA,3,3,1,0,0,1,33,2,5,5,NA +65389,7,2,1,32,NA,5,6,2,NA,NA,2,NA,2,2,4,NA,2,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,13593.59406,16516.502952,2,90,77,77,NA,4,3,1,0,0,2,30,2,2,5,NA +65390,7,2,2,2,NA,5,6,1,3,38,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6796.893869,7396.552454,2,93,15,15,5,3,3,1,0,0,1,41,2,5,1,5 +65391,7,2,1,51,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,3,1,NA,1,2,1,1,2,1,1,2,1,3,11389.795225,13662.741278,2,92,8,8,1.91,5,5,0,2,1,2,47,2,1,1,3 +65392,7,2,2,40,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,17635.020067,18381.689068,2,97,6,6,1.02,6,6,1,2,0,1,37,1,3,1,3 +65393,7,2,1,78,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,15844.527135,16445.651972,1,101,4,4,1.22,2,2,0,0,2,2,77,1,4,1,3 +65394,7,2,2,71,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,28175.708676,28476.609384,1,91,4,4,1.7,1,1,0,0,1,2,71,1,4,2,NA +65395,7,2,1,77,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,NA,14537.797299,15440.503889,3,91,2,2,0.83,1,1,0,0,1,1,77,1,5,5,NA +65396,7,2,1,54,NA,5,6,1,NA,NA,2,NA,2,7,4,NA,5,3,NA,1,2,1,1,2,1,1,2,1,NA,12983.367248,13800.313434,2,101,77,77,NA,4,1,0,0,0,1,39,NA,NA,5,NA +65397,7,1,1,65,NA,5,6,NA,NA,NA,2,NA,2,1,4,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,12579.986433,0,1,95,3,3,0.43,4,4,0,1,2,1,65,2,5,1,3 +65398,7,2,2,80,NA,5,6,1,NA,NA,2,NA,2,1,9,NA,4,2,NA,1,2,2,1,2,2,1,1,2,NA,18693.365067,19341.691824,1,92,12,12,NA,1,1,0,0,1,2,80,2,4,2,NA +65399,7,2,1,59,NA,4,4,2,NA,NA,2,NA,2,1,7,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,18753.573091,18839.996658,2,99,15,15,4.34,4,4,0,0,0,1,59,2,4,1,5 +65400,7,2,1,16,NA,1,1,1,16,197,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,22768.423624,22886.980387,3,92,7,7,1.41,5,5,1,2,0,1,40,1,3,1,4 +65401,7,2,1,55,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,31291.360507,35666.138476,2,91,4,4,1.4,1,1,0,0,0,1,55,1,4,5,NA +65402,7,2,1,33,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,99283.360764,105284.943086,1,94,15,15,5,4,3,0,0,1,1,33,1,2,5,NA +65403,7,2,1,52,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,4,NA,1,2,2,1,2,2,1,2,2,1,31291.360507,35666.138476,2,91,3,3,1.16,1,1,0,0,0,1,52,1,1,4,NA +65404,7,2,2,27,NA,5,6,1,NA,NA,2,NA,2,2,1,NA,5,5,2,1,2,2,1,2,2,1,2,2,3,16929.836231,18593.694637,2,101,8,6,2.85,2,1,0,0,0,2,27,2,5,5,NA +65405,7,2,1,17,NA,1,1,1,17,211,2,NA,1,1,NA,12,NA,NA,NA,2,2,2,1,2,2,1,2,2,1,18635.323223,19040.145288,1,103,6,6,1.57,3,3,0,1,0,2,50,2,3,4,NA +65406,7,2,1,20,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,104488.914565,106745.836574,1,98,3,1,0.22,4,1,0,0,0,1,20,1,4,5,NA +65407,7,2,1,46,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,18790.641284,22550.069226,2,100,6,6,0.99,5,5,0,3,0,2,40,1,3,1,3 +65408,7,2,2,19,NA,2,2,2,19,233,2,NA,2,2,4,10,NA,NA,NA,1,2,2,2,2,2,1,2,2,1,12680.621719,14355.413798,2,90,3,3,0.46,5,5,0,2,2,1,75,2,1,1,2 +65409,7,2,1,5,NA,4,4,2,5,66,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7701.757497,8492.447039,2,90,2,2,0.38,4,4,1,2,0,2,32,1,4,5,NA +65410,7,2,2,71,NA,5,6,1,NA,NA,2,NA,2,2,3,NA,5,2,NA,1,2,1,1,2,2,1,2,1,NA,13838.805939,14318.765975,1,103,15,15,3.7,5,5,0,2,1,1,55,1,5,1,5 +65411,7,2,2,16,NA,5,6,1,17,204,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,8391.252153,8615.174176,1,92,8,8,2.3,4,4,0,1,0,2,41,NA,NA,1,3 +65412,7,2,1,41,NA,5,6,1,NA,NA,2,NA,2,1,3,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,18898.73153,19305.900504,1,100,8,8,2.62,3,3,0,1,0,1,41,2,5,1,5 +65413,7,2,2,1,17,2,2,2,NA,18,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8214.128831,8731.974448,1,99,8,8,1.91,5,5,2,0,1,2,38,2,4,1,4 +65414,7,2,2,6,NA,5,6,1,6,81,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8290.163782,8692.019106,1,92,15,15,5,4,4,0,2,0,1,55,1,5,1,5 +65415,7,2,2,1,22,3,3,1,NA,22,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14349.194039,14956.025029,1,103,6,6,1.11,5,5,1,1,1,1,29,1,3,1,3 +65416,7,2,1,23,NA,5,6,1,NA,NA,2,NA,2,2,1,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,18088.213601,18580.673153,1,98,12,5,2.15,2,1,0,0,0,1,23,2,5,5,NA +65417,7,2,2,75,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,1,4,NA,1,2,2,1,2,2,1,2,2,NA,29145.675285,31446.34406,3,92,10,10,2.82,4,4,0,1,1,1,36,1,3,1,5 +65418,7,2,2,7,NA,4,4,2,7,86,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7282.523598,7776.514874,2,99,6,6,1.11,5,5,0,4,0,2,34,1,4,5,NA +65419,7,2,1,19,NA,3,3,1,19,232,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,33505.877646,33253.482687,2,101,5,3,1.1,2,1,0,0,0,1,19,1,4,NA,NA +65420,7,2,2,24,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,NA,NA,NA,NA,22306.465066,21209.244743,2,98,5,5,0.59,7,7,3,0,0,2,50,1,5,4,NA +65421,7,2,2,70,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,27103.875166,29389.100868,1,95,4,4,0.65,4,4,0,0,1,2,70,1,1,2,NA +65422,7,2,1,7,NA,4,4,1,7,94,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9535.948,10279.797103,2,93,4,4,0.56,5,5,2,1,0,1,27,1,2,6,NA +65423,7,2,1,50,NA,1,1,2,NA,NA,2,NA,2,2,7,NA,1,4,NA,1,2,2,1,2,2,1,2,2,1,21506.056514,21429.79108,2,95,6,6,2.24,1,1,0,0,0,1,50,2,1,4,NA +65424,7,2,1,2,NA,5,6,1,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8821.037035,9893.758146,1,102,15,15,4.59,4,4,1,1,0,1,35,1,5,1,5 +65425,7,2,2,2,NA,5,7,2,2,35,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,21940.920626,22868.807624,1,95,6,6,1.15,5,5,2,1,0,1,29,1,4,6,NA +65426,7,2,2,4,NA,3,3,2,4,58,NA,NA,2,2,2,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,40064.649797,41758.993816,1,93,10,10,2.48,5,5,2,1,0,1,40,2,5,1,5 +65427,7,2,2,64,NA,3,3,2,NA,NA,2,NA,2,1,7,NA,1,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,36910.075958,37362.049791,2,97,2,2,0.38,4,4,0,2,2,2,64,2,1,1,NA +65428,7,2,2,8,NA,5,6,1,8,97,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9007.62445,9504.796896,2,102,15,15,3.92,5,5,1,2,0,1,34,2,5,1,5 +65429,7,2,1,17,NA,2,2,2,17,213,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,16033.31661,16386.200415,2,90,5,5,0.8,5,5,0,3,0,2,40,2,1,5,NA +65430,7,2,2,34,NA,2,2,2,NA,NA,2,NA,2,2,4,NA,3,1,2,2,2,2,2,2,2,2,2,2,2,35353.005268,36099.35979,2,94,9,9,2.51,4,4,2,0,0,2,34,2,3,1,3 +65431,7,2,1,73,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,4,4,NA,1,2,2,1,2,2,1,2,2,NA,8497.912951,8664.367847,2,100,4,4,1.47,1,1,0,0,1,1,73,1,4,4,NA +65432,7,1,2,70,NA,4,4,NA,NA,NA,2,NA,2,2,6,NA,4,2,NA,1,2,1,1,2,1,NA,NA,NA,NA,12344.929687,0,1,93,2,2,0.78,1,1,0,0,1,2,70,2,4,2,NA +65433,7,2,2,60,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,34073.955911,34748.968506,2,92,14,14,4.03,4,4,1,1,1,2,30,1,5,4,NA +65434,7,2,2,34,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,5,1,2,1,2,2,1,2,2,1,2,2,3,15494.204758,16562.601332,2,95,15,15,5,3,3,0,1,0,2,34,2,5,1,NA +65435,7,2,2,4,NA,4,4,1,4,54,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8340.858072,8802.325948,2,103,7,7,1.55,5,5,2,2,0,2,31,1,4,3,NA +65436,7,2,1,28,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,15196.92397,16091.373745,2,101,7,3,1.1,3,1,0,0,0,1,21,2,4,5,NA +65437,7,1,1,73,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,14077.240235,0,1,97,5,5,1.84,1,1,0,0,1,1,73,1,4,2,NA +65438,7,2,2,3,NA,4,4,2,3,47,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8833.042831,9629.276723,1,99,10,10,2.07,7,7,2,3,1,2,35,1,5,4,NA +65439,7,2,2,15,NA,2,2,2,15,180,NA,NA,2,1,3,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,16189.692833,16766.382859,1,93,15,15,2.96,7,7,0,1,1,2,18,1,2,NA,NA +65440,7,2,1,61,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,7323.703412,7380.991723,2,100,8,8,2.67,3,3,0,0,1,1,61,1,3,1,4 +65441,7,2,2,10,NA,3,3,1,10,121,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,22308.590534,22137.463018,1,95,7,2,0.35,5,4,1,2,0,1,26,1,4,6,NA +65442,7,2,1,2,NA,4,4,2,2,33,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5942.817425,6188.375425,2,97,13,13,NA,6,6,2,2,0,2,24,1,2,6,NA +65443,7,2,2,37,NA,5,6,2,NA,NA,2,NA,2,2,1,NA,5,1,2,1,2,1,1,2,1,1,2,1,3,17978.142628,18308.053591,1,91,14,14,4.32,3,3,0,2,0,2,37,2,5,1,NA +65444,7,2,1,4,NA,1,1,1,4,56,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12870.245769,13452.024092,1,102,13,13,NA,7,7,3,1,2,2,62,2,1,1,2 +65445,7,2,1,1,22,2,2,1,NA,24,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,8742.6471,9019.39043,2,100,99,99,NA,6,6,1,1,2,1,37,2,3,1,3 +65446,7,2,1,65,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,8168.47072,10568.054811,2,90,6,6,1.73,2,2,0,0,2,2,69,1,2,1,2 +65447,7,2,1,44,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,18841.134943,20530.600583,2,95,14,14,5,2,2,0,0,0,1,44,1,3,1,4 +65448,7,2,2,64,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,10346.035773,10764.448363,1,99,13,13,NA,3,3,0,0,2,1,67,1,2,1,2 +65449,7,2,2,2,NA,4,4,2,2,35,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7630.869112,8210.900286,2,95,6,6,0.97,6,6,2,2,0,1,37,1,3,1,4 +65450,7,2,2,49,NA,1,1,1,NA,NA,2,NA,2,2,3,NA,2,6,NA,2,2,2,2,2,2,2,2,2,2,34954.173075,37266.073044,2,98,6,6,1.21,4,4,1,0,0,2,49,2,2,6,NA +65451,7,2,2,33,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,87322.7576,94138.522454,2,91,15,15,4.2,6,6,2,0,2,1,63,1,1,1,3 +65452,7,2,2,16,NA,4,4,2,16,203,NA,NA,2,2,3,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,10694.834447,10900.381844,1,90,4,4,0.58,6,6,0,3,0,2,21,2,5,5,NA +65453,7,2,2,67,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,1,1,NA,1,2,1,1,2,2,NA,NA,NA,NA,12823.794396,13219.948623,2,100,4,4,0.44,7,7,1,2,2,1,71,2,1,1,1 +65454,7,2,2,36,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,5,3,2,1,2,2,1,2,2,1,2,2,1,11329.574648,11407.369464,1,99,10,10,4.76,2,2,1,0,0,2,36,2,5,3,NA +65455,7,2,2,14,NA,3,3,2,14,175,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,101168.631125,108085.531312,1,99,6,6,1.52,4,4,0,2,0,2,43,1,3,5,NA +65456,7,2,2,12,NA,1,1,2,13,156,NA,NA,2,2,3,7,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,16594.391299,17940.930507,3,91,6,6,0.89,7,7,1,1,0,1,59,2,1,1,1 +65457,7,2,1,25,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,13367.406737,13987.969236,1,92,15,15,4.44,5,5,0,0,1,1,65,NA,NA,1,5 +65458,7,2,1,63,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,152458.779794,153888.636628,2,94,15,15,5,2,2,0,0,2,1,63,1,5,1,5 +65459,7,2,2,2,NA,4,4,2,2,29,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7348.24433,7537.914984,2,95,1,1,0.26,2,2,1,0,0,2,20,1,2,77,NA +65460,7,2,2,64,NA,2,2,1,NA,NA,2,NA,2,1,7,NA,2,2,NA,2,2,2,1,2,2,1,2,2,1,7608.893707,8232.851326,2,100,5,5,2.11,1,1,0,0,1,2,64,2,2,2,NA +65461,7,2,1,50,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,23775.734331,24432.76962,2,96,5,5,1.08,3,3,0,0,0,1,50,1,3,1,4 +65462,7,2,2,49,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,149120.841984,149985.960772,1,98,9,9,5,1,1,0,0,0,2,49,1,5,3,NA +65463,7,2,2,6,NA,4,4,2,6,75,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7814.742747,8587.431439,2,95,7,7,1.55,5,5,0,3,0,1,30,1,4,1,4 +65464,7,2,2,29,NA,4,4,2,NA,NA,2,NA,2,1,6,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,18601.70604,17686.717051,1,90,14,14,2.96,5,5,1,2,0,1,31,1,5,1,4 +65465,7,2,2,7,NA,5,6,1,7,89,NA,NA,2,1,3,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11141.059365,11755.98595,1,98,10,10,1.89,7,7,3,2,0,1,50,1,5,1,5 +65466,7,2,1,7,NA,4,4,1,7,94,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12221.817539,12310.445459,2,100,10,10,2.75,5,5,1,1,1,1,27,1,3,1,5 +65467,7,2,1,0,6,5,6,1,NA,7,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9148.090461,9086.623516,1,92,6,6,1.47,3,3,1,0,0,2,32,2,3,1,3 +65468,7,2,1,7,NA,4,4,2,7,85,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8655.162127,8808.105516,2,95,4,4,0.65,4,4,1,2,0,2,27,1,3,5,NA +65469,7,2,1,58,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,174520.785302,180467.973037,1,95,77,77,NA,3,3,0,0,2,1,80,NA,NA,1,NA +65470,7,2,1,4,NA,1,1,1,4,52,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,14321.363328,13945.949794,2,96,77,77,NA,7,7,3,2,0,2,33,2,2,6,NA +65471,7,1,2,80,NA,5,6,NA,NA,NA,2,NA,2,2,7,NA,5,2,NA,1,1,1,1,2,1,NA,NA,NA,NA,10831.995402,0,3,90,4,4,0.92,3,3,0,0,1,2,56,2,2,1,2 +65472,7,2,1,3,NA,2,2,1,3,38,NA,NA,2,2,2,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,13504.027725,14468.59111,2,93,7,7,1.52,4,4,1,1,0,1,44,2,4,1,NA +65473,7,2,2,60,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,1,8308.628726,9015.10987,2,95,2,2,0.81,1,1,0,0,1,2,60,1,2,2,NA +65474,7,2,2,63,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,10644.199654,11088.440242,2,98,7,7,2.72,2,2,0,0,2,1,63,1,4,1,4 +65475,7,2,2,44,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,15520.204559,18173.553405,1,96,15,15,5,6,6,1,1,1,2,44,1,3,1,3 +65476,7,2,2,32,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,38151.592121,38761.146216,1,101,1,1,0.21,3,3,0,2,0,2,32,1,4,5,NA +65477,7,2,2,50,NA,2,2,2,NA,NA,2,NA,2,1,7,NA,3,3,NA,1,2,2,1,2,2,1,2,2,2,26609.95229,27262.621072,1,93,15,15,2.96,7,7,0,1,1,2,18,1,2,NA,NA +65478,7,2,2,61,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,9680.216878,10112.428208,1,96,10,10,5,1,1,0,0,1,2,61,1,4,2,NA +65479,7,2,1,51,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,21283.272729,21364.140181,1,100,15,15,3.7,5,5,0,3,0,1,51,1,5,1,5 +65480,7,2,1,10,NA,4,4,2,10,121,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8988.052978,9133.633722,2,95,8,8,1.85,5,5,1,2,0,1,55,1,2,1,3 +65481,7,2,2,62,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,1,12782.405209,13767.697696,1,100,2,2,0.54,1,1,0,0,1,2,62,1,3,2,NA +65482,7,1,1,78,NA,3,3,NA,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,81678.388584,0,1,92,9,9,3.97,2,2,0,0,2,2,67,1,3,1,5 +65483,7,1,2,52,NA,3,3,NA,NA,NA,2,NA,2,1,8,NA,5,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,119276.206757,0,1,103,15,15,5,2,2,0,1,0,2,52,2,5,3,NA +65484,7,2,1,1,14,5,7,2,NA,15,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6328.720733,6765.026101,1,91,15,15,4.01,5,5,1,2,0,2,34,1,5,1,5 +65485,7,2,1,42,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,30407.489838,32596.441724,1,97,6,6,1.03,6,6,2,2,0,2,38,1,5,1,4 +65486,7,2,2,66,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,10346.035773,10598.2543,1,99,7,6,1.84,3,2,0,0,2,1,70,1,2,1,4 +65487,7,2,2,1,18,5,6,2,NA,18,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8173.816615,8165.183174,1,97,14,14,4.45,3,3,1,0,0,2,35,2,5,1,5 +65488,7,2,1,38,NA,3,3,2,NA,NA,2,NA,2,1,3,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,15425.274863,16733.462521,1,90,7,7,2.1,3,3,1,0,0,2,40,2,5,1,4 +65489,7,2,1,18,NA,4,4,2,18,216,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,10558.572325,11042.564542,2,99,4,4,0.41,7,7,0,2,0,2,36,1,3,5,NA +65490,7,2,2,20,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,1,1,2,2,1,2,2,NA,NA,NA,NA,22225.098465,28674.927734,2,97,1,1,0.27,2,2,1,0,0,2,20,1,2,5,NA +65491,7,2,2,25,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,NA,NA,NA,NA,24654.107413,23891.769846,1,100,5,5,0.85,5,5,0,2,0,2,54,1,2,2,NA +65492,7,2,2,65,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,1,1,NA,1,2,1,1,2,1,1,2,1,3,11342.714991,11512.583626,1,99,6,6,1.07,6,6,2,1,2,1,44,2,5,4,NA +65493,7,2,1,9,NA,5,7,2,9,109,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9720.482616,10484.39038,2,91,15,15,3.7,5,5,1,2,0,1,50,NA,NA,1,5 +65494,7,2,1,3,NA,3,3,2,3,39,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,88790.489317,95503.197037,2,91,15,15,5,3,3,1,0,0,1,40,1,4,6,NA +65495,7,2,2,5,NA,1,1,1,5,67,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11859.546176,12772.78418,1,102,13,13,NA,7,7,3,1,2,2,62,2,1,1,2 +65496,7,2,1,5,NA,1,1,1,5,64,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16613.593777,17139.487274,1,92,14,14,3.15,5,5,1,2,0,1,34,1,4,1,4 +65497,7,2,1,42,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,116464.874823,129540.216925,2,94,3,3,0.54,4,4,0,1,0,2,48,1,3,1,3 +65498,7,2,2,39,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,3,4,2,1,2,2,1,2,2,1,2,2,1,16369.013285,16419.342576,3,91,5,5,0.65,7,7,0,4,0,2,39,1,3,4,NA +65499,7,2,1,19,NA,3,3,2,19,231,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,19277.921327,19518.221274,2,97,7,7,1.89,3,3,0,0,0,1,50,1,2,1,2 +65500,7,2,1,46,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,17787.524589,17931.023329,2,100,8,8,4.82,1,1,0,0,0,1,46,1,3,3,NA +65501,7,2,2,24,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,53634.754806,54437.113731,1,98,5,1,0,3,1,0,0,0,1,32,1,5,5,NA +65502,7,2,1,1,16,4,4,1,NA,17,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9438.902193,9727.203655,2,102,4,4,0.72,4,4,2,0,0,1,48,1,3,1,3 +65503,7,2,2,44,NA,1,1,1,NA,NA,2,NA,2,2,5,NA,2,1,2,2,2,2,2,2,2,2,2,2,2,33767.584626,34595.8104,2,102,6,4,1.02,6,2,0,4,0,2,43,2,1,5,NA +65504,7,2,1,7,NA,1,1,1,7,86,NA,NA,2,2,2,0,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,13870.762641,14200.45921,2,102,7,7,1.33,6,6,1,3,0,1,34,2,2,1,1 +65505,7,2,1,55,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,17839.845235,18404.710221,3,92,15,15,5,3,3,0,1,0,1,55,2,5,1,4 +65506,7,2,1,50,NA,1,1,1,NA,NA,2,NA,99,NA,NA,NA,2,5,NA,2,2,2,1,2,2,1,2,2,2,30839.213846,30386.695922,1,95,4,4,0.68,5,5,0,1,0,2,38,2,3,4,NA +65507,7,2,2,13,NA,2,2,2,13,158,NA,NA,2,1,3,5,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,15442.648697,16179.397194,3,90,4,4,0.63,5,5,0,3,0,1,45,2,4,1,4 +65508,7,2,1,31,NA,2,2,2,NA,NA,1,1,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,32770.630289,33645.258285,2,95,14,14,4.45,3,3,1,0,0,2,29,1,5,1,5 +65509,7,2,2,10,NA,4,4,2,10,130,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9235.947079,9749.775473,1,96,7,7,1.39,5,5,0,2,2,1,69,2,2,1,2 +65510,7,2,2,65,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,44238.530111,44780.242841,1,95,3,3,0.87,2,2,0,0,2,2,65,1,2,1,3 +65511,7,2,1,7,NA,1,1,1,7,86,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,14820.807433,14905.891142,2,102,7,7,1.53,5,5,0,3,0,1,43,2,2,1,4 +65512,7,2,2,39,NA,1,1,2,NA,NA,2,NA,2,2,5,NA,3,1,1,2,2,2,2,2,2,2,2,2,2,35353.005268,38359.582487,2,94,4,4,0.81,3,3,0,1,0,1,49,2,3,1,3 +65513,7,2,1,32,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,47932.213152,49921.729758,1,92,10,10,3.04,4,4,1,1,0,1,32,1,3,1,2 +65514,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,43425.032766,48500.713195,1,96,15,15,5,2,2,0,0,2,2,80,1,5,1,5 +65515,7,2,2,14,NA,4,4,2,14,173,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17185.945299,17434.901758,2,91,2,2,0.26,4,4,0,1,0,1,20,1,3,5,NA +65516,7,2,1,0,9,1,1,1,NA,10,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,7527.69611,7949.840792,1,92,99,99,NA,5,5,1,0,0,1,46,2,3,1,3 +65517,7,2,2,25,NA,1,1,2,NA,NA,2,NA,2,2,3,NA,4,1,2,1,2,2,1,2,2,2,2,2,2,39426.061521,41875.604468,2,94,8,8,2.7,3,3,1,0,0,1,27,1,3,1,4 +65518,7,2,1,45,NA,4,4,2,NA,NA,2,NA,2,1,5,NA,2,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,16052.801806,16001.600848,2,90,6,6,1.03,6,6,3,1,0,1,45,2,2,1,2 +65519,7,2,1,13,NA,5,6,2,13,165,NA,NA,2,2,1,6,NA,NA,NA,1,1,1,1,2,1,1,2,1,1,10346.302718,11892.421636,2,91,99,99,NA,7,4,0,4,0,1,36,2,9,1,2 +65520,7,2,2,36,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,44274.069981,46208.106563,2,101,7,7,2.58,2,2,0,0,0,2,36,1,5,1,3 +65521,7,2,1,17,NA,3,3,1,17,205,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,26457.098276,26381.28385,2,98,3,3,0.38,5,5,0,4,0,2,39,1,4,5,NA +65522,7,2,2,71,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,1,2,NA,11550.700389,12323.715655,2,93,2,2,0.54,1,1,0,0,1,2,71,1,2,2,NA +65523,7,2,2,11,NA,4,4,1,12,144,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8362.256577,9003.967662,2,100,8,8,1.8,5,5,0,3,0,2,43,1,3,1,3 +65524,7,2,1,63,NA,1,1,1,NA,NA,2,NA,2,1,7,NA,1,1,NA,2,2,1,1,2,1,2,2,1,2,10596.142548,10856.489537,1,94,7,7,1.48,5,5,0,0,1,2,52,2,1,1,1 +65525,7,2,2,69,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,1,11224.764345,11466.33634,1,101,5,5,1.84,1,1,0,0,1,2,69,1,5,2,NA +65526,7,2,1,4,NA,4,4,1,4,58,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12032.669734,13267.985975,2,96,6,6,1.48,4,4,1,1,0,2,25,1,4,5,NA +65527,7,2,1,11,NA,4,4,2,11,142,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7730.47951,9212.541007,1,99,7,7,1.53,5,5,0,3,0,1,39,1,3,1,3 +65528,7,2,1,0,0,4,4,2,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,NA,NA,NA,NA,NA,NA,NA,5360.999096,5929.781839,2,90,8,6,1.46,4,3,1,1,0,2,21,1,5,6,NA +65529,7,2,2,1,18,5,7,2,NA,19,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,22159.470641,22857.583467,1,95,3,3,0.45,4,4,2,1,0,2,26,1,3,4,NA +65530,7,2,1,40,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,136880.768184,145646.064425,1,94,5,5,1.04,4,4,1,1,0,1,18,1,2,NA,NA +65531,7,2,1,11,NA,1,1,1,11,136,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11881.117946,11763.87702,1,102,15,15,4.47,4,4,0,2,0,2,30,1,4,1,4 +65532,7,2,1,18,NA,4,4,2,18,224,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11107.552941,11616.709768,2,99,4,4,1,3,3,0,1,0,2,38,1,3,5,NA +65533,7,2,1,4,NA,4,4,1,4,58,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11302.271106,11769.28244,3,92,6,6,0.93,5,5,2,1,0,2,37,1,5,1,3 +65534,7,2,2,31,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,27381.645976,28428.806364,2,95,15,1,0.18,5,1,0,0,0,1,47,1,5,1,3 +65535,7,2,2,0,10,3,3,2,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8383.207272,8612.693254,1,91,6,6,1.03,5,5,3,0,0,2,37,1,5,6,NA +65536,7,2,2,61,NA,1,1,1,NA,NA,2,NA,2,1,7,NA,2,1,NA,2,2,2,2,2,2,1,2,2,2,15876.871857,17178.834476,2,102,4,4,0.67,4,4,0,0,2,2,20,1,1,NA,NA +65537,7,2,1,21,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,31707.924183,33437.457992,1,97,3,3,0.73,3,3,0,0,0,2,50,1,4,1,3 +65538,7,2,2,9,NA,3,3,1,9,119,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,47428.012402,47285.525443,2,98,10,10,4.42,2,2,0,1,0,2,41,1,4,3,NA +65539,7,2,1,27,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,13367.406737,13987.969236,1,92,15,15,4.44,5,5,0,0,1,1,65,NA,NA,1,5 +65540,7,2,1,9,NA,3,3,1,9,115,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,74331.764009,78594.005469,2,91,9,9,2.6,4,4,0,2,0,1,53,1,2,1,5 +65541,7,2,2,9,NA,4,4,1,9,110,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12120.418061,12444.673315,2,97,7,7,1.72,5,5,1,2,0,1,32,1,4,1,4 +65542,7,2,1,2,NA,3,3,2,2,28,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,37959.146468,40828.920669,1,94,15,15,5,3,3,1,0,0,1,35,1,5,1,5 +65543,7,2,1,23,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,108373.053289,112114.199141,3,92,15,15,5,3,3,0,0,0,1,56,NA,NA,1,4 +65544,7,2,2,19,NA,4,4,2,19,234,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,19113.842115,19208.656277,1,97,1,1,0.09,4,4,0,1,0,2,44,2,2,1,3 +65545,7,2,1,28,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,116462.885745,124577.022727,1,93,15,15,5,2,2,0,0,0,1,28,1,5,6,NA +65546,7,2,2,22,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,25052.373156,24265.266353,1,92,6,6,1.31,3,3,0,0,1,2,80,1,3,4,NA +65547,7,2,2,63,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,24832.705563,25238.431199,2,100,2,2,0.73,1,1,0,0,1,2,63,1,4,2,NA +65548,7,2,2,47,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,99120.116925,103753.216485,2,98,14,14,4.16,3,3,0,0,0,1,49,1,5,1,4 +65549,7,2,1,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,12291.154515,13189.875012,1,92,5,5,1.84,1,1,0,0,1,1,80,1,3,2,NA +65550,7,2,1,31,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,34997.800447,36838.864542,2,96,14,14,3.36,4,4,1,1,0,2,28,1,2,6,NA +65551,7,2,2,8,NA,3,3,2,9,108,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,60197.256541,63931.531988,2,94,14,14,2.63,6,6,1,3,0,1,39,1,4,1,4 +65552,7,2,2,13,NA,3,3,1,13,165,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,37065.780724,38522.476457,1,98,5,5,0.74,5,5,0,3,0,1,35,1,2,6,NA +65553,7,2,2,42,NA,2,2,2,NA,NA,2,NA,2,2,2,NA,2,4,2,2,2,2,2,2,2,NA,NA,NA,NA,32229.130119,41089.02125,2,90,13,2,0.46,2,1,0,0,1,2,80,NA,NA,77,NA +65554,7,2,1,47,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,32980.717958,34973.413194,1,95,5,5,1.19,3,3,1,1,0,1,47,1,2,3,NA +65555,7,2,2,20,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,53634.754806,56026.668478,1,98,5,2,0.45,3,1,0,0,0,1,32,1,5,5,NA +65556,7,2,1,5,NA,4,4,2,5,71,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10234.881417,10547.495238,2,97,2,2,0.33,4,4,2,1,0,2,34,1,2,5,NA +65557,7,2,2,30,NA,2,2,2,NA,NA,2,NA,2,2,3,NA,5,5,2,2,2,2,2,2,2,NA,NA,NA,NA,27973.581456,27218.795462,2,99,99,99,NA,5,3,0,1,0,1,40,2,1,6,NA +65558,7,2,2,36,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,42489.109693,44345.173355,1,100,14,9,5,2,1,0,0,0,1,37,1,2,6,NA +65559,7,2,1,8,NA,2,2,2,8,101,NA,NA,1,1,NA,3,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,9807.589376,10786.008845,2,90,3,3,0.38,5,5,0,4,0,2,33,2,2,5,NA +65560,7,2,1,4,NA,2,2,2,4,54,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,11852.624029,11657.344215,2,99,99,99,NA,3,3,1,0,0,1,35,2,2,1,2 +65561,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,1,2,NA,60148.377616,67408.231176,1,92,8,8,2.17,4,4,0,1,2,2,80,1,3,2,NA +65562,7,2,2,62,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,9548.871949,9975.218868,2,95,6,6,1.36,3,3,0,1,1,2,62,1,4,5,NA +65563,7,2,1,25,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,39260.973419,41280.172031,1,91,4,2,0.55,3,1,0,0,0,2,22,1,5,6,NA +65564,7,2,2,36,NA,4,4,2,NA,NA,2,NA,2,1,7,NA,4,4,2,1,2,2,1,2,2,1,2,2,1,19738.81952,19597.773568,3,90,3,3,0.37,5,5,2,2,0,2,36,2,4,4,NA +65565,7,2,1,27,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,108410.783716,113500.095101,1,91,15,6,2.69,3,1,0,0,0,1,27,1,3,6,NA +65566,7,2,2,30,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,85444.349063,88741.398785,3,91,8,8,1.95,4,4,2,0,0,2,30,1,5,1,4 +65567,7,2,1,20,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,32375.321924,34954.784356,1,95,1,1,0.21,4,4,1,0,1,2,75,1,1,2,NA +65568,7,2,2,36,NA,1,1,1,NA,NA,2,NA,2,2,3,NA,1,1,2,2,2,2,1,2,2,NA,NA,NA,NA,45655.090694,44423.220436,3,92,6,6,0.86,7,7,1,4,0,2,36,2,1,1,1 +65569,7,2,2,16,NA,2,2,2,16,197,NA,NA,1,1,NA,9,NA,NA,NA,2,2,2,1,2,2,1,2,2,1,20678.81116,21093.085203,1,93,5,5,0.84,5,5,1,2,0,2,52,2,1,3,NA +65570,7,2,1,16,NA,3,3,2,16,200,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,35593.481513,36275.823276,1,91,5,5,1.36,2,2,0,1,0,2,49,1,5,3,NA +65571,7,2,2,74,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,1,2,NA,1,2,1,1,2,1,1,2,1,NA,13446.397433,14295.858749,1,93,3,3,0.65,3,3,0,0,3,2,74,2,1,2,NA +65572,7,2,2,79,NA,5,6,1,NA,NA,2,NA,2,1,9,NA,5,5,NA,1,2,2,1,2,2,1,2,2,NA,15984.880532,16163.124545,1,98,9,9,4.92,1,1,0,0,1,2,79,2,5,5,NA +65573,7,2,1,44,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,22165.906062,22485.884772,1,96,7,7,3.58,1,1,0,0,0,1,44,1,4,3,NA +65574,7,2,1,0,3,3,3,2,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8637.740206,8903.804193,1,91,6,6,1.07,6,6,3,1,0,2,27,1,4,6,NA +65575,7,2,1,28,NA,2,2,2,NA,NA,2,NA,2,2,3,NA,2,6,NA,2,2,2,2,2,2,1,2,2,2,35669.2076,38557.984895,2,94,14,4,1.74,5,1,0,0,0,1,24,2,4,5,NA +65576,7,2,2,27,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,63207.045171,66153.523399,2,102,10,6,2.3,2,1,0,0,0,2,27,1,4,6,NA +65577,7,2,1,54,NA,4,4,2,NA,NA,2,NA,2,1,6,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,15044.515884,15040.577827,3,90,15,15,5,3,3,0,0,0,2,55,2,4,1,4 +65578,7,2,2,1,18,1,1,1,NA,19,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,11901.705423,12408.80856,2,102,8,8,1.91,5,5,1,2,0,1,36,2,1,1,4 +65579,7,2,2,3,NA,5,6,2,3,47,NA,NA,2,1,2,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5380.83825,5375.15484,2,95,15,15,5,3,3,1,0,0,1,53,1,5,1,2 +65580,7,2,2,19,NA,2,2,1,19,233,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,17338.975742,19021.185309,2,93,8,8,2.49,3,3,0,0,0,1,52,2,2,1,4 +65581,7,2,1,46,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,28542.421068,31101.791288,2,101,7,7,2.58,2,2,0,0,0,2,36,1,5,1,3 +65582,7,2,2,7,NA,5,6,2,7,95,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5481.728631,5853.665419,1,91,15,15,5,6,6,0,2,2,1,50,2,5,1,5 +65583,7,2,2,16,NA,4,4,2,16,202,NA,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,10694.834447,10849.760352,1,90,9,9,1.65,7,7,0,4,0,1,36,1,4,1,4 +65584,7,2,1,11,NA,4,4,2,11,134,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8579.422451,8987.382625,1,99,6,6,2.18,2,2,0,1,0,2,31,1,4,5,NA +65585,7,2,2,49,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,1,2,2,3,21956.01693,22136.94803,2,91,8,8,2.34,4,4,0,2,0,1,56,2,5,1,5 +65586,7,2,2,35,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,32501.623429,34582.098932,2,97,3,3,0.46,5,5,0,3,0,1,40,1,2,1,3 +65587,7,2,1,78,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,62466.132707,66344.89016,1,94,6,6,1.91,2,2,0,0,2,1,78,1,4,1,3 +65588,7,2,2,15,NA,3,3,2,15,184,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,74165.041171,75130.242541,2,94,10,10,3.51,3,3,0,2,0,2,39,2,4,3,NA +65589,7,2,1,69,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,2,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,10288.337394,10907.668198,3,91,14,4,1.02,6,2,0,0,2,1,48,2,1,1,1 +65590,7,2,2,43,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,18795.138328,22008.372948,2,93,9,9,2.07,5,5,0,1,0,1,55,NA,NA,5,NA +65591,7,2,2,5,NA,2,2,2,6,72,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11429.37307,11583.084593,2,90,15,15,5,4,4,1,1,0,1,49,1,4,1,4 +65592,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,26010.201422,30173.312639,2,95,3,3,1.21,1,1,0,0,1,2,80,1,2,2,NA +65593,7,2,2,51,NA,2,2,1,NA,NA,2,NA,2,2,5,NA,5,1,NA,1,2,2,1,2,2,2,2,2,2,20178.078974,20795.430208,2,100,14,14,3.58,4,4,0,1,0,1,46,2,5,1,5 +65594,7,2,2,60,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,4,NA,1,2,2,1,2,2,1,2,2,1,10192.188896,10604.379638,1,99,4,4,1.74,1,1,0,0,1,2,60,1,3,4,NA +65595,7,1,2,66,NA,2,2,NA,NA,NA,2,NA,2,2,4,NA,4,1,NA,2,2,2,1,2,2,NA,NA,NA,NA,10235.0654,0,2,93,6,6,1.3,4,4,0,0,2,2,36,2,4,1,4 +65596,7,2,2,60,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,11896.060838,12427.20723,1,96,15,15,5,2,2,0,0,2,1,61,1,5,1,5 +65597,7,2,2,19,NA,4,4,1,19,230,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,18163.985724,18749.311901,2,101,2,2,0.46,1,1,0,0,0,2,19,1,4,NA,NA +65598,7,1,1,53,NA,3,3,NA,NA,NA,2,NA,2,1,5,NA,2,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,20980.882737,0,2,93,6,6,1.48,4,4,0,1,0,1,53,2,2,1,3 +65599,7,2,2,56,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,12127.194143,12676.977658,3,90,15,15,4.2,6,6,1,0,2,1,60,1,5,1,4 +65600,7,2,2,19,NA,1,1,2,19,232,2,NA,1,1,NA,12,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,20937.26435,21936.153747,1,90,15,15,5,4,4,0,0,0,1,54,1,5,1,5 +65601,7,2,1,15,NA,4,4,2,15,190,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13366.904548,14267.035861,1,93,7,7,1.79,4,4,0,2,0,1,53,2,4,1,4 +65602,7,2,1,19,NA,4,4,2,20,NA,2,NA,2,2,3,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12548.434193,12514.39179,2,99,3,1,0.31,4,1,0,0,0,1,19,2,4,NA,NA +65603,7,2,2,63,NA,5,6,2,NA,NA,2,NA,2,1,4,NA,3,1,NA,1,2,1,1,2,1,1,2,1,NA,13656.521422,13861.04165,1,91,4,4,1.33,2,2,0,0,2,1,65,2,4,1,3 +65604,7,2,1,29,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,9668.679611,9969.996889,1,102,15,15,3.82,5,5,1,1,0,1,29,1,4,1,4 +65605,7,2,1,68,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,10274.998921,11619.264446,1,91,8,8,3.57,2,2,0,0,2,1,68,1,3,1,2 +65606,7,2,2,48,NA,5,6,2,NA,NA,2,NA,2,2,5,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,18215.139307,19150.911381,1,91,77,77,NA,4,4,0,2,0,1,50,2,5,1,5 +65607,7,2,2,5,NA,4,4,2,5,61,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8873.727797,9364.677323,2,99,5,5,0.78,5,5,2,2,0,2,30,1,3,5,NA +65608,7,2,1,5,NA,2,2,2,5,71,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,15745.774489,16244.197679,2,91,4,4,0.67,5,4,2,0,2,2,66,2,1,1,NA +65609,7,2,2,1,19,3,3,2,NA,19,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,25257.21318,27876.153487,1,101,7,7,1.82,4,4,2,0,0,2,27,1,2,1,3 +65610,7,2,1,9,NA,4,4,1,9,117,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8714.559478,8865.734494,2,96,3,3,0.47,6,6,0,4,0,1,36,1,4,1,4 +65611,7,2,2,19,NA,2,2,2,19,232,2,NA,2,2,3,12,NA,NA,NA,2,2,2,2,2,2,1,2,2,2,12680.621719,13709.581084,2,90,99,99,NA,5,5,1,1,0,2,40,2,3,1,1 +65612,7,2,1,5,NA,4,4,1,5,69,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,NA,NA,NA,NA,NA,NA,NA,7991.632447,8596.395387,1,102,12,12,NA,7,7,3,2,0,2,52,1,4,5,NA +65613,7,2,2,53,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,122472.877524,125201.399718,2,94,15,15,5,3,3,0,1,1,1,63,1,5,1,3 +65614,7,2,2,10,NA,1,1,1,10,121,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15859.146626,16025.878294,1,92,1,1,0,3,1,0,2,0,2,43,1,2,4,NA +65615,7,1,1,80,NA,3,3,NA,NA,NA,2,NA,2,1,9,NA,1,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,38666.703155,0,2,94,2,2,0.81,1,1,0,0,1,1,80,2,1,2,NA +65616,7,2,1,0,3,3,3,2,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9570.577309,9932.368407,1,95,6,6,1,6,6,3,0,0,2,23,1,4,6,NA +65617,7,2,1,41,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,21571.318341,21852.480517,1,102,15,15,5,3,3,0,1,0,1,41,1,5,1,5 +65618,7,2,2,2,NA,2,2,2,3,36,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,9955.153132,10990.75621,2,94,9,9,2.51,4,4,2,0,0,2,34,2,3,1,3 +65619,7,2,1,20,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,50647.682308,53126.874664,2,96,8,8,3.67,2,2,0,0,0,1,58,1,3,3,NA +65620,7,2,2,25,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,110849.032294,115406.960266,2,92,14,6,2.75,2,1,0,0,0,2,25,1,5,5,NA +65621,7,2,1,63,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,8748.603912,9090.779024,1,96,14,14,5,2,2,0,0,2,2,61,1,3,1,3 +65622,7,2,1,7,NA,4,4,1,7,87,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15130.588085,15393.064565,2,102,15,15,3.82,5,5,1,2,0,1,34,1,3,1,4 +65623,7,2,2,25,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,18626.118419,17709.928623,1,93,15,15,5,5,5,0,1,0,2,25,1,5,5,NA +65624,7,2,2,11,NA,4,4,1,11,135,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12120.418061,12444.673315,2,97,7,7,1.72,5,5,1,2,0,1,32,1,4,1,4 +65625,7,2,1,23,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,14690.01297,15450.354874,3,91,2,2,0.73,1,1,0,0,0,1,23,1,5,5,NA +65626,7,2,1,11,NA,4,4,2,11,133,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8017.552697,8398.795399,1,99,4,4,0.41,7,7,2,4,0,2,43,1,4,4,NA +65627,7,2,1,16,NA,4,4,2,16,193,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,15970.206483,16086.518081,2,97,2,2,0.3,4,4,0,2,0,1,42,1,2,6,NA +65628,7,2,1,56,NA,1,1,2,NA,NA,1,1,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,25381.488007,25009.053797,2,99,6,6,2.33,1,1,0,0,0,1,56,1,4,2,NA +65629,7,2,2,51,NA,5,6,2,NA,NA,2,NA,2,2,1,NA,2,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,13281.538492,13864.580434,3,90,5,5,1.05,3,3,0,0,0,1,53,2,1,1,2 +65630,7,2,1,4,NA,1,1,2,4,59,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16214.341036,15789.305867,1,98,9,9,2,7,6,3,2,0,2,32,1,4,1,4 +65631,7,2,1,24,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,17420.978407,17014.040717,2,97,2,2,0.49,2,2,0,0,0,1,24,1,4,6,NA +65632,7,2,2,42,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,5,3,2,1,2,2,1,2,2,1,2,2,1,34639.996543,35471.414202,1,102,7,7,1.7,4,4,0,0,2,1,44,1,4,4,NA +65633,7,2,1,57,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,31699.998102,36617.55692,1,98,1,1,0.04,1,1,0,0,0,1,57,1,4,5,NA +65634,7,2,2,61,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,1,9113.905743,9695.883475,3,90,15,15,5,5,5,0,1,1,2,61,1,5,2,NA +65635,7,2,2,29,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,22225.098465,22243.480978,2,97,4,4,0.81,4,4,1,1,0,2,51,1,3,4,NA +65636,7,2,2,51,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,19323.414782,18794.578845,2,91,15,15,5,4,4,0,0,1,1,61,NA,NA,1,2 +65637,7,2,1,66,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,6358.062034,6283.458155,1,99,7,7,3.49,1,1,0,0,1,1,66,1,4,3,NA +65638,7,2,1,12,NA,5,7,2,12,153,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,21852.102821,22875.024578,3,91,5,5,0.65,7,7,0,4,0,2,39,1,3,4,NA +65639,7,1,2,14,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,91539.042546,0,1,101,15,15,5,4,4,0,2,0,2,40,1,4,1,3 +65640,7,2,2,65,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,1,12751.545122,13835.806616,2,101,1,1,0.08,2,2,0,0,2,2,80,1,1,2,NA +65641,7,2,2,33,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,2,1,2,2,1,2,2,1,2,2,1,74517.751389,83352.706958,2,94,5,5,0.89,4,4,0,2,0,2,51,1,2,3,NA +65642,7,2,2,41,NA,3,3,2,NA,NA,2,NA,2,1,7,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,96255.674553,98150.909956,2,94,14,14,5,3,3,0,0,0,1,42,1,5,1,5 +65643,7,2,2,38,NA,3,3,2,NA,NA,2,NA,2,2,4,NA,5,1,1,1,2,2,1,2,2,1,2,2,1,95214.22557,102645.939709,1,97,15,15,5,5,4,1,1,0,2,38,NA,NA,1,5 +65644,7,2,2,19,NA,4,4,2,19,233,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,18163.985724,18905.695776,2,101,1,1,0.23,2,1,0,0,0,2,19,1,3,NA,NA +65645,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,38666.703155,42427.769217,2,91,7,7,1.61,4,4,0,0,3,1,65,1,3,6,NA +65646,7,2,1,8,NA,3,3,1,8,99,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18596.465852,19407.799286,1,94,7,7,1.29,6,6,1,3,0,1,38,1,3,1,2 +65647,7,2,2,29,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,52701.331723,59294.433957,1,94,5,5,1.04,4,4,0,2,0,2,29,1,3,1,3 +65648,7,2,1,61,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,7101.739553,7379.502561,2,100,4,4,1.74,1,1,0,0,1,1,61,1,3,3,NA +65649,7,2,2,37,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,26428.874559,27145.22781,2,99,14,14,4.09,3,3,0,2,0,2,37,1,5,5,NA +65650,7,2,2,79,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,20101.581228,20798.747999,3,92,77,77,NA,1,1,0,0,1,2,79,1,4,2,NA +65651,7,2,1,6,NA,5,7,2,6,81,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7923.925927,8546.646915,1,91,15,15,5,5,5,0,3,0,1,40,1,5,1,5 +65652,7,1,2,1,20,3,3,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,24749.659974,0,1,94,1,1,0.08,7,7,2,4,0,1,31,1,2,1,4 +65653,7,2,2,30,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,1,2,1,2,2,1,2,2,1,2,2,1,33506.462855,33906.169633,2,96,4,4,0.65,5,5,0,3,0,1,30,1,4,1,2 +65654,7,2,1,10,NA,5,6,2,10,131,NA,NA,1,1,NA,5,NA,NA,NA,1,1,1,1,2,1,1,2,2,1,6850.601671,7624.777305,3,91,6,6,1.34,4,4,0,2,0,1,52,2,3,1,1 +65655,7,2,2,54,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,16741.034883,16786.385595,2,95,12,12,NA,3,3,0,0,0,2,29,2,5,5,NA +65656,7,2,2,2,NA,3,3,1,2,27,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,45341.612978,50043.120503,3,91,14,14,5,3,3,1,0,0,2,30,1,4,1,5 +65657,7,2,1,15,NA,1,1,1,16,192,NA,NA,1,1,NA,9,NA,NA,NA,2,1,1,1,2,1,1,2,2,1,29234.272259,28953.402615,2,98,7,7,2.25,3,3,0,1,0,2,51,2,1,1,1 +65658,7,2,2,49,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,29448.834066,28780.798614,1,97,9,9,4.92,1,1,0,0,0,2,49,1,5,5,NA +65659,7,2,2,71,NA,4,4,2,NA,NA,2,NA,2,1,6,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,12344.929687,13268.288363,1,93,2,2,0.74,1,1,0,0,1,2,71,2,2,2,NA +65660,7,2,2,73,NA,3,3,2,NA,NA,2,NA,2,1,6,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,36122.708948,47794.076653,1,97,2,2,0.75,1,1,0,0,1,2,73,2,2,2,NA +65661,7,2,2,38,NA,2,2,2,NA,NA,2,NA,2,2,5,NA,3,3,2,2,2,2,1,2,2,2,2,2,2,35678.162793,37949.435224,2,99,3,3,0.52,3,3,0,0,1,2,38,2,3,3,NA +65662,7,2,2,31,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,33506.462855,35016.985063,2,96,6,6,1.62,3,3,0,2,0,2,31,1,3,5,NA +65663,7,2,2,24,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,3,1,2,2,1,2,2,1,2,2,1,52701.331723,53172.517558,1,94,5,5,0.74,5,5,1,1,0,2,24,1,3,1,4 +65664,7,2,2,13,NA,3,3,2,13,160,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,71837.483011,75155.181458,1,94,15,15,5,3,3,0,1,0,2,43,1,5,1,5 +65665,7,2,1,19,NA,1,1,1,19,233,2,NA,1,1,NA,12,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,15626.107676,15463.700675,2,93,9,9,1.94,6,6,0,3,0,2,37,NA,NA,3,NA +65666,7,2,2,3,NA,2,2,1,3,44,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15457.736897,16648.051651,2,98,8,8,1.48,7,7,3,0,0,1,26,1,3,1,3 +65667,7,2,1,8,NA,4,4,1,8,98,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10410.106675,10534.907593,2,96,6,6,1.32,5,5,1,3,0,2,30,1,4,3,NA +65668,7,2,2,8,NA,5,7,1,8,97,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11541.681354,12101.149927,1,92,15,15,5,4,4,0,2,0,1,41,2,5,1,5 +65669,7,2,1,47,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,152858.509804,159007.057971,1,95,14,8,4.41,2,1,0,0,0,1,47,1,4,3,NA +65670,7,2,1,13,NA,1,1,1,14,169,NA,NA,1,1,NA,7,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,17424.208904,17520.505085,1,102,5,5,0.92,5,5,0,3,0,2,39,2,3,1,3 +65671,7,2,2,2,NA,4,4,2,2,27,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7444.013422,7636.156038,1,90,5,5,1.32,2,2,1,0,0,2,27,2,3,5,NA +65672,7,2,2,22,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,30275.274308,33292.204257,2,101,3,3,0.92,1,1,0,0,0,2,22,1,4,5,NA +65673,7,2,1,2,NA,3,3,1,2,32,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,24594.444896,28818.16319,1,98,1,1,0.16,3,3,1,0,0,1,28,1,2,6,NA +65674,7,2,2,80,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,17285.492411,17948.070756,1,102,7,7,1.8,5,4,1,0,2,1,47,1,3,5,NA +65675,7,2,1,66,NA,1,1,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,11568.876339,11794.347884,1,102,10,10,4.42,2,2,0,0,2,2,62,1,5,1,4 +65676,7,2,2,35,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,2,1,2,2,1,2,2,1,2,2,1,71034.153987,75000.659691,1,98,9,9,2.6,4,4,1,1,0,2,35,1,2,1,NA +65677,7,2,2,4,NA,1,1,2,4,54,NA,NA,1,1,NA,NA,NA,NA,NA,2,NA,2,2,2,2,NA,NA,NA,NA,13193.876261,13756.035699,3,91,7,7,1.23,6,6,2,2,0,1,36,2,1,1,1 +65678,7,2,1,33,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,12697.263698,13996.985089,1,91,6,6,1.07,6,6,3,1,0,2,27,1,4,6,NA +65679,7,2,1,69,NA,5,7,2,NA,NA,2,NA,2,1,7,NA,4,3,NA,1,2,2,1,2,2,1,2,2,NA,10298.198778,10826.998489,1,95,2,2,0.72,1,1,0,0,1,1,69,2,4,3,NA +65680,7,2,2,44,NA,5,6,1,NA,NA,2,NA,2,2,5,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,16162.24986,16822.942152,3,91,15,15,5,3,3,0,1,0,2,44,2,5,1,5 +65681,7,2,2,4,NA,1,1,1,4,59,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16462.187772,17163.602129,3,92,8,8,1.55,6,6,1,3,0,2,38,1,5,1,4 +65682,7,2,2,57,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,143785.115498,143265.966876,1,99,10,10,5,1,1,0,0,0,2,57,1,5,3,NA +65683,7,2,1,51,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,2,1,NA,1,2,2,1,2,1,1,2,2,1,7879.750437,7851.284287,2,92,10,8,2.01,7,4,1,1,1,2,27,2,3,1,3 +65684,7,2,1,14,NA,1,1,1,14,179,NA,NA,2,2,4,8,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,18242.832494,18343.652859,1,102,2,2,0.52,3,3,0,2,0,2,36,2,3,4,NA +65685,7,2,2,29,NA,1,1,2,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,NA,NA,NA,NA,51746.15111,54067.303468,1,95,8,8,2.24,4,4,2,0,0,2,29,1,3,1,4 +65686,7,2,2,9,NA,4,4,1,9,117,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10085.683644,10404.203071,2,102,6,6,1.22,5,5,0,2,0,2,42,1,4,1,4 +65687,7,2,2,55,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,23128.736624,23721.941544,2,101,2,2,0.79,1,1,0,0,0,2,55,1,2,3,NA +65688,7,2,2,54,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,187291.098551,186266.152024,2,91,15,15,5,3,3,0,0,0,2,54,1,4,1,4 +65689,7,2,1,19,NA,4,4,2,19,234,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13969.457688,14694.403205,1,90,6,6,1.57,3,3,0,1,0,2,36,1,3,5,NA +65690,7,2,1,16,NA,3,3,2,16,198,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,107087.58296,107224.801212,1,95,8,8,1.28,7,7,1,4,0,1,32,1,3,1,3 +65691,7,2,2,16,NA,5,6,1,16,199,NA,NA,2,2,2,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,8391.252153,8753.945484,1,92,12,12,NA,7,7,1,2,1,2,45,2,3,1,3 +65692,7,2,1,14,NA,3,3,2,14,169,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,26824.630008,26472.092796,1,95,6,6,1.3,4,4,0,3,0,2,46,1,4,3,NA +65693,7,2,1,7,NA,3,3,2,7,94,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,66868.503099,69864.859716,1,98,15,15,5,4,4,1,1,0,1,40,1,4,1,5 +65694,7,2,2,5,NA,2,2,2,6,72,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,13366.393396,14756.857003,2,94,9,9,2.51,4,4,2,0,0,2,34,2,3,1,3 +65695,7,1,1,9,NA,5,6,NA,NA,NA,NA,NA,1,1,NA,3,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,8943.919305,0,1,92,5,5,0.63,7,7,0,4,1,1,60,NA,NA,1,NA +65696,7,2,2,8,NA,4,4,2,8,105,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6996.144083,7533.021082,2,99,5,5,0.78,5,5,2,2,0,2,30,1,3,5,NA +65697,7,2,1,16,NA,3,3,2,16,201,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,26749.020961,27839.957403,1,101,6,6,1.21,4,4,0,2,0,2,33,1,2,6,NA +65698,7,2,1,8,NA,4,4,2,8,97,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11094.855304,11787.231447,1,90,7,7,2.1,3,3,0,1,0,1,35,1,3,6,NA +65699,7,2,1,50,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,152467.08796,154000.877343,1,94,6,6,2.24,1,1,0,0,0,1,50,1,3,3,NA +65700,7,2,2,18,NA,4,4,1,18,220,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,14166.687432,14623.20249,1,100,13,13,NA,5,5,2,0,0,2,54,1,4,5,NA +65701,7,2,2,17,NA,4,4,2,17,205,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11711.384457,11558.024533,2,95,9,9,1.81,6,6,1,1,0,2,56,1,4,3,NA +65702,7,2,2,62,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,10999.00871,11458.057418,3,92,7,7,1.49,5,5,0,2,1,2,62,1,4,2,NA +65703,7,2,2,29,NA,1,1,2,NA,NA,2,NA,2,2,5,NA,4,3,2,1,2,2,1,2,2,NA,NA,NA,NA,39426.061521,39893.228552,3,92,8,8,2.01,4,4,1,0,0,2,49,2,5,4,NA +65704,7,2,2,7,NA,3,3,2,7,87,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,82043.921571,82230.595899,1,97,14,14,3.9,4,4,0,2,0,1,47,1,3,1,5 +65705,7,2,2,63,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,1,4,NA,1,2,2,1,2,2,1,2,2,1,15207.312407,15975.329738,1,92,4,4,0.99,2,2,0,0,1,1,26,1,1,5,NA +65706,7,2,2,11,NA,3,3,2,11,143,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,24070.467912,24097.958076,1,95,6,3,0.45,6,4,1,2,0,1,28,1,2,1,2 +65707,7,2,1,75,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,62703.997496,73870.695024,1,94,10,10,3.04,4,4,0,0,2,1,75,1,3,1,3 +65708,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,35334.703093,40990.264786,1,101,3,3,1.25,1,1,0,0,1,2,80,1,2,2,NA +65709,7,2,2,17,NA,3,3,2,17,209,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,97212.131473,101229.4133,1,91,14,14,3.8,4,4,0,2,0,1,50,NA,NA,1,5 +65710,7,2,2,17,NA,4,4,2,17,210,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11608.900361,11982.991894,1,99,8,8,2.59,3,3,0,2,0,2,46,1,4,2,NA +65711,7,2,1,46,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,11113.602843,11073.454175,3,90,77,77,NA,5,5,0,2,0,1,46,2,3,1,3 +65712,7,2,1,75,NA,2,2,2,NA,NA,1,1,2,1,7,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,14090.083482,14599.284236,2,90,6,6,2.24,2,2,0,0,2,1,75,2,4,1,2 +65713,7,2,1,72,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,1,3,NA,1,2,2,1,2,2,1,2,2,NA,14078.198261,14841.449973,1,91,1,1,0.05,2,1,0,0,2,1,72,1,1,3,NA +65714,7,2,1,72,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,64271.597433,68262.462992,1,94,15,15,4.95,4,4,0,0,2,1,72,1,3,1,3 +65715,7,2,1,12,NA,5,7,2,12,146,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,60818.973858,62775.825513,1,99,15,15,5,4,4,0,2,0,2,44,1,5,1,5 +65716,7,2,2,54,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,42559.487719,42454.393427,1,98,6,6,1.57,3,3,0,0,0,1,58,1,3,1,3 +65717,7,2,1,10,NA,4,4,1,10,124,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11443.206518,12087.326286,1,100,13,13,NA,3,3,0,1,0,2,52,2,3,1,NA +65718,7,2,2,11,NA,5,7,2,11,137,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9227.090107,9736.375878,2,100,15,15,4.83,4,4,1,1,0,1,43,2,5,1,5 +65719,7,2,1,68,NA,5,6,1,NA,NA,2,NA,2,2,3,NA,2,1,NA,1,2,2,1,2,2,1,2,2,3,11145.558675,12081.671552,2,96,4,4,0.92,3,3,0,1,1,2,41,2,2,1,2 +65720,7,2,1,5,NA,2,2,2,5,61,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12403.412256,13289.361067,2,90,6,6,1.62,3,3,1,0,0,2,28,1,5,1,4 +65721,7,2,2,6,NA,1,1,1,6,82,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14538.945634,14691.797657,2,92,8,8,1.42,7,7,0,4,0,2,37,1,1,6,NA +65722,7,2,2,39,NA,1,1,2,NA,NA,2,NA,1,1,NA,NA,2,6,2,1,2,2,1,2,2,1,2,2,1,37237.570046,37476.359157,2,97,4,1,0,2,1,0,0,0,1,41,1,2,6,NA +65723,7,1,1,73,NA,3,3,NA,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,15200.416613,0,1,98,4,4,1.19,2,2,0,0,2,2,72,1,3,1,4 +65724,7,1,2,4,NA,1,1,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,2,2,2,NA,NA,NA,NA,13366.393396,0,2,94,14,7,2.72,3,2,1,0,0,1,25,2,3,6,NA +65725,7,2,2,8,NA,3,3,2,9,108,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,70999.269152,75403.63644,1,93,15,15,5,4,4,0,2,0,1,51,1,3,1,5 +65726,7,2,1,23,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,15196.92397,16091.373745,2,101,7,3,1.1,3,1,0,0,0,1,21,2,4,5,NA +65727,7,2,2,3,NA,1,1,1,3,41,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15457.736897,16432.24332,3,92,7,7,1.41,5,5,1,2,0,1,40,1,3,1,4 +65728,7,2,2,0,1,4,4,2,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4581.358327,5045.31579,2,101,4,4,0.85,4,4,1,0,1,2,61,1,4,3,NA +65729,7,2,1,9,NA,3,3,1,9,113,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,23188.935049,25672.571973,3,91,7,7,1.1,7,7,0,4,0,1,40,1,4,1,3 +65730,7,2,2,52,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,16181.169973,16457.814273,2,100,14,14,4.86,3,3,0,0,0,2,52,1,5,1,3 +65731,7,2,1,17,NA,2,2,1,17,208,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,18206.126374,18306.74388,2,93,4,4,0.84,3,3,0,1,0,2,46,2,3,1,2 +65732,7,2,1,2,NA,1,1,2,2,27,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10803.555682,10625.559962,2,94,6,6,1.32,4,4,2,0,0,1,29,1,3,1,3 +65733,7,1,2,29,NA,5,6,NA,NA,NA,2,NA,2,2,2,NA,5,1,3,1,2,2,1,2,2,NA,NA,NA,NA,12636.996393,0,3,90,12,12,NA,3,3,0,0,0,2,29,2,5,1,5 +65734,7,2,2,14,NA,4,4,2,14,170,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13841.239638,13875.328502,1,96,15,15,4.52,6,6,0,4,0,1,46,1,4,1,4 +65735,7,2,2,69,NA,2,2,1,NA,NA,2,NA,2,1,8,NA,4,2,NA,2,2,2,1,2,2,1,2,2,1,9104.567599,9484.550932,2,93,6,6,2.69,1,1,0,0,1,2,69,2,4,2,NA +65736,7,2,1,71,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,3,1,NA,1,2,1,1,2,2,1,2,1,NA,16439.475505,17615.98168,1,100,5,5,1.18,3,3,0,0,2,2,34,2,5,5,NA +65737,7,2,2,53,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,33274.645943,34015.957912,2,95,14,14,3.34,4,4,0,0,0,1,43,1,3,1,3 +65738,7,2,1,35,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,18025.279948,19114.89054,1,97,4,3,0.93,3,2,0,0,0,1,35,1,3,1,4 +65739,7,2,1,71,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,58205.324383,61609.052582,2,98,8,8,3.06,2,2,0,0,2,1,71,1,4,1,3 +65740,7,2,1,68,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,10098.443227,10212.20306,1,102,9,9,5,1,1,0,0,1,1,68,1,4,3,NA +65741,7,2,1,26,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,1,6,NA,2,2,2,2,2,2,1,2,2,2,38560.502118,39812.43256,2,102,8,8,1.09,7,7,1,3,0,2,33,2,1,6,NA +65742,7,2,1,30,NA,1,1,2,NA,NA,2,NA,2,2,3,NA,3,5,NA,2,2,2,2,2,2,2,2,2,2,34887.439952,35069.154585,2,94,15,15,5,3,3,0,0,0,1,41,2,3,1,NA +65743,7,2,2,40,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,NA,NA,NA,NA,25569.682712,26728.878308,1,97,15,15,5,4,4,0,1,0,1,40,1,4,1,4 +65744,7,1,2,80,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,54095.581484,0,2,94,77,77,NA,2,2,0,0,2,2,80,1,5,1,5 +65745,7,2,1,27,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,69082.166945,70155.790389,2,103,15,15,3.44,7,7,0,1,2,2,79,1,3,2,NA +65746,7,2,1,19,NA,3,3,1,19,234,2,NA,2,1,4,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,103364.662244,103614.262032,1,98,3,1,0.09,4,1,0,0,0,1,20,1,4,5,NA +65747,7,2,2,6,NA,4,4,2,6,77,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7646.649777,8233.445923,2,99,3,3,0.52,3,3,0,1,0,2,23,1,3,1,3 +65748,7,2,1,64,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,7907.095293,7814.315452,2,97,5,5,1.3,3,3,0,1,1,1,64,1,4,3,NA +65749,7,2,2,2,NA,2,2,2,2,25,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,9534.013652,9566.569071,2,97,12,6,0.89,7,7,3,0,0,2,26,2,1,6,NA +65750,7,2,1,14,NA,3,3,1,14,173,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,79147.85144,78921.048453,1,98,15,15,5,5,5,0,3,0,2,44,1,5,1,5 +65751,7,2,1,54,NA,1,1,2,NA,NA,2,NA,2,1,7,NA,3,1,NA,2,2,2,1,2,2,2,2,2,2,22446.308035,22366.708253,2,94,1,1,0.03,2,2,0,0,0,2,48,2,1,1,3 +65752,7,2,1,21,NA,5,6,1,NA,NA,2,NA,2,2,1,NA,4,5,NA,1,2,2,1,2,2,1,2,2,3,14385.653726,15564.966804,2,101,6,99,NA,2,1,0,0,0,1,20,2,4,5,NA +65753,7,2,2,30,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,6,2,1,2,2,1,2,2,1,2,2,1,27738.890335,33497.780693,2,101,3,3,0.3,7,7,1,2,0,2,50,1,2,4,NA +65754,7,2,2,50,NA,1,1,1,NA,NA,2,NA,2,2,6,NA,1,5,NA,2,2,2,1,2,2,1,2,2,2,28701.155283,32172.514581,3,92,13,13,NA,4,4,0,2,0,2,50,2,1,5,NA +65755,7,1,2,64,NA,1,1,NA,NA,NA,2,NA,2,2,4,NA,1,2,NA,2,2,2,NA,NA,NA,NA,NA,NA,NA,16352.915834,0,3,92,NA,NA,NA,5,5,2,1,1,2,64,2,1,2,NA +65756,7,1,1,12,NA,5,6,NA,NA,NA,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7964.334824,0,1,95,6,6,1.34,4,4,0,2,0,2,32,2,3,2,NA +65757,7,2,2,45,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,21857.756498,21879.219845,2,97,9,9,1.45,7,7,1,2,2,2,45,1,3,5,NA +65758,7,2,2,67,NA,5,6,2,NA,NA,2,NA,2,2,2,NA,2,1,NA,1,2,1,1,2,1,1,2,1,3,12403.522912,13236.989116,1,93,3,3,0.65,3,3,0,0,3,2,74,2,1,2,NA +65759,7,2,1,11,NA,3,3,2,11,134,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,53915.042746,57006.573447,1,91,14,14,2.44,7,7,2,4,0,1,33,1,5,1,5 +65760,7,2,1,41,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,37402.70356,37784.383858,2,102,14,14,3.8,4,4,2,0,0,2,41,2,4,1,5 +65761,7,2,1,31,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,67671.21344,73410.277865,3,90,15,15,5,3,3,1,0,0,1,31,1,5,1,5 +65762,7,2,2,11,NA,5,6,2,11,140,NA,NA,2,2,2,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6834.715094,7298.452383,2,90,3,1,0,5,1,1,2,0,1,44,2,5,1,5 +65763,7,2,2,68,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,1,8308.628726,8949.073879,2,95,6,6,2.69,1,1,0,0,1,2,68,1,3,2,NA +65764,7,2,2,73,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,63767.913736,65948.76781,1,94,6,6,1.91,2,2,0,0,2,1,78,1,4,1,3 +65765,7,2,2,20,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,128575.977224,134245.696628,1,102,6,4,1.42,2,1,0,0,0,2,23,1,5,5,NA +65766,7,1,2,67,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,5,4,NA,1,2,2,1,2,2,NA,NA,NA,NA,36706.470429,0,1,103,3,3,0.98,1,1,0,0,1,2,67,1,5,4,NA +65767,7,2,1,1,12,3,3,1,NA,12,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,40111.361732,44385.174851,1,98,7,7,1.48,5,5,1,1,0,1,46,1,3,1,3 +65768,7,2,2,50,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,38954.135779,39992.589933,1,91,5,5,1.3,3,3,0,1,0,2,50,1,4,2,NA +65769,7,2,1,31,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,15051.024912,14836.484643,3,90,15,15,4.2,6,6,1,0,2,1,60,1,5,1,4 +65770,7,2,1,40,NA,1,1,1,NA,NA,2,NA,2,2,3,NA,2,6,NA,2,2,2,2,2,2,2,2,2,2,37402.70356,40836.297693,2,102,7,7,1.79,4,4,0,2,0,1,40,2,2,6,NA +65771,7,2,1,55,NA,5,7,1,NA,NA,1,2,2,1,9,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,16575.817424,16910.393297,1,94,8,8,2.97,2,2,0,0,1,2,74,2,3,1,4 +65772,7,2,2,80,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,4,NA,1,2,2,1,2,2,1,2,2,NA,20131.904783,20903.590301,1,92,6,6,1.31,3,3,0,0,1,2,80,1,3,4,NA +65773,7,2,1,34,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,22937.913723,23181.846174,1,100,14,14,3.47,4,4,2,0,0,1,34,1,5,1,5 +65774,7,2,1,24,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,37911.437415,38428.199561,2,103,6,6,1.98,2,2,0,0,0,1,24,1,2,6,NA +65775,7,2,2,49,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,18494.181242,18934.264494,2,99,9,9,2.43,4,4,0,2,0,2,49,1,3,3,NA +65776,7,2,1,2,NA,4,4,1,2,30,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5853.073657,6453.970807,2,95,2,2,0.41,3,3,2,0,0,2,19,1,2,NA,NA +65777,7,2,2,11,NA,4,4,2,12,144,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6655.097829,7106.52929,2,99,15,15,4.9,7,7,1,4,0,2,53,1,5,1,5 +65778,7,2,1,11,NA,4,4,2,11,141,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13423.881856,14179.490667,2,101,13,3,0.64,5,4,0,3,1,2,62,1,1,2,NA +65779,7,2,2,2,NA,5,7,2,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8579.211947,8800.655964,1,97,9,9,2.6,4,4,1,1,0,2,45,1,4,1,4 +65780,7,2,2,7,NA,3,3,2,7,93,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,24070.467912,25563.654853,1,95,10,6,1.34,5,4,1,2,0,1,32,1,3,6,NA +65781,7,2,2,41,NA,5,6,2,NA,NA,2,NA,2,2,4,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,15091.588227,15171.391678,1,93,6,6,1.15,5,5,1,0,2,2,70,NA,NA,1,NA +65782,7,2,2,53,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,22565.644629,22012.541181,1,97,15,15,5,6,6,0,1,1,2,53,1,4,1,NA +65783,7,2,1,25,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,124820.027137,131239.54259,1,91,10,10,3.78,3,3,0,0,2,1,62,1,5,1,5 +65784,7,2,2,57,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,17622.141982,17298.28124,2,95,7,7,2.58,2,2,0,0,0,2,57,1,4,3,NA +65785,7,2,1,0,8,1,1,2,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,2,NA,2,2,2,2,NA,NA,NA,NA,6217.36354,6396.366428,3,91,7,7,1.23,6,6,2,2,0,1,36,2,1,1,1 +65786,7,2,1,8,NA,3,3,1,8,104,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,49922.147265,51884.389986,1,98,7,7,1.66,5,5,2,1,0,2,37,1,5,1,3 +65787,7,2,1,39,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,86986.68246,91060.136414,2,94,7,7,2.38,2,2,0,1,0,1,39,1,4,3,NA +65788,7,2,2,5,NA,5,6,1,5,62,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7143.995395,7265.801592,3,91,15,15,5,4,4,1,1,0,1,40,2,5,1,5 +65789,7,2,1,5,NA,4,4,2,5,70,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7430.518669,8193.361877,2,99,1,1,0.07,4,4,1,1,0,2,24,1,2,5,NA +65790,7,2,2,5,NA,2,2,2,5,69,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11429.37307,11793.034101,2,90,2,2,0.49,3,3,2,0,0,2,26,1,4,1,NA +65791,7,2,1,24,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,19775.099106,19464.255682,1,96,15,15,5,3,3,0,0,0,1,55,1,4,1,5 +65792,7,2,1,0,6,1,1,1,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6999.189812,6930.018579,3,92,4,4,0.43,7,7,2,2,0,2,36,1,2,6,NA +65793,7,2,2,16,NA,3,3,2,16,196,NA,NA,1,1,NA,10,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,25543.162298,26253.778018,2,95,6,6,1.19,4,4,0,1,0,1,44,1,3,1,2 +65794,7,2,1,9,NA,5,6,1,9,116,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,5062.43381,5485.75338,3,91,6,6,1.22,5,5,1,2,0,2,37,1,4,1,2 +65795,7,2,1,9,NA,4,4,1,9,111,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14792.384662,15048.994189,2,102,5,3,0.63,5,4,2,1,0,1,24,1,4,6,NA +65796,7,2,1,56,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,26135.885159,28479.463721,2,101,1,1,0.1,2,2,0,0,0,1,56,1,3,6,NA +65797,7,2,2,52,NA,4,4,2,NA,NA,2,NA,2,1,5,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,19735.328357,19287.640039,1,90,8,8,4.48,1,1,0,0,0,2,52,2,4,3,NA +65798,7,2,2,26,NA,2,2,1,NA,NA,2,NA,2,2,6,NA,3,1,2,1,2,2,2,2,2,1,2,2,1,42621.881199,43251.535191,2,102,4,4,0.57,6,6,2,3,0,2,26,2,3,1,NA +65799,7,2,1,21,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,15572.117537,16108.231355,2,94,15,15,4.44,5,5,0,1,1,2,74,1,5,2,NA +65800,7,2,2,61,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,153418.292529,156457.542801,1,92,15,15,5,3,3,0,0,2,2,61,1,5,1,5 +65801,7,2,2,9,NA,4,4,2,9,109,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8579.490652,8919.477637,2,97,6,6,1,6,6,1,2,2,2,60,1,2,2,NA +65802,7,1,2,9,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7710.907339,0,2,99,6,6,0.94,7,7,0,4,0,2,32,1,3,1,3 +65803,7,2,2,15,NA,3,3,2,15,189,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,38400.791741,41869.717003,1,95,7,7,1.66,5,5,0,3,0,1,34,1,2,1,4 +65804,7,2,1,59,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,185033.990584,192737.162475,1,97,14,14,4.96,2,2,0,0,0,1,59,1,4,1,5 +65805,7,2,2,11,NA,3,3,2,11,139,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,19824.800404,20630.46787,1,101,6,6,1.21,4,4,0,2,0,2,33,1,2,6,NA +65806,7,2,1,5,NA,1,1,1,5,68,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16632.464801,17158.955649,3,91,3,3,0.39,6,6,1,1,0,1,39,2,1,6,NA +65807,7,2,1,49,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,108408.375382,108975.782069,2,98,14,14,4.16,3,3,0,0,0,1,49,1,5,1,4 +65808,7,2,1,65,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,7323.703412,7610.147862,2,100,9,9,2.46,4,4,1,1,1,2,59,1,3,1,3 +65809,7,2,1,0,8,3,3,2,NA,8,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,22795.485282,22401.400888,1,92,9,9,3.24,3,3,1,0,0,1,30,1,5,6,NA +65810,7,2,2,2,NA,3,3,1,2,32,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,44572.321124,49194.06017,1,98,8,8,2.46,3,3,1,0,0,1,29,1,4,6,NA +65811,7,2,2,11,NA,1,1,2,11,136,NA,NA,1,1,NA,5,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,13085.954443,13661.915968,2,97,4,4,0.6,6,6,2,2,0,1,35,2,2,6,NA +65812,7,2,1,30,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,14894.763298,16100.128566,2,92,6,6,1.35,3,3,1,0,0,2,32,1,5,1,5 +65813,7,2,1,11,NA,1,1,2,11,138,NA,NA,2,1,3,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,13285.093011,14158.005149,2,94,7,7,1.57,4,4,0,2,0,1,30,2,3,1,4 +65814,7,2,1,11,NA,4,4,1,11,134,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13213.679978,13442.903072,2,96,7,7,1.49,5,5,2,1,0,1,51,1,5,1,3 +65815,7,1,2,65,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,10033.449917,0,2,95,3,3,0.95,2,2,0,0,1,2,65,1,2,3,NA +65816,7,2,1,6,NA,3,3,2,6,82,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,23796.980721,24835.204126,1,92,4,4,0.61,5,5,1,2,0,1,34,1,3,6,NA +65817,7,2,2,19,NA,3,3,2,19,235,2,NA,2,1,5,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,77001.138762,79232.910414,1,98,15,15,5,3,3,0,0,0,1,56,1,5,1,5 +65818,7,2,1,17,NA,5,6,2,17,211,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,6852.192992,7202.81544,2,100,15,15,5,3,3,0,1,0,1,58,2,5,1,5 +65819,7,2,1,9,NA,1,1,1,9,108,NA,NA,1,1,NA,2,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,11159.151566,11335.739115,1,102,6,6,1.03,6,6,0,4,0,1,34,2,2,1,1 +65820,7,2,1,77,NA,5,6,2,NA,NA,2,NA,2,1,5,NA,2,2,NA,1,2,1,1,2,1,1,2,1,NA,9681.885604,10696.882276,1,93,2,2,0.74,1,1,0,0,1,1,77,2,2,2,NA +65821,7,2,2,5,NA,5,6,1,5,70,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,8171.700571,8311.029296,1,92,15,15,5,4,4,1,1,0,1,38,2,5,1,5 +65822,7,2,1,63,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,1,88617.795432,89088.673687,1,91,5,5,2.2,1,1,0,0,1,1,63,1,2,2,NA +65823,7,2,1,37,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,4,NA,1,2,2,2,2,2,1,2,2,1,46446.757775,47702.387865,1,102,1,1,0.33,2,2,0,0,0,1,37,1,2,4,NA +65824,7,2,1,57,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,104228.438447,104101.346681,2,95,10,10,5,1,1,0,0,0,1,57,1,5,5,NA +65825,7,2,2,8,NA,4,4,1,9,108,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7619.934086,8032.046596,2,103,7,7,1.55,5,5,2,2,0,2,31,1,4,3,NA +65826,7,2,1,15,NA,1,1,1,16,192,NA,NA,2,2,4,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,29234.272259,28953.402615,3,92,13,13,NA,4,4,0,2,0,2,50,2,1,5,NA +65827,7,2,1,42,NA,1,1,1,NA,NA,2,NA,2,2,6,NA,4,6,NA,1,2,2,1,2,2,1,2,2,2,37402.70356,37112.276585,2,102,15,14,5,5,1,0,3,0,1,42,2,4,6,NA +65828,7,2,2,22,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,118761.81384,123645.102237,3,91,7,4,1.74,2,1,0,0,0,1,23,NA,NA,6,NA +65829,7,2,2,3,NA,3,3,1,3,42,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,69494.442609,71683.798234,1,98,15,15,4.56,4,4,2,0,0,2,33,1,4,1,4 +65830,7,2,1,2,NA,1,1,1,3,36,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15546.999135,15568.006794,3,92,5,5,0.87,4,4,2,0,0,2,28,1,3,1,3 +65831,7,2,2,19,NA,4,4,1,19,232,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12531.903464,13043.632492,2,100,1,1,0.08,5,5,1,2,0,2,19,1,3,NA,NA +65832,7,2,2,80,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,1,2,1,2,2,1,1,2,NA,15852.523312,16085.826144,2,97,6,6,2.04,2,2,0,0,2,2,80,1,3,2,NA +65833,7,2,2,1,13,1,1,1,NA,15,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,11901.705423,12652.027961,2,102,4,4,0.65,5,5,1,0,0,2,58,2,1,4,NA +65834,7,2,1,6,NA,4,4,2,6,76,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10229.206765,10406.656985,1,96,15,15,4.52,6,6,0,4,0,1,46,1,4,1,4 +65835,7,2,1,18,NA,5,6,2,18,217,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,6666.045669,7317.485505,3,90,77,77,NA,5,5,0,2,0,1,46,2,3,1,3 +65836,7,2,2,18,NA,5,7,2,18,216,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,58352.457563,59447.870488,1,99,77,77,NA,3,3,0,0,0,1,42,1,4,6,NA +65837,7,2,1,66,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,11212.469396,11300.176858,1,100,15,99,NA,5,2,0,0,3,2,50,1,4,6,NA +65838,7,2,1,63,NA,2,2,2,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,11061.174348,11020.288023,1,95,7,7,2.65,2,2,0,0,1,1,63,1,4,1,NA +65839,7,2,1,4,NA,1,1,1,4,55,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14318.290734,14771.527769,3,91,15,14,4.03,5,4,2,0,0,1,42,2,4,1,5 +65840,7,2,1,21,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,12395.607222,12971.055335,1,102,9,9,2.39,5,5,0,1,1,1,55,2,5,1,5 +65841,7,2,1,63,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,85242.614785,86042.075041,1,93,15,15,5,1,1,0,0,1,1,63,1,5,5,NA +65842,7,2,1,0,3,1,1,1,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9064.168162,9064.335231,3,92,14,14,4.71,3,3,1,0,0,1,29,1,5,1,5 +65843,7,2,1,9,NA,1,1,2,9,109,NA,NA,1,1,NA,3,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,12477.812875,13297.681754,2,94,5,5,0.67,6,6,1,3,0,1,37,2,3,1,4 +65844,7,2,1,69,NA,2,2,2,NA,NA,2,NA,2,1,7,NA,5,1,NA,2,1,2,1,2,2,2,1,2,NA,12118.033999,12538.522644,2,91,3,3,0.66,2,2,0,0,1,1,69,2,5,1,1 +65845,7,2,1,13,NA,5,6,2,13,160,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7350.524832,7855.79983,2,90,8,8,2.59,3,3,0,1,0,2,41,2,4,1,4 +65846,7,2,2,61,NA,2,2,1,NA,NA,2,NA,2,1,7,NA,4,1,NA,2,2,2,2,2,2,2,2,2,2,7278.790659,7582.574348,2,93,15,15,5,4,4,0,0,1,1,57,2,5,1,4 +65847,7,2,1,3,NA,2,2,1,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,14004.176901,13773.448831,2,93,3,3,0.66,2,2,1,0,0,2,31,2,3,5,NA +65848,7,1,1,11,NA,5,7,NA,NA,NA,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7803.43213,0,1,93,15,15,5,3,3,0,2,0,2,40,2,5,4,NA +65849,7,2,1,74,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,17753.406962,18715.910687,1,101,4,4,1.29,2,2,0,0,2,2,74,1,3,1,3 +65850,7,2,1,58,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,25118.469449,25612.281104,3,92,5,5,1.56,2,2,0,0,1,1,58,1,3,1,2 +65851,7,2,2,20,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,50915.06085,56529.78018,3,92,4,4,0.65,4,4,2,0,0,2,20,1,3,5,NA +65852,7,2,2,29,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,5,6,2,1,2,2,1,2,2,1,2,2,1,40212.914634,41314.674899,2,92,15,10,5,2,1,0,0,0,2,29,1,5,6,NA +65853,7,2,2,14,NA,3,3,2,14,172,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,97212.131473,101229.4133,1,91,14,14,4.03,4,4,0,2,0,1,52,1,4,1,5 +65854,7,2,1,56,NA,5,7,2,NA,NA,2,NA,2,1,5,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,11690.444016,12008.407525,3,90,9,9,3.14,3,3,0,0,0,1,56,2,3,1,3 +65855,7,2,1,8,NA,3,3,2,8,107,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,23796.980721,24835.204126,1,95,5,5,1.03,4,4,0,2,0,1,33,1,3,1,3 +65856,7,2,1,63,NA,4,4,2,NA,NA,2,NA,2,1,4,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,8060.574062,8123.626407,1,93,7,7,1.61,4,4,0,0,1,2,27,2,3,5,NA +65857,7,2,2,64,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,97050.018399,96721.703127,1,99,14,14,5,1,1,0,0,1,2,64,1,5,3,NA +65858,7,2,2,5,NA,1,1,2,5,69,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,13366.393396,14209.054666,2,94,7,7,1.23,6,6,2,1,0,1,33,2,1,6,NA +65859,7,2,2,0,10,3,3,2,NA,10,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,25770.951107,25070.954843,2,91,15,15,4.34,4,4,2,0,0,1,39,1,5,1,5 +65860,7,2,2,5,NA,4,4,1,5,63,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11142.946789,11989.935044,2,96,5,5,0.67,6,6,1,2,1,1,34,1,4,1,4 +65861,7,2,1,8,NA,2,2,2,9,109,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,2,2,2,1,2,2,1,10248.861635,10307.698588,1,96,15,15,5,4,4,0,2,0,1,36,2,3,1,4 +65862,7,2,1,54,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,27227.937106,27194.736507,1,101,3,3,1.1,1,1,0,0,0,1,54,1,4,3,NA +65863,7,2,2,33,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,15817.041096,15849.338176,2,92,15,8,4.59,2,1,0,0,0,2,25,2,5,5,NA +65864,7,2,1,0,1,3,3,2,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13392.309303,13898.571164,1,99,14,14,3.44,5,5,3,0,0,1,30,1,4,1,5 +65865,7,2,2,34,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,4,1,1,1,2,2,1,2,2,NA,NA,NA,NA,39561.667842,39822.148122,2,98,12,12,NA,3,3,0,1,0,2,34,1,4,1,3 +65866,7,2,2,6,NA,4,4,1,6,79,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9209.511624,9916.240201,1,100,5,5,0.85,5,5,0,2,0,2,54,1,2,2,NA +65867,7,2,2,60,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,37934.469637,38685.959862,1,94,6,6,1.98,2,2,0,0,1,2,60,1,4,3,NA +65868,7,2,1,70,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,NA,53069.077479,57205.244401,2,90,15,15,5,2,1,0,0,2,1,67,1,5,6,NA +65869,7,2,2,66,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,1,9518.80186,10252.529496,2,100,4,4,1.16,2,2,0,0,1,2,18,1,2,NA,NA +65870,7,2,2,1,12,5,6,1,NA,13,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,4488.195848,4764.622817,2,92,99,2,0.31,7,4,3,3,1,1,61,2,1,1,3 +65871,7,2,2,6,NA,1,1,2,6,74,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,18721.371751,18903.185351,1,95,6,6,1.37,3,3,1,1,0,2,28,1,4,5,NA +65872,7,2,1,1,15,1,1,1,NA,15,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,10666.404974,11148.562293,2,96,8,8,1.33,7,7,2,1,1,1,62,2,1,1,1 +65873,7,2,2,36,NA,5,6,2,NA,NA,2,NA,2,2,2,NA,3,1,2,1,2,2,1,2,2,NA,NA,NA,NA,18018.210636,21650.053885,2,91,14,14,3.47,4,4,1,1,0,2,36,2,3,1,5 +65874,7,2,2,43,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,127315.335607,127929.014806,1,91,10,10,2.77,5,5,0,3,0,1,43,1,5,1,5 +65875,7,2,2,4,NA,1,1,1,4,58,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15457.736897,16648.051651,2,98,6,6,0.63,7,7,2,2,1,1,60,1,3,1,2 +65876,7,2,1,36,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,21288.18311,20984.737161,1,102,1,1,0,5,5,0,3,0,2,41,1,4,1,4 +65877,7,2,1,76,NA,4,4,2,NA,NA,2,NA,2,1,6,NA,4,1,NA,1,2,1,1,2,2,1,2,2,NA,10123.333237,10321.62644,1,93,2,2,0.54,2,2,0,0,2,1,76,2,4,1,1 +65878,7,2,1,29,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,4,5,NA,1,2,2,1,2,1,NA,NA,NA,NA,9177.295801,9603.338468,2,92,7,7,1.89,3,3,0,0,1,1,36,2,3,5,NA +65879,7,2,2,32,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,45655.090694,45995.96139,3,92,15,15,5,3,3,1,0,0,1,34,1,5,1,5 +65880,7,2,2,26,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,53638.260635,61764.513393,2,96,4,4,1.47,1,1,0,0,0,2,26,1,4,5,NA +65881,7,2,1,1,13,4,4,2,NA,13,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6992.24593,7710.094516,2,97,2,2,0.27,3,3,1,0,0,2,21,1,3,6,NA +65882,7,2,2,11,NA,2,2,2,11,140,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10762.400563,11222.736057,2,90,12,12,NA,4,4,0,2,0,2,38,2,4,1,4 +65883,7,2,1,79,NA,4,4,2,NA,NA,2,NA,2,1,7,NA,3,4,NA,1,2,2,1,2,2,1,2,2,NA,7199.330978,7568.243922,1,93,2,2,0.64,1,1,0,0,1,1,79,2,3,4,NA +65884,7,2,1,2,NA,5,6,1,3,36,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6672.795321,7206.439819,2,102,15,15,3.92,5,5,1,2,0,1,34,2,5,1,5 +65885,7,2,1,69,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,21941.544332,21717.573526,1,99,4,4,1.16,2,2,0,0,2,2,63,1,5,6,NA +65886,7,2,2,2,NA,5,7,1,2,25,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8692.478172,9353.203477,1,100,6,6,1.18,5,5,1,2,0,2,30,1,3,1,4 +65887,7,2,1,0,1,1,1,2,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,5875.721278,6205.225081,2,97,6,6,1.1,5,5,2,1,0,2,29,2,2,6,NA +65888,7,2,2,11,NA,4,4,1,11,134,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9139.784234,9759.758014,2,100,14,14,3.58,4,4,0,1,1,2,55,1,5,1,4 +65889,7,2,1,30,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,2,2,2,1,2,2,1,2,2,1,37080.526463,37488.446325,1,103,6,6,1.57,3,3,0,1,0,2,50,2,3,4,NA +65890,7,2,1,3,NA,2,2,1,3,46,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15915.595287,17052.411707,2,96,14,14,3.36,4,4,1,1,0,2,28,1,2,6,NA +65891,7,2,1,3,NA,4,4,2,3,45,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8961.738846,9235.465849,1,93,10,10,2.91,4,4,2,0,0,2,27,1,5,1,4 +65892,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,25840.959268,28861.347345,1,101,3,3,0.86,2,2,0,0,1,2,80,1,1,2,NA +65893,7,2,2,55,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,16058.142925,16013.018639,2,95,5,5,1.18,3,3,0,1,0,2,55,1,4,5,NA +65894,7,2,1,12,NA,4,4,1,12,150,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13653.432599,13787.136512,2,96,6,6,1.62,3,3,0,2,0,2,31,1,3,5,NA +65895,7,2,2,50,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,26922.241442,27209.395492,1,90,7,7,1.55,5,5,0,3,0,1,51,2,3,1,2 +65896,7,2,2,31,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,89807.047643,92868.804281,1,94,15,1,0.44,4,1,0,0,1,1,33,1,2,5,NA +65897,7,2,1,13,NA,1,1,1,14,168,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,23389.620035,23146.524434,1,94,10,10,2.94,4,4,0,2,0,2,52,1,5,2,NA +65898,7,2,1,66,NA,4,4,2,NA,NA,2,NA,2,2,3,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,5950.975297,5997.525697,2,99,6,6,1.11,5,5,0,0,1,1,66,2,4,1,4 +65899,7,2,2,12,NA,4,4,2,12,147,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17426.123122,17678.558809,1,91,10,10,2.56,5,5,0,3,0,1,51,2,5,1,4 +65900,7,2,2,18,NA,3,3,1,18,218,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,76992.7514,81576.336255,1,100,15,15,4.07,5,5,0,2,0,2,41,1,5,1,4 +65901,7,2,1,22,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,11164.358128,11468.312676,2,93,1,1,0.09,1,1,0,0,0,1,22,1,4,5,NA +65902,7,2,2,22,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,1,1,2,2,1,2,2,1,2,2,1,18723.98095,21433.166124,2,95,7,7,1.41,5,5,2,0,0,2,53,1,3,3,NA +65903,7,2,1,2,NA,4,4,2,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4912.962876,5216.242891,2,90,6,6,1.03,6,6,3,1,0,1,45,2,2,1,2 +65904,7,2,2,4,NA,2,2,1,4,48,NA,NA,2,1,2,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13201.625134,13621.675873,2,92,15,15,5,4,4,1,1,0,2,47,1,5,1,5 +65905,7,2,1,54,NA,5,6,1,NA,NA,2,NA,2,1,3,NA,1,1,NA,1,2,1,1,2,2,1,2,1,NA,15728.666463,15671.845555,2,91,15,15,4.63,7,7,1,2,0,1,36,2,4,1,3 +65906,7,2,2,7,NA,2,2,1,7,87,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15009.847173,16312.401192,2,93,15,15,4.34,4,4,0,2,0,1,33,2,5,1,5 +65907,7,1,2,47,NA,2,2,NA,NA,NA,2,NA,2,7,77,NA,3,1,NA,2,1,2,1,2,2,NA,NA,NA,NA,23968.560941,0,2,90,99,99,NA,4,4,0,2,0,1,39,NA,NA,4,NA +65908,7,2,1,17,NA,4,4,2,17,214,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,18526.8521,18563.481203,1,97,6,6,1.41,3,3,0,1,0,2,51,1,4,5,NA +65909,7,2,1,35,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,19091.246741,19659.303383,1,91,10,10,3.78,3,3,1,0,0,1,35,2,5,1,5 +65910,7,2,1,36,NA,5,6,2,NA,NA,2,NA,2,2,4,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,13601.994691,14414.229968,2,100,15,15,5,4,4,1,1,0,1,36,2,5,1,5 +65911,7,2,2,76,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,38833.86357,44548.098777,3,92,5,5,1.59,2,2,0,0,2,1,64,1,3,1,3 +65912,7,2,1,18,NA,5,6,1,18,220,2,NA,2,2,1,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,9948.022697,10353.284725,2,101,99,99,NA,4,1,0,0,0,1,18,2,4,NA,NA +65913,7,2,2,19,NA,4,4,2,19,239,2,NA,2,1,4,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11478.437608,11446.094627,1,96,7,7,1.69,4,4,0,1,0,2,19,2,4,NA,NA +65914,7,2,2,79,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,12863.404053,17087.605763,2,90,2,2,0.87,1,1,0,0,1,2,79,1,2,2,NA +65915,7,2,1,37,NA,1,1,2,NA,NA,2,NA,2,2,4,NA,3,1,NA,2,2,2,2,2,2,1,2,2,2,30626.581617,36447.669921,2,90,3,3,0.58,4,4,0,2,0,2,36,2,3,1,3 +65916,7,2,1,9,NA,4,4,2,9,117,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,9738.268689,9808.886868,2,99,9,9,1.78,6,6,1,1,0,1,46,1,3,6,NA +65917,7,2,2,6,NA,5,7,2,7,84,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,18348.624469,20109.577944,2,90,77,77,NA,6,6,0,4,0,2,41,NA,NA,4,NA +65918,7,2,2,34,NA,5,6,1,NA,NA,2,NA,2,2,77,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,15792.287872,16329.218615,1,103,12,12,NA,2,2,0,0,0,1,34,2,5,1,5 +65919,7,2,2,73,NA,5,6,1,NA,NA,2,NA,2,2,5,NA,1,2,NA,1,2,1,1,2,2,1,2,1,NA,15825.056964,16318.16087,2,94,15,15,5,3,3,0,0,1,2,40,2,5,1,5 +65920,7,2,2,36,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,NA,NA,NA,NA,31335.13799,31552.004994,1,95,4,4,0.65,6,6,2,2,0,2,36,1,4,6,NA +65921,7,2,2,41,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,4,3,2,1,2,2,1,2,2,1,2,2,1,19711.72366,19172.260632,1,96,5,5,1.45,2,2,0,1,0,2,41,1,4,3,NA +65922,7,2,1,10,NA,4,4,2,10,121,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8861.237416,9017.822314,2,95,2,2,0.26,3,3,0,2,0,2,31,1,3,5,NA +65923,7,2,1,62,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,138075.879417,141933.339512,2,91,14,14,5,1,1,0,0,1,1,62,1,5,3,NA +65924,7,2,2,19,NA,4,4,1,19,238,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,15006.987722,14964.702287,1,98,2,1,0.21,4,1,0,0,0,2,19,1,4,NA,NA +65925,7,2,1,23,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,29738.952706,30589.306008,2,94,6,3,0.68,3,2,0,0,0,1,26,1,4,5,NA +65926,7,2,2,14,NA,4,4,1,14,170,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11791.755593,11820.79689,2,96,3,3,0.47,6,6,0,4,0,1,36,1,4,1,4 +65927,7,2,2,65,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,111378.575836,111001.787784,2,97,8,8,3.06,2,2,0,0,2,1,68,1,2,1,4 +65928,7,2,2,39,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,17884.885732,18357.680967,1,98,6,6,1.73,3,3,0,1,0,2,39,1,4,1,1 +65929,7,2,1,64,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,35869.019314,40296.63257,3,92,5,5,1.59,2,2,0,0,2,1,64,1,3,1,3 +65930,7,2,2,80,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,59902.67172,68981.485025,1,101,3,3,1.3,1,1,0,0,1,2,80,1,3,2,NA +65931,7,2,1,22,NA,5,6,2,NA,NA,2,NA,2,1,4,NA,2,5,NA,1,2,2,1,2,2,1,2,2,NA,10141.381563,10817.596093,3,90,12,12,NA,4,4,0,0,1,1,62,2,4,3,NA +65932,7,2,1,17,NA,2,2,1,17,215,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,18242.832494,18053.229058,1,102,77,77,NA,6,6,0,2,1,2,37,1,4,1,4 +65933,7,2,1,11,NA,3,3,1,11,143,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,54897.892683,57357.850008,2,98,15,15,5,3,3,0,1,0,1,56,1,5,1,5 +65934,7,2,1,3,NA,3,3,2,3,42,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,75551.990912,88526.885345,1,90,14,14,3.93,3,3,1,0,0,1,35,1,2,1,5 +65935,7,2,1,18,NA,4,4,2,18,223,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12530.944806,12773.594654,2,90,8,8,1.67,6,6,1,1,0,1,52,1,3,1,5 +65936,7,2,1,7,NA,3,3,2,7,88,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,64387.576177,71283.768751,1,95,8,8,2.7,3,3,0,1,2,1,69,1,5,1,3 +65937,7,2,2,61,NA,2,2,2,NA,NA,2,NA,2,2,6,NA,3,4,NA,2,2,2,2,2,2,2,2,2,2,9716.805546,10855.679158,2,90,12,12,NA,3,3,0,0,2,2,61,2,3,4,NA +65938,7,2,1,0,2,1,1,1,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,9064.168162,9064.335231,3,92,4,4,0.89,3,3,1,0,0,2,24,2,4,1,3 +65939,7,2,2,20,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,18097.801029,17207.598344,2,100,3,3,0.27,7,7,2,1,0,2,41,1,2,5,NA +65940,7,2,2,24,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,13851.686232,14498.558979,3,91,15,3,0.92,5,1,2,0,0,1,42,2,4,1,5 +65941,7,2,1,6,NA,2,2,1,6,74,NA,NA,2,1,3,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10212.603023,10439.995832,2,92,15,15,5,4,4,1,1,0,2,47,1,5,1,5 +65942,7,2,2,3,NA,1,1,1,3,42,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,19235.084509,19847.108514,3,92,15,8,2.62,4,3,1,1,0,1,30,1,2,6,NA +65943,7,2,1,2,NA,4,4,1,2,33,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8009.966208,8254.622305,2,96,3,3,0.54,4,4,2,1,0,2,25,1,4,2,NA +65944,7,2,2,64,NA,2,2,2,NA,NA,2,NA,2,1,9,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,9716.805546,10308.451947,2,90,9,9,5,1,1,0,0,1,2,64,2,4,3,NA +65945,7,2,2,2,NA,1,1,1,2,30,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13464.808163,14038.51136,1,101,2,2,0.26,5,5,3,0,0,2,26,1,2,1,3 +65946,7,2,1,34,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,4,NA,1,2,2,1,2,2,1,2,2,1,15415.338508,15856.841729,1,93,4,4,1.65,1,1,0,0,0,1,34,1,5,4,NA +65947,7,2,2,3,NA,5,6,1,3,36,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,5485.572703,5823.427887,2,92,5,5,0.64,7,7,1,2,1,1,66,2,1,1,3 +65948,7,2,1,5,NA,4,4,1,5,68,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9016.053035,9388.597537,2,100,3,3,0.38,5,5,2,1,0,2,28,1,2,5,NA +65949,7,1,1,48,NA,2,2,NA,NA,NA,2,NA,2,2,6,NA,2,1,NA,2,2,2,1,2,2,NA,NA,NA,NA,35393.002863,0,2,93,4,4,0.84,3,3,0,1,0,2,46,2,3,1,2 +65950,7,2,1,32,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,23471.353577,23675.625296,1,100,14,6,1.85,3,2,1,0,0,1,33,1,5,5,NA +65951,7,2,2,50,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,102085.27025,105869.935801,1,99,14,14,4.86,3,3,0,1,0,1,56,1,5,1,5 +65952,7,2,1,17,NA,2,2,1,17,212,2,NA,2,2,1,13,NA,NA,NA,2,2,2,1,2,2,2,2,2,2,24228.858782,24791.594558,2,102,6,6,1,6,6,1,3,0,1,35,2,3,1,3 +65953,7,2,2,24,NA,1,1,1,NA,NA,2,NA,2,2,5,NA,2,5,1,2,2,2,2,2,2,1,2,2,1,36169.442288,36681.102865,2,96,5,5,0.68,6,6,0,3,2,1,60,2,1,1,1 +65954,7,2,2,66,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,10192.188896,10440.656902,1,99,12,12,NA,1,1,0,0,1,2,66,1,5,1,NA +65955,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,29016.444561,32518.702589,3,91,4,4,1.16,2,2,0,0,2,1,80,1,5,1,5 +65956,7,2,1,37,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,86986.68246,89821.123051,2,94,12,12,NA,5,5,1,1,0,1,37,1,4,1,3 +65957,7,2,2,47,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,30039.01139,30195.662279,2,95,8,8,3.44,2,2,0,0,0,2,24,1,4,5,NA +65958,7,2,2,13,NA,3,3,1,13,167,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,34778.638222,37920.357213,3,91,7,7,1.1,7,7,0,4,0,1,40,1,4,1,3 +65959,7,2,1,13,NA,1,1,1,13,159,NA,NA,1,1,NA,6,NA,NA,NA,2,1,2,1,2,1,1,2,2,1,20560.901695,20875.182272,2,96,3,3,0.46,5,5,1,2,0,1,37,1,1,1,2 +65960,7,2,2,0,4,4,4,2,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4137.127382,4386.966342,2,97,3,3,0.33,6,6,2,0,0,2,32,1,2,1,3 +65961,7,2,2,0,0,3,3,1,NA,0,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,17773.146728,17119.196492,2,98,99,99,NA,7,7,1,1,1,1,19,1,3,NA,NA +65962,7,2,2,56,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,1,16966.723528,16502.38463,2,92,2,2,0.57,2,2,0,0,0,2,56,1,3,2,NA +65963,7,2,2,60,NA,5,6,1,NA,NA,2,NA,2,1,3,NA,3,2,NA,1,2,1,NA,NA,NA,1,2,1,3,7575.470578,7867.856697,2,92,12,NA,NA,7,1,0,0,2,1,53,2,3,1,3 +65964,7,2,1,13,NA,4,4,2,13,164,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18526.8521,18563.481203,1,97,7,7,1.74,4,4,0,3,0,2,32,1,4,5,NA +65965,7,2,1,6,NA,2,2,1,6,77,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,8635.515602,8675.270774,2,93,4,4,0.56,5,5,0,2,0,1,37,NA,NA,1,1 +65966,7,2,1,19,NA,4,4,2,19,230,2,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,16658.161391,16980.73087,2,91,2,2,0.26,4,4,0,1,0,1,20,1,3,5,NA +65967,7,2,2,36,NA,2,2,2,NA,NA,2,NA,2,1,7,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,35353.005268,35616.958386,2,94,8,8,2.01,4,4,1,1,0,1,44,2,4,1,4 +65968,7,2,2,8,NA,2,2,1,8,99,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12307.832776,12427.36095,2,93,14,14,3.25,4,4,0,2,0,2,46,2,5,1,4 +65969,7,2,1,14,NA,1,1,2,14,169,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,20398.562455,20202.582308,2,94,14,14,4.03,4,4,0,2,0,2,33,2,2,1,NA +65970,7,2,1,22,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,20901.316439,20413.081322,2,91,14,14,3.42,5,5,1,0,0,2,28,NA,NA,1,NA +65971,7,2,1,30,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,80069.373466,86138.346669,1,98,6,6,1.31,3,3,1,0,0,1,30,1,5,1,5 +65972,7,2,2,1,17,1,1,1,NA,18,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11512.764389,11667.597427,3,92,6,6,1.7,2,2,1,0,0,2,20,1,3,4,NA +65973,7,2,2,5,NA,4,4,2,5,66,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9287.93089,10379.213194,2,90,7,7,1.61,4,4,1,1,1,2,65,1,3,2,NA +65974,7,2,2,63,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,118611.064701,118209.809508,1,91,10,10,4.49,2,2,0,0,2,1,60,1,5,1,4 +65975,7,2,2,30,NA,3,3,2,NA,NA,2,NA,2,1,6,NA,5,4,2,2,2,2,2,2,2,1,2,2,1,19486.670926,20613.901312,2,90,5,5,1.19,3,3,1,0,1,2,60,2,1,4,NA +65976,7,2,1,13,NA,4,4,1,13,165,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13523.666124,13550.403519,2,98,3,3,0.88,2,2,0,1,0,2,38,1,4,5,NA +65977,7,2,1,3,NA,2,2,2,3,42,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,11992.176902,12455.795985,1,96,10,10,2.59,5,5,1,0,0,1,32,2,4,1,2 +65978,7,2,1,57,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,145224.318312,145047.237897,1,98,6,6,2.86,1,1,0,0,0,1,57,1,4,5,NA +65979,7,2,2,2,NA,5,7,2,2,27,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6443.362832,6553.223138,1,98,14,14,3.9,4,4,2,0,0,1,39,1,5,1,4 +65980,7,2,1,38,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,13076.210481,14300.146605,2,97,5,5,1.19,3,3,0,1,0,2,41,1,3,1,2 +65981,7,2,1,8,NA,2,2,1,8,102,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13927.458372,13742.678011,2,98,7,7,2.16,3,3,0,1,0,2,51,1,1,1,2 +65982,7,2,2,4,NA,3,3,2,4,49,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,78165.891242,86270.974005,1,101,6,6,1.28,4,4,2,0,0,1,44,1,4,1,4 +65983,7,2,1,9,NA,4,4,2,9,112,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,8017.552697,8398.795399,1,99,4,4,0.41,7,7,2,4,0,2,43,1,4,4,NA +65984,7,2,2,16,NA,5,6,2,16,196,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11225.761275,11659.847432,2,91,8,8,2.34,4,4,0,2,0,1,56,2,5,1,5 +65985,7,2,2,7,NA,5,6,1,7,93,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5139.061504,5511.809249,2,103,77,77,NA,5,5,0,2,0,2,39,2,5,1,5 +65986,7,2,1,45,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,82864.936499,86441.088971,1,99,15,15,5,4,4,0,2,0,2,44,1,5,1,5 +65987,7,2,2,29,NA,5,7,1,NA,NA,2,NA,2,1,6,NA,5,5,2,1,2,2,1,2,2,NA,NA,NA,NA,47970.616628,49304.059008,1,102,10,10,3.22,4,4,0,0,2,2,29,2,5,5,NA +65988,7,2,1,20,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,21763.209029,22385.504537,2,92,4,1,0.23,4,1,0,0,0,1,21,1,4,5,NA +65989,7,2,1,1,18,2,2,1,NA,19,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,8326.330571,8424.765655,2,93,3,3,0.37,5,5,3,0,0,1,28,2,1,6,NA +65990,7,2,1,53,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,2,1,NA,1,2,1,1,2,2,1,2,1,NA,17232.67865,17489.495288,1,100,99,99,NA,6,6,0,1,0,1,53,2,2,1,3 +65991,7,2,2,26,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,118761.81384,121363.708734,3,91,15,6,2.75,3,1,0,0,0,2,26,1,4,5,NA +65992,7,2,2,61,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,11699.431733,12601.246533,1,96,14,14,5,2,2,0,0,2,2,61,1,3,1,3 +65993,7,2,2,65,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,149765.47604,152732.36321,1,92,8,8,2.17,4,4,0,1,2,2,80,1,3,2,NA +65994,7,2,1,62,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,7903.072331,7964.892648,2,99,NA,77,NA,7,7,1,0,1,2,51,1,2,1,3 +65995,7,1,2,80,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,21756.194073,0,1,93,2,2,0.59,1,1,0,0,1,2,80,1,3,2,NA +65996,7,2,2,9,NA,3,3,1,9,109,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,20242.832328,19974.015949,2,93,6,6,2.05,2,2,0,1,0,2,30,1,4,3,NA +65997,7,2,2,17,NA,4,4,1,17,209,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13620.028009,14467.639304,2,93,9,9,2.07,5,5,0,1,0,1,55,NA,NA,5,NA +65998,7,2,2,67,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,7869.59899,8220.968168,2,100,3,3,1.1,1,1,0,0,1,2,67,1,4,5,NA +65999,7,2,1,69,NA,2,2,1,NA,NA,2,NA,2,1,9,NA,4,3,NA,2,2,2,1,2,2,1,2,2,2,9404.30514,9554.950099,2,93,6,6,1.72,2,2,0,0,2,1,69,2,4,3,NA +66000,7,2,2,54,NA,2,2,1,NA,NA,2,NA,2,1,7,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,24287.448154,24414.10513,2,92,15,10,5,2,1,0,0,1,2,54,2,5,3,NA +66001,7,2,1,62,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,100988.137931,99957.29004,1,99,15,15,5,2,2,0,0,2,1,62,1,5,1,4 +66002,7,2,1,11,NA,1,1,1,11,143,NA,NA,2,7,77,5,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,11367.678664,11216.859778,2,96,77,77,NA,7,7,3,2,0,2,33,2,2,6,NA +66003,7,2,1,24,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,25815.880139,26556.735732,2,101,4,2,0.64,2,1,0,0,0,1,24,1,4,5,NA +66004,7,2,1,2,NA,1,1,1,2,25,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,13305.770449,13463.073191,3,92,6,6,1.06,5,5,2,0,0,2,54,2,1,77,NA +66005,7,2,2,18,NA,2,2,2,18,219,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,14437.97544,15197.369043,2,90,6,6,1.21,4,4,0,0,0,2,59,2,1,6,NA +66006,7,2,2,18,NA,3,3,2,18,218,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,NA,NA,NA,1,2,2,1,36586.371708,44099.282264,1,101,1,1,0.08,6,6,0,1,0,1,51,1,2,5,NA +66007,7,2,2,9,NA,3,3,2,9,115,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,24070.467912,23750.822126,1,95,7,7,1.17,6,6,1,3,0,2,44,1,4,1,NA +66008,7,2,2,43,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,6,2,1,2,2,1,2,2,1,2,2,1,154825.466557,160454.355913,1,91,15,14,5,3,2,0,0,2,2,73,1,4,3,NA +66009,7,2,2,0,6,4,4,2,NA,7,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4581.358327,5045.31579,2,97,3,3,0.66,3,3,2,0,0,2,19,1,3,NA,NA +66010,7,2,2,40,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,6,2,1,2,2,1,2,2,1,2,2,1,27934.372045,28826.461363,1,101,6,6,1.17,4,4,0,1,0,1,41,1,3,6,NA +66011,7,2,2,12,NA,4,4,2,13,156,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10848.628906,11198.221038,1,99,10,10,2.07,7,7,2,3,1,2,35,1,5,4,NA +66012,7,2,1,2,NA,1,1,2,2,27,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11160.282155,11175.362327,2,97,8,8,2.01,4,4,2,0,0,2,24,1,4,1,1 +66013,7,2,1,23,NA,2,2,2,NA,NA,2,NA,2,2,4,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,35338.972549,35820.670014,2,90,2,2,0.25,5,5,0,1,0,2,41,2,4,1,NA +66014,7,2,2,5,NA,4,4,2,5,69,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10389.292229,10964.092156,2,95,1,1,0.09,5,5,3,1,0,2,31,1,2,1,NA +66015,7,2,1,64,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,7926.298973,8333.304577,2,96,8,8,3.06,2,2,0,0,1,1,64,2,5,1,5 +66016,7,2,2,4,NA,5,6,2,4,56,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7349.373527,7474.681451,2,91,7,7,1.56,4,4,1,1,0,2,37,2,5,1,5 +66017,7,2,2,11,NA,3,3,1,11,133,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,48532.852397,48387.04619,1,98,15,15,5,5,5,0,3,0,2,41,1,5,6,NA +66018,7,2,2,4,NA,4,4,2,4,56,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10788.880391,11608.95565,2,95,6,6,0.97,6,6,2,2,0,1,37,1,3,1,4 +66019,7,2,1,12,NA,4,4,1,12,155,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,16089.133406,15900.017206,2,102,3,3,0.76,3,3,0,1,1,2,66,1,2,3,NA +66020,7,2,2,9,NA,1,1,2,9,110,NA,NA,1,1,NA,3,NA,NA,NA,2,1,2,1,2,2,1,2,2,NA,15225.935813,15373.8033,2,94,7,7,1.79,4,4,1,1,0,2,32,1,4,1,4 +66021,7,2,1,33,NA,5,7,2,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,25461.575888,25330.616054,1,93,15,15,5,2,2,0,0,0,2,34,1,5,1,5 +66022,7,2,2,35,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,28958.579549,28751.652767,1,96,12,12,NA,5,5,1,2,0,2,35,1,5,1,4 +66023,7,2,1,2,NA,5,6,1,2,30,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10123.286306,10611.741928,1,100,10,10,3.04,4,4,2,0,0,1,30,2,5,1,5 +66024,7,2,2,11,NA,1,1,1,11,139,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15841.451259,16252.614023,3,92,15,15,3.15,7,7,0,4,0,2,35,2,3,3,NA +66025,7,2,1,8,NA,4,4,2,8,105,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9468.438225,10001.401449,2,99,6,6,1.57,3,3,0,2,0,2,31,1,3,77,NA +66026,7,2,1,65,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,65748.417123,66365.048213,2,99,15,15,5,1,1,0,0,1,1,65,1,5,3,NA +66027,7,2,2,40,NA,1,1,2,NA,NA,2,NA,2,1,7,NA,5,1,3,1,2,2,1,2,2,1,2,2,1,31235.666551,32148.463094,2,94,6,6,2.94,1,1,0,0,0,2,40,2,5,1,NA +66028,7,2,2,30,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,96499.801072,98371.919459,1,92,14,14,3.93,3,3,1,0,0,1,20,1,4,1,4 +66029,7,2,1,25,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,108410.783716,112153.23206,1,91,8,8,2.17,4,4,0,0,0,1,59,1,4,1,5 +66030,7,2,1,13,NA,1,1,1,13,165,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,29234.272259,29395.83763,3,92,10,1,0,5,1,2,1,1,2,68,1,3,1,1 +66031,7,2,2,56,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,19183.115011,19284.554221,1,92,4,4,1.75,1,1,0,0,0,2,56,1,5,5,NA +66032,7,2,1,36,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,30626.581617,32055.135325,2,90,14,14,3.45,4,4,1,1,0,2,34,2,5,6,NA +66033,7,2,2,37,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,2,1,2,2,1,2,2,1,2,2,1,64581.191728,67036.946354,2,94,99,99,NA,2,2,0,0,0,2,37,1,2,1,4 +66034,7,2,1,29,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,26847.643051,29218.940922,1,98,7,7,1.03,7,7,0,4,0,2,20,1,3,5,NA +66035,7,2,1,0,5,1,1,1,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4461.618312,4741.503802,2,103,10,10,1.63,7,7,1,4,0,1,31,NA,NA,1,4 +66036,7,2,2,70,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,62212.598767,64340.261278,1,94,9,9,3.97,2,2,0,0,2,1,74,1,4,1,4 +66037,7,2,2,14,NA,4,4,2,14,169,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11711.384457,12440.215685,1,98,10,10,3.77,3,3,0,1,0,1,48,NA,NA,1,4 +66038,7,2,2,2,NA,1,1,2,2,35,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,9955.153132,10271.907274,2,94,77,77,NA,4,4,2,0,0,1,26,2,2,1,4 +66039,7,2,1,8,NA,3,3,2,8,105,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15653.970322,16628.805574,1,91,6,6,1.07,6,6,3,1,0,2,27,1,4,6,NA +66040,7,2,2,24,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,NA,NA,NA,1,2,2,1,40149.982555,41250.018596,2,103,6,6,1.98,2,2,0,0,0,1,24,1,2,6,NA +66041,7,2,1,58,NA,1,1,1,NA,NA,1,1,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,31872.125984,32498.709833,2,96,8,8,3.67,2,2,0,0,0,1,58,1,3,3,NA +66042,7,2,1,15,NA,2,2,2,15,186,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18909.886675,20785.327762,2,90,8,8,1.72,5,5,1,2,0,1,20,2,1,1,2 +66043,7,2,2,64,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,166028.936087,173980.461474,2,101,12,12,NA,1,1,0,0,1,2,64,1,3,1,NA +66044,7,2,1,14,NA,5,6,1,15,180,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12013.02156,13498.577364,3,92,12,12,NA,5,5,0,2,0,1,47,1,3,1,3 +66045,7,2,1,55,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,22506.522055,23661.545768,1,98,4,4,0.75,4,4,0,1,0,2,48,1,2,1,3 +66046,7,2,2,0,0,1,1,1,NA,0,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9767.083234,10416.172562,3,92,8,8,2,4,4,2,0,0,1,30,1,4,1,4 +66047,7,2,2,0,1,4,4,2,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,3594.351671,3811.412689,2,99,6,6,1.11,5,5,1,2,0,2,41,1,2,5,NA +66048,7,2,2,6,NA,5,6,1,6,72,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10387.513218,11140.943027,1,92,77,77,NA,4,4,1,1,0,2,40,2,4,1,4 +66049,7,2,1,73,NA,2,2,2,NA,NA,2,NA,2,2,8,NA,5,1,NA,2,2,2,2,2,2,2,2,2,NA,12343.565567,12789.649007,3,90,10,10,3.04,4,4,0,0,2,2,80,2,1,3,NA +66050,7,2,2,80,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,10072.885959,10423.387676,2,100,2,2,0.78,1,1,0,0,1,2,80,1,4,2,NA +66051,7,2,1,40,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,30451.148148,30372.925419,2,101,4,4,0.73,5,5,1,2,0,1,40,1,5,1,5 +66052,7,2,2,43,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,2,1,2,2,1,2,2,1,2,2,1,138322.767578,145546.941919,1,101,7,7,2.31,2,2,0,1,0,2,43,1,4,3,NA +66053,7,2,2,65,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,133492.667054,133041.068157,1,95,14,14,5,2,2,0,0,2,2,65,1,4,1,4 +66054,7,2,2,33,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,95214.22557,100722.009256,1,97,15,15,5,4,4,1,1,0,2,33,1,5,1,3 +66055,7,2,1,4,NA,4,4,1,4,57,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7311.663111,7763.016267,2,93,4,4,0.56,5,5,2,1,0,1,27,1,2,6,NA +66056,7,2,2,57,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,23325.73926,22943.576186,1,101,10,10,5,1,1,0,0,0,2,57,1,3,3,NA +66057,7,2,2,48,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,24004.078396,24148.434886,2,99,2,2,0.81,1,1,0,0,0,2,48,1,2,5,NA +66058,7,2,2,74,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,64463.340883,65151.773075,1,91,8,8,3.4,2,2,0,0,2,2,74,1,4,1,2 +66059,7,2,1,60,NA,2,2,2,NA,NA,2,NA,2,1,9,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,11019.434708,11234.197915,3,91,15,15,4.47,4,4,0,1,2,2,79,1,4,3,NA +66060,7,2,2,8,NA,2,2,2,8,102,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15148.721588,15796.67129,2,91,8,1,0,3,1,0,2,0,2,33,2,4,5,NA +66061,7,2,1,34,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,6,NA,1,2,2,1,2,2,1,2,2,1,22295.761589,23482.073935,3,92,4,4,1.34,1,1,0,0,0,1,34,1,1,6,NA +66062,7,2,1,7,NA,3,3,2,8,96,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,23729.905536,29042.69522,1,101,3,3,0.61,4,4,1,2,0,1,38,1,2,4,NA +66063,7,2,1,0,0,1,1,1,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4944.997189,5222.307037,2,103,13,13,NA,5,5,2,1,0,1,32,2,2,1,2 +66064,7,2,2,3,NA,1,1,1,3,37,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,21465.084926,22148.063325,1,92,4,4,0.74,4,4,1,1,0,1,42,2,3,1,4 +66065,7,2,2,2,NA,5,6,2,2,28,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8173.816615,8894.95474,1,97,14,14,4.5,3,3,1,0,0,1,30,1,5,1,5 +66066,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,34718.816885,38024.444986,1,91,15,15,5,3,3,0,0,2,1,60,1,5,1,3 +66067,7,2,2,7,NA,4,4,2,7,95,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10994.192555,11605.838362,2,97,3,3,0.46,5,5,0,3,0,1,40,1,2,1,3 +66068,7,2,1,76,NA,5,6,1,NA,NA,2,NA,2,2,1,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,6945.351825,7467.825932,1,103,5,5,0.65,6,6,0,0,1,2,26,2,4,5,NA +66069,7,1,2,55,NA,2,2,NA,NA,NA,2,NA,2,1,7,NA,2,4,NA,2,2,2,2,2,2,NA,NA,NA,NA,24902.414229,0,1,90,77,77,NA,2,2,0,0,0,2,55,2,2,4,NA +66070,7,2,2,62,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,1,12174.606153,16326.594828,1,90,7,7,1.3,5,5,1,2,1,2,62,1,2,2,NA +66071,7,2,2,65,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,11862.436765,13289.857171,1,90,7,7,3.85,1,1,0,0,1,2,65,1,3,1,NA +66072,7,1,1,77,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,NA,NA,NA,NA,NA,NA,NA,38226.070503,0,1,99,NA,NA,NA,2,2,0,0,2,1,77,1,3,1,NA +66073,7,2,1,80,NA,1,1,1,NA,NA,2,NA,2,7,77,NA,1,2,NA,2,2,2,1,2,2,2,2,2,NA,8388.502332,8563.888023,2,92,12,12,NA,7,7,0,1,2,2,64,2,1,2,NA +66074,7,1,1,42,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,18790.641284,0,2,100,15,15,5,4,3,0,2,0,1,42,1,3,5,NA +66075,7,2,1,69,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,3,12579.986433,13271.133625,1,92,7,7,2.1,3,3,0,0,2,1,37,2,5,5,NA +66076,7,2,1,17,NA,2,2,1,17,213,2,NA,2,2,3,11,NA,NA,NA,2,2,2,1,2,2,2,2,2,2,22721.243258,23068.545411,2,102,5,5,0.59,7,7,1,3,0,1,37,2,1,6,NA +66077,7,2,1,63,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,22234.74698,22519.946154,2,94,15,15,5,2,2,0,0,1,1,63,1,5,1,4 +66078,7,2,1,3,NA,3,3,1,3,37,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,32718.806351,38337.758985,1,94,6,6,1.21,4,4,2,0,0,1,27,1,2,1,2 +66079,7,2,1,54,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,26135.885159,26946.665552,2,101,4,4,1.65,1,1,0,0,0,1,54,1,3,5,NA +66080,7,2,1,8,NA,4,4,2,8,106,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10651.061092,11315.742189,1,90,6,6,1.57,3,3,0,1,0,2,36,1,3,5,NA +66081,7,1,1,8,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14610.93355,0,2,102,14,14,3.8,4,4,0,2,0,1,47,1,4,1,4 +66082,7,2,2,9,NA,4,4,1,9,112,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,10332.067017,12551.283611,1,100,9,9,2.6,4,4,0,1,0,1,45,1,3,1,3 +66083,7,2,1,21,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,5,NA,1,2,2,1,2,2,1,2,2,1,36038.266622,37278.43838,2,101,3,3,0.3,7,7,1,2,0,2,50,1,2,4,NA +66084,7,2,2,76,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,NA,73204.401173,80916.420945,2,91,7,7,3.13,1,1,0,0,1,2,76,1,3,3,NA +66085,7,2,2,5,NA,5,7,2,5,66,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,27969.562936,30869.748923,3,91,7,7,1.57,4,4,2,0,0,2,29,2,3,1,3 +66086,7,1,2,80,NA,2,2,NA,NA,NA,2,NA,2,1,4,NA,1,2,NA,2,1,2,1,2,2,NA,NA,NA,NA,10430.111347,0,2,90,7,7,0.89,7,7,1,3,3,1,60,2,3,1,3 +66087,7,2,2,18,NA,2,2,2,18,223,2,NA,2,1,5,12,NA,NA,NA,1,2,2,2,2,1,1,2,2,1,19458.108146,21037.021471,2,91,4,4,0.94,3,3,0,1,0,2,50,2,1,4,NA +66088,7,2,1,2,NA,4,4,2,2,32,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5662.231921,5835.178913,1,99,5,5,1.13,3,3,1,1,0,2,30,1,1,4,NA +66089,7,2,1,34,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,17802.31438,18635.96967,1,102,3,3,0.92,1,1,0,0,0,1,34,1,4,5,NA +66090,7,2,2,25,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,5,1,1,2,2,1,2,2,NA,NA,NA,NA,50915.06085,51518.363256,3,92,7,7,2.1,3,3,1,1,0,2,25,1,4,5,NA +66091,7,2,1,41,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,32980.717958,33092.243754,1,95,3,3,0.76,3,3,0,0,1,1,41,1,2,1,4 +66092,7,2,2,68,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,17243.546687,17909.086027,1,92,9,9,3.64,2,2,0,0,2,1,77,1,5,1,4 +66093,7,2,2,41,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,29010.447112,32633.46257,1,100,5,5,2.15,1,1,0,0,0,2,41,1,4,5,NA +66094,7,2,1,25,NA,5,6,1,NA,NA,2,NA,2,2,1,NA,5,5,NA,1,2,2,1,2,2,1,2,2,3,14385.653726,15564.966804,2,101,8,6,2.8,2,1,0,0,0,1,24,2,5,5,NA +66095,7,2,2,72,NA,3,3,2,NA,NA,2,NA,2,1,9,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,64368.917314,67563.498341,1,90,8,8,3.3,2,2,0,0,2,1,77,2,2,1,5 +66096,7,2,2,26,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,34906.069211,35828.732314,1,103,1,1,0.03,3,3,0,0,0,1,50,1,2,3,NA +66097,7,2,2,11,NA,5,7,2,11,134,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,16195.492817,16951.263709,3,91,5,5,0.65,7,7,0,4,0,2,39,1,3,4,NA +66098,7,2,1,29,NA,4,4,2,NA,NA,1,1,2,1,3,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,15920.644312,16085.139317,1,96,7,7,2.23,3,3,1,0,0,1,29,2,5,1,5 +66099,7,2,1,15,NA,5,6,1,16,192,NA,NA,2,2,2,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10346.302718,11006.15627,2,91,15,15,4.63,7,7,1,2,0,1,36,2,4,1,3 +66100,7,2,2,16,NA,4,4,2,16,203,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11711.384457,11743.959438,2,95,4,4,0.84,3,3,0,1,0,2,40,1,3,3,NA +66101,7,2,2,20,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,6,2,1,2,2,1,2,2,1,2,2,1,48943.054903,67007.111083,2,98,1,1,0.23,2,2,1,0,0,2,20,1,3,6,NA +66102,7,2,2,2,NA,4,4,1,2,33,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11846.491502,12833.518532,2,101,3,3,0.46,5,5,1,2,0,1,34,1,2,6,NA +66103,7,2,1,25,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,101419.325386,103801.228657,1,100,6,6,1.31,3,3,0,0,2,1,65,1,5,1,5 +66104,7,2,2,50,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,4,NA,1,2,2,1,2,2,1,2,2,1,32467.087681,32793.115,2,101,3,3,0.3,7,7,1,2,0,2,50,1,2,4,NA +66105,7,2,1,6,NA,3,3,2,6,75,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,68423.584566,71489.623895,1,98,15,15,3.7,5,5,2,1,0,1,34,1,5,1,5 +66106,7,2,2,2,NA,2,2,2,2,30,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7660.112391,8143.030995,2,99,13,13,NA,6,6,2,1,0,2,31,1,4,6,NA +66107,7,2,1,16,NA,4,4,2,16,197,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13416.172328,13756.125082,1,96,14,14,2.19,7,7,0,2,0,1,39,1,2,1,3 +66108,7,2,1,53,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,1,1,NA,1,2,1,1,2,2,1,2,1,3,20111.196953,20296.097622,1,92,4,4,0.76,4,4,0,0,0,2,53,2,1,1,1 +66109,7,2,1,32,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,15561.574634,17154.493542,1,98,6,6,0.81,6,6,0,4,0,2,34,NA,NA,1,2 +66110,7,2,1,63,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,105578.507837,104500.803223,1,99,15,15,5,2,2,0,0,2,1,63,1,5,1,NA +66111,7,2,2,26,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,26311.803433,25091.046888,1,97,15,15,5,6,6,0,1,1,2,53,1,4,1,NA +66112,7,1,2,33,NA,4,4,NA,NA,NA,2,NA,2,2,2,NA,3,5,3,1,2,1,1,2,1,NA,NA,NA,NA,29610.008111,0,2,93,1,1,0.2,2,2,1,0,0,2,33,2,3,5,NA +66113,7,2,1,40,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,105141.812429,109679.354704,1,98,15,15,5,4,4,1,1,0,1,40,1,4,1,5 +66114,7,2,2,39,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,21306.824647,21522.187676,2,98,3,3,0.38,5,5,0,4,0,2,39,1,4,5,NA +66115,7,2,2,59,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,196995.351093,202246.928022,1,91,10,10,3.51,3,3,0,0,1,1,21,1,4,5,NA +66116,7,2,1,47,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,28542.421068,28714.346279,2,101,5,5,1.36,2,2,0,0,1,1,79,1,4,2,NA +66117,7,2,2,16,NA,3,3,2,16,197,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,65698.166619,66553.178083,2,95,15,15,5,2,2,0,1,0,2,52,1,5,3,NA +66118,7,2,1,10,NA,1,1,1,10,126,NA,NA,2,2,2,4,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,13581.60325,14182.420159,1,100,99,99,NA,7,7,2,3,0,2,35,2,1,1,NA +66119,7,2,1,14,NA,3,3,1,14,175,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,59545.101745,58762.542429,1,102,8,8,1.6,7,7,0,4,0,2,39,1,4,1,4 +66120,7,2,2,3,NA,4,4,2,3,38,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8451.169331,8918.740308,2,99,13,13,NA,5,5,2,0,0,2,21,1,3,5,NA +66121,7,2,1,47,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,146181.198007,146233.940601,2,91,15,15,5,3,2,0,0,1,1,47,1,5,5,NA +66122,7,2,1,2,NA,3,3,1,2,32,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,47507.757497,52569.646909,1,101,8,8,1.85,5,5,3,0,0,2,31,1,2,1,2 +66123,7,2,2,29,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,35250.588028,36394.049804,2,95,4,4,0.79,3,3,1,0,0,1,50,1,4,6,NA +66124,7,2,2,37,NA,1,1,1,NA,NA,2,NA,2,1,5,NA,1,1,2,2,2,2,1,2,2,1,2,2,2,38218.668882,37878.487888,2,102,7,7,1.04,7,7,1,2,0,2,37,2,1,1,2 +66125,7,2,2,46,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,37411.196266,38309.127338,1,102,14,14,4.59,3,3,0,0,1,2,46,1,4,1,1 +66126,7,2,2,67,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,12751.545122,13320.887973,2,101,9,9,4.08,2,2,0,0,2,2,67,1,5,1,3 +66127,7,2,2,61,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,11696.973403,11982.125462,2,97,7,7,2.65,2,2,0,1,1,2,61,1,4,3,NA +66128,7,2,2,1,14,2,2,2,NA,15,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8230.248767,8808.52375,2,100,15,15,4.26,5,5,1,1,0,1,54,1,4,1,5 +66129,7,2,2,60,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,97050.018399,96721.703127,1,99,12,12,NA,1,1,0,0,1,2,60,1,5,3,NA +66130,7,2,2,0,1,3,3,1,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,24719.075551,24047.650564,2,91,10,10,3.4,3,3,1,0,0,2,32,1,5,1,5 +66131,7,2,2,36,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,77778.949308,78018.093799,1,101,6,6,0.97,7,7,2,1,0,1,43,1,2,1,NA +66132,7,2,1,26,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,29738.952706,30589.306008,2,94,6,3,0.68,3,2,0,0,0,1,26,1,4,5,NA +66133,7,2,1,40,NA,2,2,1,NA,NA,1,1,2,1,7,NA,3,6,NA,1,2,2,2,2,2,1,2,2,1,39096.402803,46193.238956,2,91,14,7,3.94,3,1,0,1,0,1,40,2,3,6,NA +66134,7,2,1,4,NA,1,1,2,4,56,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14505.510202,15541.607306,2,94,8,8,2.7,3,3,1,0,0,1,27,1,3,1,4 +66135,7,2,1,24,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,NA,NA,NA,1,2,2,1,12861.670836,12561.234288,2,99,5,5,0.65,6,6,2,1,0,2,53,1,4,3,NA +66136,7,2,1,27,NA,3,3,2,NA,NA,2,NA,2,2,2,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,76458.986322,98479.173389,3,90,9,9,3.64,2,2,0,0,0,1,27,2,4,1,5 +66137,7,2,1,20,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,12135.693667,13397.909622,1,90,15,15,5,5,5,0,2,0,1,47,2,5,1,5 +66138,7,2,2,36,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,16579.134475,17201.146893,3,91,15,15,5,4,4,1,1,0,1,39,2,5,1,5 +66139,7,2,1,47,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,21571.318341,25887.074025,1,102,7,7,1.8,5,4,1,0,2,1,47,1,3,5,NA +66140,7,2,2,63,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,11879.290971,12794.969668,2,96,77,77,NA,1,1,0,0,1,2,63,1,3,5,NA +66141,7,2,1,71,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,1,2,1,2,2,1,2,2,NA,69210.206708,71835.969778,1,98,14,14,4.96,2,2,0,0,2,1,71,1,5,1,5 +66142,7,2,1,21,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,27271.751091,27454.884133,2,101,6,2,0.46,3,1,0,0,0,1,21,1,4,5,NA +66143,7,2,2,2,24,2,2,1,2,24,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9611.087345,9740.345081,2,93,9,9,2.6,4,4,2,0,0,2,20,1,5,1,3 +66144,7,2,2,4,NA,1,1,1,5,60,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,19235.084509,21236.049482,3,92,7,7,1.65,4,4,1,1,0,1,27,1,3,1,3 +66145,7,2,2,5,NA,4,4,1,5,67,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13130.790087,14128.876607,2,102,5,3,0.63,5,4,2,1,0,1,24,1,4,6,NA +66146,7,2,2,6,NA,3,3,2,6,81,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,21910.300386,22800.721264,1,99,3,3,0.88,2,2,0,1,0,2,48,1,1,3,NA +66147,7,2,2,57,NA,5,6,1,NA,NA,2,NA,2,2,6,NA,5,2,NA,1,2,1,1,2,1,1,2,2,NA,13697.309651,14098.608838,1,103,2,2,0.53,2,2,0,0,0,1,29,2,4,5,NA +66148,7,2,1,0,6,4,4,1,NA,7,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7434.326058,7971.593122,1,100,8,8,1.7,5,5,2,0,0,2,26,1,3,5,NA +66149,7,2,1,18,NA,4,4,2,18,227,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,17606.165994,18260.901254,2,101,14,14,4.03,4,4,0,1,0,2,40,1,5,1,5 +66150,7,2,2,72,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,1,2,1,2,2,1,2,2,NA,17029.680467,17622.254657,1,101,6,6,1.43,4,4,0,1,2,2,72,1,2,1,NA +66151,7,2,2,74,NA,4,4,2,NA,NA,2,NA,2,1,9,NA,2,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,16291.303936,17381.577792,1,93,2,2,0.61,2,2,0,0,1,2,45,2,3,5,NA +66152,7,2,2,58,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,13093.362366,12735.028157,1,99,7,7,1.06,7,7,3,1,0,1,38,1,4,6,NA +66153,7,2,1,78,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,15176.622228,16064.120023,1,101,4,4,1.11,2,2,0,0,1,1,78,1,4,2,NA +66154,7,2,1,74,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,68074.313029,74840.450144,1,101,3,3,1.16,1,1,0,0,1,1,74,1,2,2,NA +66155,7,2,2,19,NA,4,4,1,19,230,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11078.202838,10933.134393,1,102,12,12,NA,7,7,3,2,0,2,52,1,4,5,NA +66156,7,2,2,15,NA,4,4,2,15,189,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11711.384457,11558.024533,2,95,6,6,0.86,6,6,0,4,0,2,32,1,4,6,NA +66157,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,47098.572584,50542.386793,1,95,7,7,2.72,2,2,0,0,2,1,80,1,3,1,3 +66158,7,2,1,11,NA,5,6,1,11,139,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9175.735601,9896.833095,3,91,15,15,5,4,4,1,1,0,1,40,2,5,1,5 +66159,7,2,2,6,NA,5,6,1,6,82,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9007.62445,9504.796896,2,102,8,8,1.72,5,5,0,2,1,1,63,2,5,1,5 +66160,7,2,2,36,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,3,1,2,2,1,2,2,NA,NA,NA,NA,27627.442402,28606.852107,1,99,14,14,5,2,2,0,0,1,2,64,1,3,3,NA +66161,7,2,1,80,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,14979.892428,16276.055879,1,92,3,3,0.98,2,1,0,0,1,1,53,NA,NA,5,NA +66162,7,2,2,60,NA,2,2,1,NA,NA,2,NA,2,1,5,NA,5,1,NA,2,2,2,2,2,2,2,2,2,2,10614.141896,11057.12801,2,93,15,15,5,2,2,0,0,2,1,60,2,5,1,5 +66163,7,2,1,12,NA,1,1,1,12,147,NA,NA,1,1,NA,6,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,18242.832494,18521.680571,1,102,6,6,1.03,6,6,0,4,0,1,34,2,2,1,1 +66164,7,2,2,6,NA,4,4,1,6,75,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8292.876947,8466.609309,1,102,1,1,0,5,5,0,3,0,2,41,1,4,1,4 +66165,7,2,1,24,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,26847.643051,28699.104328,1,98,5,5,1.05,3,3,1,0,0,1,24,1,3,1,3 +66166,7,2,2,2,NA,4,4,2,2,25,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7348.24433,8211.623817,2,101,2,2,0.22,4,4,1,1,0,2,41,1,2,4,NA +66167,7,2,2,23,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,11717.478547,12264.683949,1,95,5,5,0.73,6,6,1,0,1,1,62,2,3,1,NA +66168,7,2,2,8,NA,3,3,1,8,97,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,53931.048037,53769.024148,2,96,7,7,2.38,2,2,0,1,0,2,30,1,4,3,NA +66169,7,2,1,63,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,105295.506815,106646.104223,2,94,15,15,5,3,3,0,1,1,1,63,1,5,1,3 +66170,7,1,1,2,24,5,7,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,25107.382643,0,1,101,13,13,NA,3,3,1,0,0,2,20,1,2,6,NA +66171,7,2,2,6,NA,4,4,2,6,80,NA,NA,2,1,3,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9235.947079,9578.084112,1,96,9,9,2.78,4,4,0,2,0,1,54,2,5,4,NA +66172,7,2,2,20,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,53634.754806,54437.113731,1,98,3,3,0.73,3,3,0,0,0,1,52,1,4,1,3 +66173,7,2,2,32,NA,1,1,1,NA,NA,2,NA,2,1,99,NA,2,5,2,1,2,2,1,2,2,1,2,2,1,39561.667842,40925.159766,2,98,2,2,0.27,4,4,2,1,0,2,32,2,2,5,NA +66174,7,2,2,4,NA,4,4,1,5,60,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10437.988787,11231.392369,2,100,5,5,0.88,5,5,2,1,0,2,30,1,4,6,NA +66175,7,2,1,13,NA,3,3,2,13,162,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,30943.024697,32205.010072,1,98,3,3,0.5,5,5,0,3,0,2,56,1,3,3,NA +66176,7,2,1,0,5,3,3,1,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,30452.785006,32601.018115,3,92,15,15,5,4,4,2,0,0,1,38,1,5,1,5 +66177,7,2,1,44,NA,4,4,1,NA,NA,2,NA,2,2,1,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,22480.961662,23102.216297,1,98,6,6,1.57,3,3,0,0,2,1,66,2,2,1,4 +66178,7,2,1,62,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,10420.275705,10827.833191,2,96,14,14,3.06,5,5,1,1,1,2,54,1,3,6,NA +66179,7,2,2,23,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,1,NA,NA,NA,1,2,2,1,16937.04417,17660.28577,1,92,2,2,0.33,5,5,0,1,0,1,51,2,1,4,NA +66180,7,2,2,15,NA,5,6,2,15,183,NA,NA,1,1,NA,9,NA,NA,NA,1,1,1,1,2,1,1,2,2,1,7284.336217,7807.466703,3,90,2,2,0.45,3,3,0,1,0,1,55,2,1,1,3 +66181,7,2,2,11,NA,3,3,2,11,138,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,58907.362493,59749.51689,1,91,14,14,4.03,4,4,0,2,0,1,52,1,4,1,5 +66182,7,2,1,7,NA,3,3,2,7,87,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,25019.74954,25881.463934,1,101,3,3,0.44,5,5,0,3,0,1,35,1,3,1,4 +66183,7,2,2,14,NA,4,4,2,14,173,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14143.201945,13910.07431,2,97,2,2,0.33,4,4,2,1,0,2,34,1,2,5,NA +66184,7,2,1,24,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,25807.688156,25402.018879,1,100,15,15,5,4,4,0,0,0,1,54,1,5,1,5 +66185,7,2,2,2,NA,3,3,1,2,26,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,23729.271287,24041.081904,1,94,3,3,0.65,3,3,1,0,0,2,20,1,4,6,NA +66186,7,2,2,45,NA,1,1,1,NA,NA,2,NA,2,2,5,NA,2,1,NA,2,2,1,1,2,1,2,2,2,2,40337.933888,43242.784835,2,98,13,13,NA,5,5,0,2,0,1,48,2,1,1,2 +66187,7,2,1,24,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,26847.643051,28699.104328,1,98,5,3,1.07,4,1,2,0,0,1,24,1,3,6,NA +66188,7,2,1,7,NA,2,2,1,7,88,NA,NA,2,1,2,0,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,11778.213296,12552.114189,2,93,5,5,0.87,4,4,1,1,0,1,41,2,5,1,3 +66189,7,2,1,47,NA,1,1,2,NA,NA,2,NA,2,2,5,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,31640.296506,32716.968709,2,94,12,12,NA,4,4,0,2,0,1,47,2,2,1,2 +66190,7,2,2,1,18,5,7,2,NA,18,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7280.108168,7886.672866,3,91,14,14,3.17,6,6,1,3,0,1,39,1,4,1,5 +66191,7,2,2,56,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,24382.996387,23715.691726,1,92,3,3,0.98,2,2,0,0,1,1,70,1,2,1,2 +66192,7,2,1,80,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,32785.873783,35446.092694,1,94,9,9,3.8,2,2,0,0,2,1,80,1,4,1,4 +66193,7,2,2,25,NA,4,4,2,NA,NA,2,NA,2,2,1,NA,4,1,2,1,2,1,1,2,2,NA,NA,NA,NA,21640.010524,20942.104189,1,93,6,6,1.35,3,3,0,1,0,1,32,2,4,1,4 +66194,7,2,2,63,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,149804.257477,155051.140087,1,97,15,15,5,3,3,0,1,2,2,63,1,5,1,NA +66195,7,2,2,9,NA,4,4,1,9,109,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7619.934086,8032.046596,2,103,6,6,1.3,4,4,1,1,0,2,26,1,4,1,3 +66196,7,2,2,31,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,2,1,2,2,1,2,2,NA,NA,NA,NA,36053.766709,35796.14047,1,100,5,5,0.85,5,5,0,2,0,2,54,1,2,2,NA +66197,7,2,2,60,NA,2,2,1,NA,NA,2,NA,2,1,6,NA,1,1,NA,2,2,2,1,2,2,2,2,2,2,10536.096735,10975.825598,2,93,5,5,1.32,2,2,0,0,2,1,71,2,4,1,1 +66198,7,2,2,46,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,11762.034222,11824.231183,3,90,77,77,NA,7,7,1,2,0,1,41,2,3,6,NA +66199,7,2,2,58,NA,2,2,1,NA,NA,2,NA,2,2,6,NA,2,1,NA,2,2,2,2,2,2,1,2,2,1,19676.781212,20033.616894,2,103,12,12,NA,3,3,0,0,1,1,60,2,2,1,2 +66200,7,2,1,10,NA,1,1,1,10,129,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12577.115885,12876.06354,2,96,7,7,1.79,4,4,0,2,0,1,43,2,3,1,2 +66201,7,2,1,45,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,152858.509804,159455.333031,1,101,8,8,2.24,4,4,0,1,0,1,45,1,4,1,NA +66202,7,2,1,61,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,1,1,NA,1,2,1,1,2,1,1,2,1,3,5201.567667,6086.620135,2,92,99,77,NA,7,3,3,3,1,1,61,2,1,1,3 +66203,7,2,1,17,NA,5,7,2,17,214,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13748.325141,13775.506705,1,97,15,15,5,6,6,0,1,1,2,53,1,4,1,NA +66204,7,2,2,33,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,36053.766709,37031.002154,1,100,14,14,3.47,4,4,2,0,0,1,34,1,5,1,5 +66205,7,2,2,28,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,5,3,2,1,2,2,1,2,2,1,2,2,1,112991.277498,114001.49655,1,93,14,14,5,1,1,0,0,0,2,28,1,5,3,NA +66206,7,2,1,62,NA,4,4,1,NA,NA,2,NA,2,1,5,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,7973.883342,8036.257566,1,100,9,9,2.88,3,3,0,0,1,1,62,2,5,1,4 +66207,7,2,1,80,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,7663.797586,8115.960731,1,96,7,7,3.58,1,1,0,0,1,1,80,1,1,2,NA +66208,7,2,1,53,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,35958.875702,38183.099815,1,98,8,8,2.62,4,3,0,0,0,1,53,1,2,1,3 +66209,7,2,1,15,NA,4,4,1,16,192,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13731.625553,14242.275028,1,100,14,14,5,3,3,0,1,1,2,44,1,4,5,NA +66210,7,2,2,63,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,9113.905743,10210.592308,3,90,3,3,0.78,3,3,0,1,2,1,80,2,3,1,2 +66211,7,2,2,8,NA,5,7,1,9,108,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7877.267255,8558.823016,2,94,15,15,4.44,5,5,0,1,1,2,74,1,5,2,NA +66212,7,2,1,8,NA,1,1,1,8,106,NA,NA,1,1,NA,2,NA,NA,NA,2,1,2,2,2,2,1,2,2,2,16747.549238,17012.570163,2,96,4,4,0.81,4,4,1,1,0,1,36,2,1,6,NA +66213,7,2,1,18,NA,5,7,1,18,217,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,93641.872053,93270.118243,2,98,10,10,3.04,4,4,0,0,0,1,55,1,4,1,4 +66214,7,2,2,70,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,1,2,NA,30548.472436,31485.669458,1,101,7,7,1.83,3,3,0,0,2,1,67,1,1,1,2 +66215,7,2,1,47,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,4,NA,1,2,2,1,2,2,1,2,2,1,28813.038041,28739.023279,1,94,3,3,1.16,2,1,0,0,0,2,36,1,3,5,NA +66216,7,2,2,8,NA,5,6,1,8,105,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,9620.269705,11100.236566,2,91,6,6,1.26,5,5,0,2,0,2,47,2,1,1,1 +66217,7,2,2,51,NA,1,1,1,NA,NA,2,NA,2,2,7,NA,1,1,NA,2,2,1,1,2,1,2,2,2,2,28701.155283,32172.514581,2,98,7,7,2.25,3,3,0,1,0,2,51,2,1,1,1 +66218,7,2,2,43,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,4,3,3,1,2,2,1,2,2,1,2,2,1,34666.955582,39600.756419,1,97,6,6,2.24,2,1,0,0,0,2,43,1,4,3,NA +66219,7,2,2,46,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,138322.767578,143283.052066,1,101,7,7,2.64,2,2,0,0,0,1,57,1,2,1,2 +66220,7,2,1,19,NA,3,3,2,20,NA,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,56223.281913,55799.760014,1,99,8,8,2.81,3,3,0,1,0,1,19,1,4,NA,NA +66221,7,2,2,59,NA,5,6,1,NA,NA,2,NA,2,1,3,NA,1,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,11446.604914,11655.034159,2,92,3,3,0.7,3,3,0,0,0,1,58,2,1,1,1 +66222,7,2,1,47,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,16382.74577,17320.281883,2,99,7,7,1.63,4,4,0,2,0,1,53,1,3,3,NA +66223,7,2,2,9,NA,3,3,1,9,118,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,43528.185872,44344.05334,1,92,10,10,2.1,6,6,1,1,0,2,29,1,4,1,2 +66224,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,42992.537371,49508.460769,2,95,2,2,0.54,1,1,0,0,1,2,80,1,3,2,NA +66225,7,2,2,0,4,4,4,1,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4439.36229,4707.453058,2,100,14,14,3.06,5,5,1,0,0,1,50,1,5,1,5 +66226,7,1,1,2,NA,2,2,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11853.772636,0,2,96,3,3,0.54,4,4,1,1,0,1,29,1,2,1,2 +66227,7,2,1,66,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,1,1,NA,1,2,1,1,2,1,1,2,1,NA,6357.471593,6706.752466,2,92,5,5,0.64,7,7,1,2,1,1,66,2,1,1,3 +66228,7,2,1,28,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,115391.113177,120921.742093,1,102,14,8,4.41,2,1,0,0,0,1,27,1,4,5,NA +66229,7,2,1,71,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,51668.474366,53628.722404,1,99,15,15,5,2,2,0,0,2,2,68,1,3,1,5 +66230,7,2,2,64,NA,2,2,2,NA,NA,2,NA,2,1,6,NA,3,4,NA,2,2,2,2,2,2,1,2,1,2,13676.984152,14509.761798,2,91,8,8,1.85,5,5,0,2,1,1,39,2,3,1,4 +66231,7,2,1,0,4,1,1,2,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5323.166653,5657.098649,3,91,6,6,0.89,7,7,1,1,0,1,59,2,1,1,1 +66232,7,2,2,17,NA,5,7,2,17,209,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11975.458482,12291.118947,1,97,15,15,5,6,6,0,3,0,1,47,1,5,1,5 +66233,7,2,2,25,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,4,1,1,1,2,2,1,2,2,1,2,2,1,16937.04417,18839.574737,1,92,14,14,3.3,4,4,2,0,0,1,28,1,4,1,4 +66234,7,2,1,26,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,108504.032354,111983.725775,1,92,6,6,1.62,3,3,1,0,0,2,26,1,5,1,5 +66235,7,2,2,33,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,17978.142628,18308.053591,1,91,5,5,0.89,4,4,2,0,0,1,39,1,4,1,5 +66236,7,2,1,3,NA,1,1,1,3,38,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,20874.345556,20902.551716,3,92,12,12,NA,4,4,2,0,0,1,30,1,3,1,4 +66237,7,2,1,52,NA,2,2,1,NA,NA,2,NA,2,1,6,NA,2,1,NA,2,2,2,1,2,2,2,2,1,2,26554.904329,26165.252043,2,93,8,8,2.49,3,3,0,0,0,1,52,2,2,1,4 +66238,7,2,2,61,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,1,7869.59899,8538.749518,2,100,6,6,2.39,1,1,0,0,1,2,61,1,2,2,NA +66239,7,2,1,80,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,14765.705646,15876.477147,3,91,14,14,5,1,1,0,0,1,1,80,1,5,2,NA +66240,7,2,1,47,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,4,4,NA,1,2,2,1,2,2,1,2,2,1,18194.001026,18423.321012,1,92,14,14,3.69,4,4,0,2,0,1,47,2,4,4,NA +66241,7,2,2,50,NA,2,2,2,NA,NA,2,NA,2,1,6,NA,4,4,NA,2,2,2,1,2,2,1,2,2,2,18341.621382,19145.40337,2,90,5,5,1.19,3,3,0,0,0,2,50,2,4,4,NA +66242,7,2,2,14,NA,1,1,1,15,180,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,16781.078148,17378.8338,2,103,2,2,0.22,7,7,0,3,0,2,39,2,1,5,NA +66243,7,2,2,39,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,26465.930618,27183.288271,2,97,15,15,5,4,4,0,2,0,1,47,NA,NA,6,NA +66244,7,2,2,3,NA,1,1,2,3,44,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,13366.393396,14756.857003,2,94,4,4,0.81,4,4,2,0,0,1,26,2,2,1,2 +66245,7,2,1,47,NA,5,6,2,NA,NA,2,NA,2,2,7,NA,2,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,18094.847125,18029.478224,3,91,10,10,4.42,2,2,0,0,0,1,47,2,2,1,NA +66246,7,2,1,40,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,NA,NA,NA,1,2,2,1,152858.509804,163392.947883,1,95,NA,NA,NA,5,5,0,2,0,2,37,1,3,1,NA +66247,7,2,1,70,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,9850.66662,10431.854777,2,98,2,2,0.75,1,1,0,0,1,1,70,1,2,2,NA +66248,7,1,1,4,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,81508.607355,0,1,91,8,8,2.51,3,3,1,0,0,2,24,1,4,1,3 +66249,7,2,2,27,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,18801.993237,20649.846581,2,96,8,6,2.39,2,1,0,0,0,1,26,2,5,5,NA +66250,7,2,2,21,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,3,1,2,2,1,2,2,1,2,2,1,55628.505329,57174.814545,3,92,4,3,0.52,5,4,0,0,0,2,57,1,4,1,2 +66251,7,2,1,33,NA,1,1,1,NA,NA,2,NA,2,2,77,NA,1,1,NA,2,2,2,2,2,2,NA,NA,NA,NA,53303.690379,52901.390578,1,100,4,4,0.78,4,4,0,0,1,1,33,2,1,1,1 +66252,7,2,1,0,0,3,3,2,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11017.136221,11794.318892,1,101,1,1,0,2,2,1,0,0,2,32,1,3,3,NA +66253,7,2,2,38,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,77778.949308,80709.488833,1,101,9,9,2.6,4,4,0,2,0,2,38,1,4,1,4 +66254,7,2,2,64,NA,2,2,1,NA,NA,2,NA,2,1,2,NA,2,5,NA,2,2,2,2,2,2,2,2,2,2,10235.0654,10662.230581,2,93,7,7,2.31,2,2,0,0,1,2,40,2,4,5,NA +66255,7,2,1,12,NA,1,1,1,13,156,NA,NA,1,1,NA,6,NA,NA,NA,2,1,1,1,2,1,1,2,2,1,32326.52031,34735.818434,2,98,13,13,NA,5,5,0,2,0,1,48,2,1,1,2 +66256,7,2,2,49,NA,1,1,2,NA,NA,2,NA,2,2,5,NA,5,4,NA,2,2,2,1,2,2,2,2,2,2,31235.666551,31909.585756,3,92,8,8,2.01,4,4,1,0,0,2,49,2,5,4,NA +66257,7,2,1,15,NA,4,4,2,15,181,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9509.185342,11220.147089,2,99,2,2,0.2,7,7,1,2,1,1,63,1,1,2,NA +66258,7,2,1,14,NA,5,6,1,14,169,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7721.59541,8116.704638,2,96,8,8,2.7,3,3,0,1,0,1,49,2,5,1,5 +66259,7,2,1,45,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,3,1,NA,1,2,2,1,2,2,1,2,2,3,16898.996353,17358.625105,1,92,8,8,2.3,4,4,0,1,0,2,41,NA,NA,1,3 +66260,7,2,2,4,NA,5,6,2,4,55,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4938.043177,5373.703942,1,91,10,10,3.78,3,3,1,0,0,1,35,2,5,1,5 +66261,7,2,1,52,NA,3,3,2,NA,NA,2,NA,2,2,7,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,166897.201244,169896.236244,2,91,15,3,0.9,7,1,0,0,1,1,49,NA,NA,5,NA +66262,7,1,2,80,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,52209.836905,0,1,98,6,6,1.95,2,2,0,0,2,1,80,1,3,1,3 +66263,7,2,1,65,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,105401.67423,106753.633419,2,92,14,14,5,1,1,0,0,1,1,65,1,5,5,NA +66264,7,2,2,64,NA,1,1,1,NA,NA,2,NA,2,2,7,NA,1,1,NA,2,2,2,2,2,2,1,2,2,2,16352.915834,17178.789759,3,92,5,5,1.26,3,3,0,0,1,1,59,2,1,1,1 +66265,7,2,1,16,NA,4,4,2,16,194,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11462.850569,11753.30805,2,100,4,4,0.69,5,5,0,3,0,1,38,1,3,6,NA +66266,7,2,2,28,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,25052.373156,28677.21758,1,95,9,9,2.3,5,5,2,1,0,1,28,1,3,1,3 +66267,7,2,1,0,9,3,3,2,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,17196.879565,17385.815001,2,94,14,14,2.63,6,6,1,3,0,1,39,1,4,1,4 +66268,7,2,1,58,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,166897.201244,167183.296853,2,91,15,15,5,3,3,0,0,0,2,54,1,4,1,4 +66269,7,2,1,19,NA,3,3,2,19,229,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,88582.269653,92728.90632,1,91,15,15,5,3,3,0,0,0,2,57,1,3,1,3 +66270,7,2,1,76,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,5,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,12101.489198,12967.543396,1,93,13,13,NA,2,2,0,0,2,1,76,2,5,1,5 +66271,7,2,1,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,14337.499427,15385.847212,1,95,3,3,0.82,2,2,0,0,2,2,80,1,3,1,2 +66272,7,2,2,29,NA,5,6,2,NA,NA,2,NA,2,1,5,NA,4,1,3,1,2,2,1,2,2,1,2,2,1,11408.12687,12544.799584,2,90,5,5,1.08,3,3,0,1,0,2,29,2,4,1,5 +66273,7,2,2,13,NA,2,2,2,13,161,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13824.001771,14551.102227,2,90,8,8,2.7,3,3,0,1,0,2,31,1,5,4,NA +66274,7,2,1,5,NA,1,1,2,6,72,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,11776.305841,11467.607256,1,90,4,4,0.46,7,7,2,3,0,2,34,2,1,6,NA +66275,7,2,2,20,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,18626.118419,18025.412332,1,93,7,7,1.79,4,4,0,0,0,2,37,2,4,6,NA +66276,7,2,2,47,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,26595.398371,26621.513872,1,94,3,3,0.79,2,2,0,0,0,1,51,NA,NA,1,4 +66277,7,2,2,19,NA,5,7,1,19,232,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,9200.381964,9723.240452,2,101,2,1,0,4,1,0,0,0,2,19,1,4,NA,NA +66278,7,2,2,36,NA,2,2,2,NA,NA,2,NA,2,2,4,NA,1,6,2,2,2,2,1,2,2,2,2,2,2,26494.281052,25779.409691,3,90,7,7,1.48,5,5,0,1,0,1,43,2,1,6,NA +66279,7,2,1,62,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,8074.676044,8165.637965,2,92,12,12,NA,1,1,0,0,1,1,62,1,4,5,NA +66280,7,2,2,69,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,1,1,NA,1,2,1,1,2,1,1,2,1,NA,19159.496319,19898.984475,1,92,77,77,NA,4,4,0,0,2,1,59,2,5,1,5 +66281,7,2,2,51,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,175997.804296,174522.064022,1,101,7,7,2.31,2,2,0,0,0,1,44,1,3,1,2 +66282,7,2,2,1,16,5,7,1,NA,17,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7143.995395,7265.801592,3,91,15,15,5,4,4,2,0,0,1,35,1,5,1,5 +66283,7,2,2,33,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,32620.612627,33141.797376,2,98,14,14,3.36,4,4,0,2,0,1,37,1,4,1,4 +66284,7,2,1,12,NA,4,4,1,12,148,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13523.666124,13550.403519,2,98,8,8,2.43,3,3,0,2,0,2,31,1,4,1,NA +66285,7,2,1,51,NA,5,6,2,NA,NA,2,NA,2,1,5,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,17493.087649,18732.743426,1,97,15,15,4.81,5,5,0,1,1,1,51,2,5,1,5 +66286,7,2,1,11,NA,4,4,1,11,140,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8714.559478,8865.734494,2,96,3,3,0.47,6,6,0,4,0,1,36,1,4,1,4 +66287,7,2,1,47,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,15341.871992,16429.080873,1,90,15,15,5,5,5,0,2,0,1,47,2,5,1,5 +66288,7,2,2,4,NA,5,7,1,4,55,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7143.995395,7265.801592,3,91,15,15,5,4,4,2,0,0,1,35,1,5,1,5 +66289,7,2,1,41,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,116464.874823,118219.690774,2,94,7,7,3.21,1,1,0,0,0,1,41,1,5,5,NA +66290,7,2,2,63,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,162373.29329,165026.206299,2,102,9,9,4.08,2,2,0,0,2,1,70,1,5,1,5 +66291,7,2,2,33,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,26426.249254,26363.744856,1,99,8,8,4.59,1,1,0,0,0,2,33,1,5,5,NA +66292,7,2,2,9,NA,2,2,1,9,110,NA,NA,2,2,2,2,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,9897.093392,10755.962815,2,93,6,6,0.93,5,5,1,2,0,1,40,2,4,1,4 +66293,7,2,1,33,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,106709.949255,125265.093735,1,97,7,7,3.76,1,1,0,0,0,1,33,1,3,5,NA +66294,7,2,1,76,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,53149.251154,56449.488341,2,91,12,12,NA,2,2,0,0,2,1,76,1,5,1,2 +66295,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,46927.876098,52201.899738,1,91,7,7,4.02,1,1,0,0,1,2,80,1,3,2,NA +66296,7,2,1,43,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,24213.568265,24151.368594,1,99,3,3,1.1,1,1,0,0,0,1,43,1,5,3,NA +66297,7,2,1,68,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,6358.062034,6381.990744,1,99,7,7,3.03,2,2,0,0,2,1,68,1,3,1,3 +66298,7,2,2,61,NA,2,2,1,NA,NA,2,NA,2,1,6,NA,5,3,NA,2,2,2,2,2,2,1,2,2,1,8725.210615,9089.36131,2,93,8,8,3.3,2,2,0,0,1,2,61,2,5,3,NA +66299,7,2,2,22,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,3,5,2,1,2,1,1,2,1,1,2,2,3,11232.759507,11862.956868,1,103,4,4,0.82,3,3,0,0,0,1,48,2,4,1,1 +66300,7,2,2,35,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,6,2,1,2,2,1,2,2,1,2,2,1,27738.890335,29287.813784,2,101,3,3,0.59,4,3,0,2,0,1,39,1,1,6,NA +66301,7,2,1,12,NA,4,4,1,13,156,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17606.165994,18260.901254,2,101,7,7,2.16,3,3,0,1,0,2,44,1,4,6,NA +66302,7,2,2,45,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,4,NA,1,2,2,1,2,2,1,2,2,1,34922.33705,36456.366148,2,97,5,1,0,2,1,0,0,0,2,45,1,2,4,NA +66303,7,2,2,24,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,29040.300396,28103.729242,2,101,8,8,2.43,3,3,0,1,0,1,35,1,4,6,NA +66304,7,2,1,30,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,114838.671743,120356.919439,1,91,15,15,5,2,1,0,0,0,1,30,1,5,6,NA +66305,7,2,2,13,NA,4,4,2,13,158,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11711.384457,12440.215685,2,95,10,10,2.32,6,6,1,2,0,1,44,1,4,1,4 +66306,7,2,2,56,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,16058.142925,15728.179634,2,95,9,9,1.81,6,6,1,1,0,2,56,1,4,3,NA +66307,7,2,1,44,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,25454.275893,28114.898546,2,102,15,15,5,4,4,0,2,0,1,44,1,3,1,1 +66308,7,2,1,55,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,32461.799549,34082.06298,1,101,3,3,0.86,2,2,0,0,1,2,80,1,1,2,NA +66309,7,2,2,30,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,2,5,2,1,2,2,1,2,2,1,2,2,1,26546.087356,27263.66872,1,102,4,4,1.02,2,2,0,1,0,2,30,1,2,5,NA +66310,7,2,2,53,NA,5,6,2,NA,NA,2,NA,2,2,2,NA,3,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,12649.084278,13204.362319,3,90,3,3,0.75,3,3,0,0,0,1,55,2,4,1,3 +66311,7,2,1,39,NA,5,7,1,NA,NA,1,1,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,13833.910151,14953.425412,2,103,15,15,5,3,3,0,1,0,2,37,2,5,1,5 +66312,7,2,1,80,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,28280.669788,29879.976389,1,99,14,14,5,2,2,0,0,2,1,80,1,4,1,4 +66313,7,2,2,1,17,1,1,1,NA,18,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14326.094268,15816.39252,3,92,4,4,0.65,4,4,2,0,0,2,20,1,3,5,NA +66314,7,1,1,2,NA,1,1,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,13968.423539,0,2,102,3,3,0.7,3,3,1,0,0,1,28,2,2,1,2 +66315,7,2,1,2,NA,1,1,1,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13281.490378,14230.158403,1,98,8,8,1.95,4,4,1,1,1,2,59,1,3,1,1 +66316,7,2,2,0,8,3,3,1,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11902.236733,11578.945551,2,97,5,5,1.24,3,3,1,0,0,2,27,1,3,1,3 +66317,7,2,1,43,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,126435.397679,126594.17356,1,91,10,10,2.77,5,5,0,3,0,1,43,1,5,1,5 +66318,7,2,2,6,NA,4,4,2,6,77,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7746.357421,7953.594257,1,99,6,6,1.34,4,4,0,2,0,1,40,1,4,1,4 +66319,7,1,2,76,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,76025.86855,0,2,98,14,14,5,2,2,0,0,2,1,78,1,5,1,3 +66320,7,2,1,21,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,14519.343202,14452.61667,2,90,6,6,0.96,5,5,0,1,0,1,55,1,4,6,NA +66321,7,2,2,71,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,NA,56693.798097,58632.718368,1,103,12,6,2.51,3,1,0,0,1,2,71,1,5,3,NA +66322,7,1,1,56,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,17796.910402,0,2,103,8,8,4.83,1,1,0,0,0,1,56,1,5,5,NA +66323,7,2,2,49,NA,1,1,1,NA,NA,2,NA,2,2,3,NA,1,1,NA,2,2,2,2,2,2,2,2,2,2,34954.173075,37355.359293,2,98,5,5,1.07,4,4,0,1,0,1,53,2,1,1,1 +66324,7,2,1,1,13,4,4,1,NA,13,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5853.073657,6453.970807,2,95,2,2,0.41,3,3,2,0,0,2,19,1,2,NA,NA +66325,7,2,2,24,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,18670.751147,19670.682386,1,96,10,10,2.95,4,4,0,1,0,2,34,2,3,1,5 +66326,7,2,1,47,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,16429.782444,20771.252762,3,90,14,14,5,2,2,0,0,0,1,47,1,2,5,NA +66327,7,2,1,60,NA,2,2,1,NA,NA,2,NA,2,1,5,NA,5,1,NA,2,2,2,2,2,2,2,2,1,2,9404.30514,9554.950099,2,93,15,15,5,2,2,0,0,2,1,60,2,5,1,5 +66328,7,2,2,12,NA,5,6,2,12,148,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11975.458482,12291.118947,1,97,15,15,4.81,5,5,0,1,1,1,51,2,5,1,5 +66329,7,2,1,6,NA,5,7,2,6,80,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7482.593572,7851.213843,1,101,4,4,0.78,4,4,1,2,0,2,31,1,4,3,NA +66330,7,2,2,2,NA,3,3,1,2,28,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,55441.113009,56169.627907,1,92,9,9,3.04,3,3,1,0,0,1,48,1,3,1,4 +66331,7,2,2,77,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,36067.495928,36452.676481,1,95,2,2,0.83,1,1,0,0,1,2,77,1,4,2,NA +66332,7,2,1,19,NA,4,4,1,19,238,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,14848.504688,14956.646891,1,98,2,1,0.36,2,1,0,0,0,1,19,1,4,NA,NA +66333,7,2,1,6,NA,2,2,1,6,81,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10738.959181,10632.988891,2,93,9,9,3.14,3,3,0,2,0,2,34,2,5,3,NA +66334,7,2,1,37,NA,1,1,1,NA,NA,2,NA,2,2,6,NA,1,1,NA,2,2,1,1,2,2,1,2,2,2,40003.013263,42339.292617,3,91,7,7,1.42,6,6,1,3,0,1,37,2,1,1,1 +66335,7,2,1,35,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,15262.313583,15991.170182,1,98,5,5,0.74,5,5,0,3,0,1,35,1,2,6,NA +66336,7,2,1,71,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,NA,43078.255639,45597.38383,1,93,12,12,NA,1,1,0,0,1,1,71,1,5,5,NA +66337,7,2,2,9,NA,5,6,1,9,116,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,3972.173341,4164.719478,1,103,77,77,NA,6,6,0,2,2,1,70,NA,NA,1,1 +66338,7,2,2,31,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,71034.153987,76359.172033,1,98,10,10,2.2,6,6,1,3,0,2,31,1,4,6,NA +66339,7,2,1,18,NA,1,1,2,18,220,2,NA,2,2,4,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,26704.187335,28443.712885,1,95,9,9,2.46,4,4,0,0,0,1,42,2,2,1,3 +66340,7,2,1,0,10,1,1,1,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,8143.831412,8871.858164,2,102,10,10,3.04,4,4,2,0,0,2,31,2,2,1,NA +66341,7,2,1,51,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,142634.419514,148973.13954,1,100,15,15,4.63,5,5,0,0,0,1,51,1,5,1,3 +66342,7,2,2,32,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,2,1,2,2,1,2,2,1,2,2,1,29733.812317,40471.383048,1,101,1,1,0,2,2,1,0,0,2,32,1,3,3,NA +66343,7,2,2,20,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,114993.808573,116714.079488,1,98,7,1,0.27,4,1,0,0,0,2,20,1,4,5,NA +66344,7,2,2,7,NA,4,4,1,7,85,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8610.003992,8918.857984,2,93,6,6,1.15,5,5,3,1,0,1,29,1,3,5,NA +66345,7,1,2,25,NA,5,6,NA,NA,NA,2,NA,2,2,2,NA,5,1,3,1,2,2,1,2,2,NA,NA,NA,NA,16021.911789,0,1,91,9,9,2.97,3,3,1,0,0,1,31,2,5,1,5 +66346,7,2,2,17,NA,5,7,1,17,207,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,8111.892084,8425.568811,3,91,15,15,5,4,4,0,2,0,1,38,2,5,1,5 +66347,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,29265.714405,31405.602677,1,95,12,12,NA,3,3,0,0,2,2,56,1,3,5,NA +66348,7,2,2,13,NA,5,7,2,13,167,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8164.811332,8249.972742,1,93,15,15,5,5,5,1,2,0,2,40,1,5,1,5 +66349,7,2,2,24,NA,5,6,1,NA,NA,2,NA,2,1,3,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,10550.607376,12189.917123,2,100,6,6,1.62,3,3,1,0,0,1,32,1,3,1,3 +66350,7,2,1,14,NA,1,1,2,14,171,NA,NA,2,2,4,8,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,19483.203262,19562.510174,2,94,7,7,1.23,6,6,2,1,0,1,33,2,1,6,NA +66351,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,53612.939104,58717.503545,1,95,15,15,5,2,2,0,0,2,2,80,1,4,1,4 +66352,7,2,2,18,NA,2,2,1,18,224,2,NA,2,2,3,12,NA,NA,NA,2,2,2,2,2,2,1,2,2,1,12970.724558,13432.752316,2,103,5,5,0.65,6,6,1,0,1,2,61,2,1,2,NA +66353,7,2,1,5,NA,1,1,1,5,65,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,2,2,2,NA,NA,NA,NA,14716.463544,14890.443704,2,96,4,4,0.69,5,5,2,0,0,2,57,2,1,4,NA +66354,7,2,2,6,NA,1,1,2,7,84,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,20753.369981,21498.66298,1,97,6,3,0.45,7,6,2,1,0,1,29,2,2,1,1 +66355,7,2,1,62,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,3,1,NA,1,2,1,1,2,2,1,2,1,NA,7576.466116,7992.718813,1,95,5,5,0.73,6,6,1,0,1,1,62,2,3,1,NA +66356,7,1,1,0,1,4,4,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8390.245917,0,1,92,7,7,1.83,3,3,1,1,0,2,28,1,3,5,NA +66357,7,1,1,52,NA,1,1,NA,NA,NA,2,NA,2,2,7,NA,1,1,NA,2,2,1,1,2,1,NA,NA,NA,NA,26478.915067,0,1,102,99,99,NA,5,5,0,2,1,1,52,2,1,1,1 +66358,7,2,1,64,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,131818.641085,133509.443669,1,102,15,15,5,2,2,0,0,2,2,63,1,4,1,4 +66359,7,2,2,10,NA,3,3,2,10,131,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,72263.168327,73296.260667,2,91,15,15,5,3,3,0,2,0,1,44,2,5,3,NA +66360,7,2,2,6,NA,1,1,1,6,76,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10118.363218,10311.586628,1,103,7,7,0.51,7,7,3,4,0,1,54,2,1,1,1 +66361,7,2,1,4,NA,2,2,1,4,51,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16775.083123,17306.08847,2,98,6,6,1.07,5,5,3,0,0,2,24,1,3,1,3 +66362,7,2,2,55,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,4,NA,1,2,2,1,2,2,1,2,2,1,36187.441698,36468.041201,1,92,5,5,1.05,3,3,0,0,0,2,55,1,4,4,NA +66363,7,2,2,4,NA,2,2,2,4,52,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16921.080098,17459.476859,1,91,7,7,1.66,4,4,2,0,0,1,32,2,5,1,4 +66364,7,1,2,2,NA,2,2,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10806.348349,0,2,91,6,6,0.93,5,5,1,2,0,2,50,2,1,5,NA +66365,7,2,1,4,NA,3,3,2,4,49,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,23328.816247,26320.448782,1,97,6,6,1.03,6,6,2,2,0,2,38,1,5,1,4 +66366,7,2,2,26,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,1,1,2,2,1,2,2,1,2,2,1,26388.213487,25090.218308,2,96,6,2,0.64,2,1,0,0,0,2,26,1,2,5,NA +66367,7,2,2,6,NA,4,4,1,6,73,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9399.281543,9696.12347,2,96,6,6,1.32,5,5,1,3,0,2,30,1,4,3,NA +66368,7,2,1,7,NA,1,1,2,7,91,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,10591.186197,11647.778431,1,90,4,4,0.46,7,7,2,3,0,2,34,2,1,6,NA +66369,7,2,2,48,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,19943.783243,19397.969296,2,95,9,9,5,1,1,0,0,0,2,48,1,4,3,NA +66370,7,2,1,2,NA,1,1,1,2,32,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,12413.685227,13300.367814,1,102,5,5,0.98,4,4,1,1,0,2,42,2,2,6,NA +66371,7,2,1,77,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,10244.849903,10769.823368,2,99,6,6,1.98,2,2,0,0,2,1,77,1,3,1,3 +66372,7,2,1,5,NA,4,4,2,5,67,NA,NA,2,2,2,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7246.488236,7794.862746,1,96,10,10,1.8,7,7,1,1,0,1,57,2,1,1,3 +66373,7,2,2,68,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,38724.771087,39491.917359,1,94,3,3,0.86,2,2,0,0,2,1,68,1,4,1,2 +66374,7,2,2,3,NA,1,1,1,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9468.006743,10197.085534,1,103,7,7,0.51,7,7,3,4,0,1,54,2,1,1,1 +66375,7,2,1,31,NA,3,3,2,NA,NA,2,NA,2,1,4,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,59510.728426,64240.841943,1,99,77,77,NA,4,4,1,1,0,1,31,2,3,1,3 +66376,7,2,1,10,NA,3,3,2,10,121,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,23796.980721,24835.204126,1,95,5,5,1.03,4,4,0,2,0,1,33,1,3,1,3 +66377,7,2,1,43,NA,3,3,2,NA,NA,2,NA,2,1,5,NA,2,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,20650.777724,21846.156397,2,97,1,1,0.21,4,4,2,0,0,2,34,2,1,1,2 +66378,7,2,2,59,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,162969.911481,163428.386694,1,101,6,6,2.42,1,1,0,0,0,2,59,1,3,3,NA +66379,7,2,2,1,22,2,2,1,NA,22,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11346.120897,12219.822862,1,98,3,3,0.4,7,7,2,3,0,2,31,2,5,1,2 +66380,7,2,2,0,0,3,3,1,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,29555.41642,28752.625674,3,92,14,14,5,3,3,1,0,0,2,36,1,5,6,NA +66381,7,2,1,66,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,5854.547456,5900.343568,2,99,3,3,1.24,1,1,0,0,1,1,66,1,4,2,NA +66382,7,2,2,40,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,40337.933888,43255.958723,3,92,10,10,2.82,4,4,0,1,1,1,36,1,3,1,5 +66383,7,2,2,3,NA,5,6,2,3,45,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6184.163292,6565.044513,1,91,12,2,0.48,7,2,2,2,0,2,54,NA,NA,1,NA +66384,7,2,2,38,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,17246.716674,18154.82322,1,99,6,6,1.12,4,4,0,2,0,1,39,1,3,1,3 +66385,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,37453.906829,43130.398676,2,100,3,3,0.65,3,3,0,0,2,2,62,1,3,3,NA +66386,7,2,2,50,NA,2,2,2,NA,NA,2,NA,2,1,7,NA,4,4,NA,2,2,2,2,2,2,NA,NA,NA,NA,17465.336559,18230.717255,3,90,10,10,3.04,4,4,0,0,2,2,80,2,1,3,NA +66387,7,2,2,2,NA,1,1,1,2,25,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,2,2,2,NA,NA,NA,NA,11414.885224,12293.882349,1,94,5,5,0.57,7,7,2,1,0,1,58,2,1,1,1 +66388,7,2,2,7,NA,4,4,2,7,94,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7814.742747,8106.808519,2,95,1,1,0.25,3,3,1,1,0,2,26,1,2,5,NA +66389,7,2,1,55,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,145342.530024,151393.302038,1,99,12,12,NA,2,2,0,0,0,1,55,1,5,1,4 +66390,7,2,2,9,NA,1,1,1,9,115,NA,NA,1,1,NA,3,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,17053.854294,17778.314301,3,92,5,5,0.95,4,4,0,2,0,2,51,2,5,1,1 +66391,7,2,2,28,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,122655.643802,126707.897291,3,91,15,15,5,2,2,0,0,0,2,28,1,5,1,5 +66392,7,2,1,14,NA,5,6,2,14,170,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8305.829479,8595.334823,1,93,15,15,5,3,3,0,2,0,2,48,2,5,3,NA +66393,7,2,2,43,NA,5,7,1,NA,NA,2,NA,2,1,7,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,20577.778251,21052.363481,1,92,14,5,2.06,2,1,0,0,0,2,43,2,4,5,NA +66394,7,2,2,2,NA,1,1,1,2,26,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,2,2,2,NA,NA,NA,NA,7051.674614,7594.685042,2,103,8,8,1.29,7,7,3,1,0,2,53,2,2,4,NA +66395,7,2,2,41,NA,5,6,2,NA,NA,2,NA,2,2,4,NA,2,6,2,1,2,2,1,2,2,1,2,2,1,12969.776823,15634.514863,2,90,4,4,0.81,3,3,0,1,0,2,41,2,2,6,NA +66396,7,2,2,46,NA,5,6,1,NA,NA,2,NA,2,2,4,NA,1,5,NA,1,2,2,1,2,2,1,2,2,1,19299.941018,19401.997997,2,102,5,5,1.08,3,3,0,1,0,2,46,2,1,5,NA +66397,7,2,1,55,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,14699.320127,14652.436145,2,90,6,6,0.96,5,5,0,1,0,1,55,1,4,6,NA +66398,7,2,1,70,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,1,2,1,1,2,1,2,2,NA,17113.447343,18123.138698,2,101,77,77,NA,2,2,0,0,2,1,70,1,2,5,NA +66399,7,2,1,61,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,6815.198656,6994.794831,3,90,15,15,5,2,2,0,0,2,1,61,1,5,1,5 +66400,7,2,2,11,NA,5,7,2,11,133,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10699.45895,11230.540406,1,97,8,8,2.51,3,3,0,2,0,2,39,2,4,2,NA +66401,7,2,2,6,NA,1,1,1,6,73,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,14414.529053,14783.957167,2,96,1,1,0.06,5,5,2,1,0,1,27,2,3,1,4 +66402,7,2,1,60,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,121588.761604,120347.630506,1,91,15,6,2.3,3,1,0,0,2,2,73,1,4,3,NA +66403,7,2,2,5,NA,1,1,1,5,64,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,17887.570772,19748.358154,1,92,4,4,0.74,4,4,1,1,0,1,51,2,1,1,1 +66404,7,2,2,35,NA,3,3,2,NA,NA,2,NA,2,1,7,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,59095.849383,59277.549533,1,91,14,14,2.44,7,7,2,4,0,1,33,1,5,1,5 +66405,7,2,1,58,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,15601.50288,15551.741356,2,99,99,3,0.9,7,1,1,0,1,1,60,NA,NA,1,NA +66406,7,2,1,10,NA,5,6,2,10,120,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7923.925927,8546.646915,1,91,77,77,NA,4,4,0,2,0,1,50,2,5,1,5 +66407,7,2,2,9,NA,2,2,2,9,111,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,15148.721588,15796.67129,2,91,2,2,0.22,4,4,0,3,0,2,45,2,5,4,NA +66408,7,2,2,0,6,4,4,2,NA,7,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,3756.765605,4035.952682,1,99,7,7,1.06,7,7,3,1,0,1,38,1,4,6,NA +66409,7,2,2,36,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,NA,NA,NA,NA,31335.13799,31552.004994,1,95,6,6,1.09,5,5,0,3,0,1,31,1,4,1,4 +66410,7,2,1,43,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,4,NA,1,2,2,1,2,2,NA,NA,NA,NA,27356.080541,28721.124083,1,101,6,6,1.31,3,3,0,2,0,1,43,1,3,4,NA +66411,7,2,2,11,NA,4,4,2,11,141,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7814.742747,8587.431439,2,95,10,10,2.32,6,6,1,2,0,1,44,1,4,1,4 +66412,7,2,2,41,NA,2,2,1,NA,NA,2,NA,2,2,2,NA,4,1,2,2,2,2,2,2,2,NA,NA,NA,NA,32606.880052,32776.922157,2,93,6,6,0.93,5,5,1,2,0,1,40,2,4,1,4 +66413,7,2,2,4,NA,5,7,1,5,60,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11412.589323,11707.167617,3,91,6,6,1.75,3,3,1,1,1,1,63,1,5,4,NA +66414,7,1,2,4,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8937.555666,0,2,99,15,15,5,3,3,1,0,0,2,34,1,5,1,5 +66415,7,2,1,1,20,2,2,1,NA,20,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,NA,NA,NA,NA,NA,NA,NA,15546.999135,16657.487532,3,92,NA,NA,NA,4,4,1,0,1,1,67,NA,NA,77,NA +66416,7,2,2,63,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,129999.035519,131590.908764,1,98,8,8,3.3,2,2,0,0,1,1,50,NA,NA,1,3 +66417,7,2,2,5,NA,4,4,1,5,66,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12819.235788,13388.4749,1,98,5,5,1.26,3,3,1,1,0,2,27,1,5,5,NA +66418,7,2,2,26,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,4,1,3,1,2,2,1,2,2,1,2,2,1,16844.740449,17564.040518,1,94,10,10,4.76,2,2,0,0,0,1,58,1,5,1,4 +66419,7,2,2,7,NA,1,1,1,7,87,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15962.145468,16664.698857,1,92,6,6,1.12,4,4,0,2,0,1,20,1,2,1,2 +66420,7,2,1,12,NA,5,6,1,12,152,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6747.259224,7022.128717,2,94,15,15,5,5,5,0,2,1,1,47,2,5,1,5 +66421,7,2,1,73,NA,5,6,2,NA,NA,2,NA,2,1,8,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,12146.092906,13015.339209,1,96,9,9,4.23,2,2,0,0,2,2,71,2,5,1,5 +66422,7,2,2,33,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,29248.061332,30978.18811,1,102,7,7,1.57,4,4,0,2,0,2,33,1,4,1,4 +66423,7,2,1,7,NA,5,6,2,7,91,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6620.63733,7182.792631,2,100,4,4,0.44,7,7,1,2,2,1,71,2,1,1,1 +66424,7,2,2,14,NA,1,1,1,14,172,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18674.868029,19048.995585,2,92,8,8,1.42,7,7,0,4,0,2,37,1,1,6,NA +66425,7,2,1,79,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,9257.537917,9255.717695,1,99,5,5,1.69,2,2,0,0,2,1,79,1,1,1,4 +66426,7,2,2,2,NA,1,1,2,2,33,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9955.153132,10990.75621,2,94,14,14,3.58,4,4,1,0,1,1,80,1,3,2,NA +66427,7,2,1,63,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,1,3,NA,1,2,2,1,2,2,1,2,2,1,8746.76562,8644.133303,2,97,15,15,5,3,3,0,0,3,2,80,1,3,2,NA +66428,7,2,2,1,15,5,7,1,NA,16,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7483.230909,7475.326886,2,96,15,15,5,3,3,1,0,0,1,39,1,4,1,4 +66429,7,2,2,69,NA,2,2,2,NA,NA,2,NA,2,1,8,NA,4,3,NA,2,2,2,2,2,2,1,2,2,2,9716.805546,10308.451947,2,90,2,2,0.73,1,1,0,0,1,2,69,2,4,3,NA +66430,7,2,1,11,NA,1,1,1,11,142,NA,NA,1,1,NA,5,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,11036.458246,10927.552283,1,102,13,13,NA,6,6,1,2,0,2,36,2,4,6,NA +66431,7,2,2,23,NA,3,3,2,NA,NA,2,NA,2,1,6,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,85402.868381,88914.492385,2,94,15,6,2.94,2,1,0,0,0,1,29,1,4,6,NA +66432,7,2,2,9,NA,3,3,2,9,118,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17668.551726,18764.602322,2,95,6,6,0.9,6,6,1,1,0,1,49,1,1,1,1 +66433,7,2,2,11,NA,3,3,1,11,141,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,16950.724686,16668.200588,2,98,5,5,0.8,5,5,1,3,0,2,37,NA,NA,4,NA +66434,7,2,2,17,NA,2,2,2,17,210,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,17848.732433,18700.272027,2,91,7,7,1.29,6,6,2,2,0,1,33,2,3,6,NA +66435,7,2,1,3,NA,2,2,2,4,48,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15372.687224,15393.459347,1,90,6,6,1.68,3,3,1,1,0,2,36,2,4,4,NA +66436,7,2,2,74,NA,5,6,1,NA,NA,2,NA,2,2,4,NA,2,1,NA,1,2,1,1,2,2,1,2,1,NA,18266.489157,18835.667339,1,100,5,5,1.18,3,3,0,0,2,2,34,2,5,5,NA +66437,7,2,1,9,NA,5,7,1,9,110,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8439.403196,8726.876152,1,103,3,3,0.37,5,5,1,2,0,2,30,1,4,5,NA +66438,7,2,1,44,NA,2,2,1,NA,NA,2,NA,2,2,4,NA,4,3,NA,2,2,2,2,2,2,2,2,1,2,35393.002863,35146.477046,2,93,3,3,0.58,4,4,0,1,1,1,65,2,1,3,NA +66439,7,2,2,48,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,34954.173075,42301.098402,2,98,7,7,1.53,5,5,0,0,0,2,48,1,3,5,NA +66440,7,2,1,8,NA,2,2,2,8,96,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12477.812875,13297.681754,2,94,8,8,2.01,4,4,1,1,0,1,44,2,4,1,4 +66441,7,2,1,74,NA,5,6,1,NA,NA,2,NA,2,1,8,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,11550.158096,12419.035396,2,94,8,8,1.8,6,6,0,1,2,1,74,2,5,1,5 +66442,7,2,1,48,NA,3,3,2,NA,NA,2,NA,2,1,5,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,79677.823556,83116.431703,1,99,15,15,4.47,4,4,0,2,0,2,52,2,5,1,5 +66443,7,2,2,38,NA,1,1,1,NA,NA,2,NA,2,2,5,NA,1,5,2,2,2,1,2,2,1,2,2,2,2,45655.090694,60280.136423,3,92,4,4,1.12,2,2,0,1,0,2,38,2,1,5,NA +66444,7,2,2,43,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,NA,NA,NA,NA,21969.841763,21746.409123,1,96,15,15,5,1,1,0,0,0,2,43,1,5,5,NA +66445,7,2,2,11,NA,1,1,1,11,139,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17053.854294,17496.484818,2,98,8,8,2.26,4,4,0,1,0,2,43,1,3,1,2 +66446,7,2,1,4,NA,4,4,2,4,52,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7466.078788,7482.321895,1,96,3,2,0.16,7,6,1,4,0,2,32,1,2,5,NA +66447,7,2,1,27,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,16995.648055,16598.645683,2,100,5,5,0.88,5,5,2,1,0,2,30,1,4,6,NA +66448,7,2,1,44,NA,5,6,2,NA,NA,2,NA,2,2,4,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,11113.602843,11073.454175,3,90,77,77,NA,7,7,1,2,0,1,41,2,3,6,NA +66449,7,2,1,62,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,5,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,7289.557268,7804.776102,3,90,77,77,NA,2,1,0,0,1,1,62,2,5,3,NA +66450,7,2,2,7,NA,3,3,2,7,86,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,74327.830279,75742.187091,2,91,6,6,1.34,4,4,1,2,0,2,33,1,4,3,NA +66451,7,2,2,52,NA,2,2,2,NA,NA,2,NA,2,1,7,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,24902.414229,25152.803056,1,90,9,9,5,1,1,0,0,0,2,52,2,3,5,NA +66452,7,2,1,2,NA,4,4,2,2,29,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6992.24593,7205.816818,2,97,3,1,0.44,3,1,2,0,0,2,20,1,2,5,NA +66453,7,2,2,22,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,16021.911789,17903.386129,1,91,12,2,0.48,7,2,2,2,0,2,54,NA,NA,1,NA +66454,7,2,1,13,NA,4,4,1,13,167,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,19401.033367,19892.636678,2,102,15,15,5,4,4,0,2,0,1,44,1,3,1,1 +66455,7,2,2,2,NA,1,1,1,2,29,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9132.13761,9422.704955,2,103,9,9,2.6,4,4,2,0,0,2,35,1,4,1,3 +66456,7,2,2,70,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,4,NA,1,2,2,1,2,2,1,2,2,NA,12842.559946,13702.031196,2,101,7,7,2.64,2,2,0,0,1,2,70,1,3,4,NA +66457,7,2,1,70,NA,2,2,2,NA,NA,2,NA,2,1,8,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,16066.082986,17530.388953,1,90,3,3,0.79,2,2,0,0,1,1,70,2,2,1,NA +66458,7,2,2,70,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,NA,20137.117895,21220.947807,1,97,3,3,1.16,1,1,0,0,1,2,70,1,4,3,NA +66459,7,2,2,15,NA,1,1,1,15,191,NA,NA,2,2,4,9,NA,NA,NA,2,1,1,2,2,1,1,2,2,1,13963.420591,15453.171136,2,103,13,13,NA,3,3,0,1,0,1,47,2,1,1,1 +66460,7,2,1,37,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,83081.99261,85461.503598,2,92,15,15,5,2,2,0,0,0,1,37,1,5,1,5 +66461,7,2,1,0,11,5,7,1,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6751.596541,7305.608189,2,92,6,6,1.35,3,3,1,0,0,2,32,1,5,1,5 +66462,7,2,1,57,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,28017.200708,28243.226144,2,102,8,8,4.87,1,1,0,0,0,1,57,1,3,3,NA +66463,7,1,2,3,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,NA,NA,NA,NA,NA,NA,NA,10683.855206,0,1,96,NA,NA,NA,4,4,1,1,0,2,37,NA,NA,1,4 +66464,7,2,1,21,NA,1,1,1,NA,NA,2,NA,2,2,6,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,37911.437415,38922.114085,2,103,4,4,0.79,3,3,0,0,0,2,42,2,2,5,NA +66465,7,2,2,38,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,2,1,2,2,1,2,2,NA,NA,NA,NA,74517.751389,74746.868777,2,94,14,14,2.83,6,6,0,4,0,2,38,1,2,1,2 +66466,7,2,1,6,NA,1,1,1,6,75,NA,NA,1,1,NA,0,NA,NA,NA,2,1,1,1,2,2,NA,NA,NA,NA,14150.136224,14374.05449,3,91,7,7,1.42,6,6,1,3,0,1,37,2,1,1,1 +66467,7,2,2,48,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,25511.973394,27084.821435,1,98,4,4,0.75,4,4,0,1,0,2,48,1,2,1,3 +66468,7,2,1,9,NA,5,7,2,9,112,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,24259.597356,25770.339373,3,91,1,1,0.19,3,3,0,2,0,2,50,1,4,3,NA +66469,7,2,1,18,NA,3,3,2,18,217,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,26749.020961,27839.957403,1,101,1,1,0.08,3,3,1,0,0,2,19,1,2,NA,NA +66470,7,2,2,31,NA,1,1,2,NA,NA,2,NA,2,2,6,NA,3,3,3,1,2,2,1,2,2,1,2,2,1,35353.005268,35220.675513,2,94,7,7,3.21,1,1,0,0,0,2,31,2,3,3,NA +66471,7,2,1,10,NA,4,4,2,10,124,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7886.48532,7943.675078,1,99,10,10,3.13,4,4,0,2,0,1,35,1,4,1,5 +66472,7,2,1,61,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,113655.661464,115113.492348,1,103,15,15,5,2,2,0,0,1,1,61,1,4,1,5 +66473,7,2,1,56,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,144757.450849,145711.976748,1,101,15,15,5,3,3,0,0,2,1,75,1,2,1,2 +66474,7,2,2,43,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,2,1,2,2,1,2,2,1,2,2,1,33331.144292,34526.406365,1,91,1,1,0.2,2,2,0,0,0,1,44,1,2,1,2 +66475,7,2,2,61,NA,5,6,2,NA,NA,2,NA,2,1,5,NA,2,1,NA,1,2,1,1,2,1,1,2,1,3,12403.522912,12838.398002,1,93,12,12,NA,4,4,0,0,2,1,66,2,4,1,2 +66476,7,2,1,60,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,131445.986898,130104.237054,1,101,9,9,5,1,1,0,0,1,1,60,1,4,3,NA +66477,7,1,2,32,NA,2,2,NA,NA,NA,2,NA,2,7,77,NA,2,77,3,2,2,2,2,2,2,NA,NA,NA,NA,27127.983961,0,2,90,77,77,NA,2,2,0,1,0,2,32,2,2,77,NA +66478,7,2,1,14,NA,1,1,1,14,172,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,22768.423624,22944.003607,2,98,14,14,2.87,5,5,0,3,0,2,34,1,2,1,2 +66479,7,2,2,2,NA,3,3,1,2,30,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,46813.021927,48287.821192,1,91,8,8,2.17,4,4,2,0,0,2,28,1,4,1,5 +66480,7,2,2,13,NA,1,1,1,13,162,NA,NA,2,2,3,6,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,21818.047789,22992.945413,2,102,7,7,1.79,4,4,0,2,0,1,40,2,2,6,NA +66481,7,2,1,12,NA,2,2,2,12,152,NA,NA,2,2,2,6,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,14081.782012,15478.382268,2,90,3,3,0.46,5,5,0,2,2,1,75,2,1,1,2 +66482,7,2,2,9,NA,1,1,1,9,109,NA,NA,1,1,NA,3,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,16986.005478,17733.622754,2,102,6,6,1,6,6,1,3,0,1,35,2,3,1,3 +66483,7,1,2,13,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,55,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12531.903464,0,2,100,2,2,0.25,4,4,2,1,0,2,39,1,2,5,NA +66484,7,2,1,6,NA,3,3,2,6,80,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,23796.980721,25112.597396,1,95,5,5,1.19,3,3,1,1,0,1,47,1,2,3,NA +66485,7,2,2,33,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,27338.92927,27355.916385,1,96,15,15,5,3,3,0,0,1,2,62,1,4,3,NA +66486,7,2,1,1,23,2,2,2,NA,23,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,13002.944731,13931.716845,2,91,4,4,0.76,4,4,1,0,0,2,25,2,4,77,NA +66487,7,2,1,31,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,12556.207754,12615.022145,2,99,NA,77,NA,7,7,1,0,1,2,51,1,2,1,3 +66488,7,2,2,10,NA,5,7,2,10,124,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9620.269705,10273.007637,2,91,12,12,NA,4,4,0,2,0,1,40,1,5,1,5 +66489,7,2,1,4,NA,3,3,1,4,52,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,81508.607355,89259.872051,1,91,8,8,2.17,4,4,2,0,0,2,28,1,4,1,5 +66490,7,1,2,57,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,42475.69088,0,1,97,9,5,1.97,2,1,0,0,1,1,61,1,5,3,NA +66491,7,2,2,30,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,2,1,2,2,1,2,2,NA,NA,NA,NA,22138.245498,30132.880506,2,93,6,6,2.05,2,2,0,1,0,2,30,1,4,3,NA +66492,7,2,1,13,NA,2,2,2,13,157,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,1,2,NA,19186.411189,19608.692738,1,90,6,6,0.81,6,6,0,3,0,2,45,1,4,1,2 +66493,7,2,2,19,NA,4,4,2,19,238,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,16363.914542,16162.453075,1,101,13,13,NA,3,3,1,0,0,2,19,1,2,NA,NA +66494,7,2,1,47,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,32719.762791,34375.255008,1,101,6,6,1.65,2,2,0,0,0,1,47,1,4,1,2 +66495,7,2,2,80,NA,2,2,1,NA,NA,2,NA,2,2,6,NA,1,2,NA,2,2,2,2,2,2,2,2,2,NA,18241.877822,20223.807162,2,93,8,8,2.57,3,3,0,0,1,1,59,2,3,1,3 +66496,7,2,2,2,NA,5,7,2,2,25,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7734.994032,7934.647352,2,95,2,2,0.56,2,2,1,0,0,2,22,1,3,5,NA +66497,7,2,2,25,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,2,1,2,2,1,2,2,1,2,2,1,17794.144581,16918.878285,2,96,4,4,0.4,7,7,3,2,0,2,25,1,2,5,NA +66498,7,2,2,14,NA,3,3,1,14,176,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,113907.203714,124196.980527,1,94,8,8,1.67,5,5,1,2,0,1,52,1,4,1,4 +66499,7,2,1,21,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,114943.792804,135002.90259,2,101,1,1,0.37,1,1,0,0,0,1,21,1,4,5,NA +66500,7,2,1,15,NA,5,6,2,15,189,NA,NA,2,2,2,10,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7291.654281,7756.692286,3,91,4,4,0.69,5,5,0,2,0,1,45,2,4,1,1 +66501,7,2,1,0,6,1,1,1,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,7237.392208,7237.525607,1,102,6,6,1.43,4,4,2,0,0,1,39,2,3,1,3 +66502,7,2,1,20,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,25815.880139,25212.845431,2,101,2,2,0.46,1,1,0,0,0,1,20,1,4,5,NA +66503,7,2,1,50,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,16117.991297,17802.733496,1,96,15,15,5,4,4,1,1,0,1,50,1,3,1,4 +66504,7,2,1,70,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,NA,53028.045147,56320.756196,2,94,8,8,3.23,2,2,0,0,1,1,70,1,4,3,NA +66505,7,2,1,34,NA,1,1,1,NA,NA,2,NA,2,1,5,NA,3,1,NA,2,2,2,1,2,2,1,2,2,2,41155.167164,40844.556107,1,102,5,5,0.92,5,5,0,3,0,2,39,2,3,1,3 +66506,7,2,2,25,NA,3,3,2,NA,NA,2,NA,2,2,2,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,39833.117645,41470.989238,2,94,4,4,1.16,2,2,0,0,0,1,39,1,2,1,5 +66507,7,2,1,74,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,NA,53028.045147,62471.592039,2,94,8,8,4.59,1,1,0,0,1,1,74,1,3,3,NA +66508,7,2,2,13,NA,4,4,2,13,159,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,16363.914542,16149.629998,1,95,12,12,NA,2,2,0,1,0,2,41,1,4,5,NA +66509,7,2,2,70,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,51433.805604,53192.834838,1,94,9,9,5,1,1,0,0,1,2,70,1,4,2,NA +66510,7,2,1,11,NA,4,4,1,11,133,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10199.928366,10684.945227,1,100,9,9,2.22,5,5,1,2,0,2,40,2,4,1,4 +66511,7,2,2,52,NA,2,2,2,NA,NA,2,NA,2,1,4,NA,4,5,NA,2,2,2,1,2,2,2,2,2,2,27285.659216,28272.553853,1,93,4,4,0.92,3,3,0,0,1,1,60,NA,NA,1,4 +66512,7,2,2,8,NA,1,1,1,8,103,NA,NA,2,2,2,2,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,21075.336925,21477.798111,1,92,5,5,0.87,4,4,0,2,0,1,42,2,1,1,4 +66513,7,2,1,69,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,2,NA,1,2,1,1,2,1,1,2,1,3,7289.557268,7804.776102,3,90,77,77,NA,4,4,0,0,2,1,69,2,5,2,NA +66514,7,2,2,36,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,38589.695298,44311.547931,2,96,8,8,4.59,1,1,0,0,0,2,36,1,5,5,NA +66515,7,2,2,70,NA,5,6,2,NA,NA,2,NA,2,1,8,NA,5,3,NA,1,2,2,1,2,2,1,2,2,NA,14786.399759,15527.475853,1,90,15,15,5,1,1,0,0,1,2,70,2,5,3,NA +66516,7,2,1,6,NA,1,1,1,6,82,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13927.458372,14007.413517,2,98,14,14,3.91,4,4,1,1,0,1,36,2,3,1,5 +66517,7,2,1,2,NA,4,4,1,2,27,NA,NA,2,1,1,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7366.629832,7382.656579,1,98,10,10,1.89,7,7,3,2,0,1,50,1,5,1,5 +66518,7,2,2,80,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,10634.832821,11430.282078,2,95,6,6,1.65,2,2,0,0,1,2,80,1,1,2,NA +66519,7,2,2,9,NA,4,4,1,9,109,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11116.391625,11717.604707,1,92,5,5,0.95,4,4,0,2,0,2,33,1,4,5,NA +66520,7,2,2,54,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,21143.964074,22787.585902,1,100,8,8,2.36,3,3,1,0,0,2,37,1,3,4,NA +66521,7,2,2,8,NA,3,3,2,8,103,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15442.305642,15459.941839,2,94,7,7,1.62,5,5,0,3,0,1,30,1,2,1,9 +66522,7,2,2,46,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,154664.071516,157709.344695,3,92,15,15,5,3,3,0,1,0,1,45,1,5,1,5 +66523,7,2,2,66,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,1,10192.188896,10440.656902,1,99,9,9,5,1,1,0,0,1,2,66,1,5,2,NA +66524,7,2,1,51,NA,3,3,2,NA,NA,2,NA,2,2,5,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,22746.832388,23155.578286,1,90,7,7,1.55,5,5,0,3,0,1,51,2,3,1,2 +66525,7,2,1,47,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,151649.038926,156529.976221,1,101,6,6,1.98,2,2,0,0,1,1,80,1,1,2,NA +66526,7,2,1,0,7,3,3,2,NA,7,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11414.210614,12219.404134,1,93,6,6,1.16,4,4,2,0,0,2,33,1,5,1,4 +66527,7,2,2,74,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,NA,14534.533756,15040.28544,1,96,14,14,5,2,2,0,0,1,2,74,1,5,5,NA +66528,7,2,2,13,NA,4,4,2,13,163,NA,NA,2,2,2,6,NA,NA,NA,1,1,1,1,2,1,1,2,2,1,14105.705847,14983.542191,1,93,5,5,0.64,7,7,0,2,1,1,21,2,4,5,NA +66529,7,2,1,0,0,4,4,2,NA,0,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5360.999096,5443.282885,2,90,6,6,1.4,3,3,1,1,0,2,33,1,4,5,NA +66530,7,2,2,3,NA,5,6,1,3,37,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7143.995395,7774.277146,3,91,15,15,5,4,4,2,0,0,2,33,2,5,1,5 +66531,7,2,2,57,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,24217.957803,24014.890408,2,94,15,15,5,2,2,0,0,1,1,63,1,5,1,4 +66532,7,2,1,48,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,17501.079959,17489.07354,1,90,9,9,2.6,4,4,0,1,0,2,49,2,2,1,5 +66533,7,2,1,79,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,17113.447343,17448.661073,2,101,5,5,1.36,2,2,0,0,1,1,79,1,4,2,NA +66534,7,2,1,3,NA,4,4,2,3,40,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9304.437652,9588.632035,2,100,1,1,0.06,3,3,1,1,0,2,30,1,4,5,NA +66535,7,2,1,23,NA,5,6,2,NA,NA,2,NA,2,2,4,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,11743.336654,12063.054146,1,90,8,8,1.43,7,7,2,0,0,1,23,2,4,1,3 +66536,7,2,2,52,NA,2,2,2,NA,NA,2,NA,2,1,5,NA,5,1,NA,2,2,2,1,2,2,1,2,2,1,19132.515566,20057.4089,3,90,77,77,NA,2,2,0,0,1,1,60,2,5,1,5 +66537,7,2,1,15,NA,3,3,1,15,182,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,39918.077466,39803.689785,1,98,9,9,4.03,2,2,0,1,0,2,49,1,5,3,NA +66538,7,2,1,69,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,92913.469106,93784.871586,2,100,8,8,3.4,2,2,0,0,2,1,69,1,4,1,4 +66539,7,2,2,9,NA,3,3,2,9,114,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,43531.157975,45562.561553,1,91,7,7,2.05,3,3,0,1,0,2,32,1,3,1,NA +66540,7,2,2,0,4,4,4,1,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5264.07765,5655.281842,2,98,5,5,0.59,7,7,3,0,0,2,50,1,5,4,NA +66541,7,2,2,70,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,15783.902141,16840.218806,2,95,5,5,1.45,2,2,0,0,2,1,72,1,3,1,3 +66542,7,2,1,63,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,8883.099096,8952.58549,2,96,8,8,2.7,3,3,0,0,2,2,52,1,3,1,4 +66543,7,2,2,57,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,18724.594661,18534.166088,2,99,15,15,5,2,2,0,0,0,1,57,1,4,1,5 +66544,7,2,2,37,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,4,2,1,2,2,1,2,2,1,2,2,1,36053.766709,39664.262913,1,100,8,8,2.36,3,3,1,0,0,2,37,1,3,4,NA +66545,7,2,2,6,NA,4,4,2,6,80,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7814.742747,8106.808519,2,95,1,1,0.09,5,5,3,1,0,2,31,1,2,1,NA +66546,7,2,2,2,NA,2,2,2,2,35,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8867.166874,8986.419761,2,90,6,6,1.12,4,4,1,1,0,2,35,2,4,1,3 +66547,7,2,1,65,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,140586.349952,144513.945685,2,91,15,15,5,2,2,0,0,2,1,65,1,5,1,5 +66548,7,1,2,4,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,68579.013834,0,1,92,4,4,1.29,2,2,1,0,0,2,24,1,4,3,NA +66549,7,2,2,9,NA,1,1,1,9,117,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14414.529053,14932.182215,2,96,6,6,1.12,4,4,0,3,0,1,26,1,2,77,NA +66550,7,2,2,42,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,30932.175051,30363.701754,2,101,6,6,1.9,2,2,0,1,0,2,42,1,5,5,NA +66551,7,2,1,22,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,33109.285968,36756.097052,2,98,3,3,0.75,2,2,0,0,0,1,22,1,2,5,NA +66552,7,2,1,45,NA,2,2,1,NA,NA,2,NA,2,1,5,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,34825.476578,34314.466393,2,93,6,6,2.69,1,1,0,0,0,1,45,2,4,1,NA +66553,7,2,1,61,NA,1,1,1,NA,NA,2,NA,2,7,77,NA,2,1,NA,2,2,2,1,2,2,NA,NA,NA,NA,6967.511455,7138.703058,1,102,13,13,NA,7,7,3,1,2,2,62,2,1,1,2 +66554,7,2,1,60,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,167711.394252,169284.299948,1,101,3,3,0.73,2,2,0,0,1,1,60,1,3,1,5 +66555,7,2,2,1,16,4,4,2,NA,16,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6398.740074,6885.115697,1,93,6,6,0.83,6,6,3,1,0,1,37,NA,NA,1,3 +66556,7,2,1,60,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,121588.761604,120347.630506,1,91,10,10,3.51,3,3,0,0,1,1,21,1,4,5,NA +66557,7,2,1,13,NA,1,1,2,13,159,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,21399.234084,21870.218555,1,91,6,6,1.35,3,3,0,2,0,2,38,1,4,3,NA +66558,7,2,2,54,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,159097.269198,162641.73095,1,97,15,15,5,3,3,0,0,1,1,64,1,3,1,3 +66559,7,2,1,47,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,38543.316567,38089.298859,1,90,15,15,5,6,6,0,4,0,2,48,1,5,1,5 +66560,7,2,2,5,NA,2,2,2,5,70,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13366.393396,14756.857003,2,94,8,8,2.01,4,4,1,1,0,1,44,2,4,1,4 +66561,7,2,2,42,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,2,3,2,2,2,2,1,2,2,2,2,2,2,32208.300114,36103.843028,1,102,3,3,0.54,3,3,0,2,0,2,42,2,2,3,NA +66562,7,2,2,26,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,97925.559493,98801.080755,1,94,10,10,4.3,2,2,0,0,0,1,27,1,5,1,5 +66563,7,2,2,73,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,15226.654411,15756.489509,1,96,7,7,2.64,2,2,0,0,2,1,68,NA,NA,1,4 +66564,7,2,2,47,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,105873.555835,105977.518969,1,98,9,9,2.88,6,3,1,3,0,1,51,1,2,1,3 +66565,7,2,2,66,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,37934.469637,38685.959862,1,94,3,3,0.8,2,2,0,0,1,2,66,1,4,3,NA +66566,7,2,1,17,NA,5,6,2,17,204,2,NA,2,1,4,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,9099.599144,9679.941995,1,90,15,15,5,3,3,0,1,0,1,39,2,5,1,NA +66567,7,2,2,2,NA,1,1,2,2,35,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,7677.363986,8161.370187,2,90,6,6,0.96,5,5,1,1,0,1,39,2,2,1,NA +66568,7,2,2,52,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,126314.769628,126413.297707,2,95,15,15,5,2,2,0,1,0,2,52,1,5,3,NA +66569,7,2,2,62,NA,2,2,2,NA,NA,2,NA,2,1,9,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,9716.805546,12994.252166,2,90,2,2,0.64,1,1,0,0,1,2,62,2,2,3,NA +66570,7,2,2,28,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,15665.259727,17204.835995,2,93,77,77,NA,2,2,0,0,0,2,28,2,5,1,5 +66571,7,2,1,13,NA,3,3,1,14,168,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,61475.445782,62636.42019,2,92,15,15,5,5,5,0,3,0,2,46,1,5,1,5 +66572,7,1,2,2,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8474.492088,0,1,102,9,9,3.24,3,3,1,0,0,1,40,1,2,1,4 +66573,7,2,1,63,NA,1,1,2,NA,NA,2,NA,2,2,7,NA,1,1,NA,2,2,2,1,2,2,NA,NA,NA,NA,9145.939054,9651.644596,1,101,5,5,0.87,4,4,0,0,2,1,63,2,1,1,NA +66574,7,2,1,6,NA,2,2,1,6,77,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14820.807433,14905.891142,2,102,15,15,4.47,4,4,1,1,0,1,32,1,5,1,4 +66575,7,2,1,38,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,107347.639721,114331.46987,3,92,15,15,5,4,4,2,0,0,1,38,1,5,1,5 +66576,7,2,1,15,NA,4,4,2,15,180,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11252.388648,11670.840662,1,99,6,6,1.35,3,3,1,1,0,2,42,1,4,4,NA +66577,7,2,2,11,NA,4,4,1,11,137,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7868.372593,8159.849106,2,96,12,10,2.17,7,6,2,3,0,1,29,1,4,3,NA +66578,7,2,2,18,NA,2,2,1,18,223,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,16781.078148,17658.768186,2,103,12,12,NA,4,4,0,1,0,2,50,2,3,1,4 +66579,7,2,1,13,NA,5,6,2,13,162,NA,NA,2,1,3,6,NA,NA,NA,1,1,1,1,2,2,1,2,2,1,6666.045669,7317.485505,3,90,99,99,NA,4,4,0,1,0,1,40,2,3,6,NA +66580,7,2,1,1,19,4,4,2,NA,19,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7084.261593,7811.556831,1,93,3,3,0.7,3,3,1,0,0,1,23,2,4,1,2 +66581,7,2,2,17,NA,5,6,1,17,209,2,NA,2,1,5,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,7534.59005,7613.178065,1,102,15,15,5,3,3,0,1,0,2,49,1,5,1,5 +66582,7,2,1,55,NA,5,6,2,NA,NA,2,NA,2,1,9,NA,5,2,NA,1,2,2,1,2,2,1,2,2,1,15215.995952,15234.024078,1,90,10,10,5,1,1,0,0,0,1,55,2,5,2,NA +66583,7,2,1,64,NA,1,1,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,9611.684527,9576.156071,1,98,12,6,1.98,3,2,0,0,1,1,64,1,4,1,3 +66584,7,2,1,44,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,NA,NA,NA,1,2,2,1,122586.881737,126968.15893,1,90,7,7,1.89,3,3,0,0,1,2,75,1,4,3,NA +66585,7,2,1,40,NA,5,6,2,NA,NA,2,NA,2,2,4,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,15271.238172,15463.719206,3,91,15,15,5,3,3,1,0,0,1,40,2,5,1,5 +66586,7,2,1,29,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,17265.374984,16862.072044,2,93,8,8,1.67,5,5,1,1,0,2,31,1,4,5,NA +66587,7,2,1,47,NA,2,2,2,NA,NA,2,NA,2,2,3,NA,4,1,NA,2,2,2,1,2,2,2,2,2,2,36610.126289,37722.018472,1,96,8,8,2.17,4,4,0,0,2,1,80,NA,NA,1,NA +66588,7,2,2,4,NA,1,1,1,4,51,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,2,2,2,NA,NA,NA,NA,9468.006743,10197.085534,2,103,8,8,1.29,7,7,3,1,0,2,53,2,2,4,NA +66589,7,2,1,23,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,136372.590634,138491.991585,1,98,8,8,2.97,2,2,0,0,0,1,23,1,3,1,5 +66590,7,2,2,7,NA,5,6,2,7,88,NA,NA,1,1,NA,0,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,6347.955472,6765.486426,1,93,8,8,1.2,7,7,1,1,1,1,24,2,2,5,NA +66591,7,2,1,34,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,80355.847074,82974.223453,1,98,15,15,3.7,5,5,2,1,0,1,34,1,5,1,5 +66592,7,2,2,9,NA,4,4,2,9,111,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7588.605543,8103.359102,1,99,14,14,4.21,4,4,0,2,0,2,44,1,5,1,5 +66593,7,2,1,13,NA,1,1,1,13,156,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,20638.769105,20614.097145,2,92,15,15,3.37,7,7,0,4,0,1,42,2,3,1,1 +66594,7,2,1,61,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,2,2,2,2,2,2,1,2,2,1,9430.93681,9879.499027,2,98,3,3,1.19,1,1,0,0,1,1,61,1,3,3,NA +66595,7,2,1,16,NA,5,7,2,16,198,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11834.781205,12120.23702,2,90,5,5,1.43,2,2,0,1,0,2,38,2,4,5,NA +66596,7,2,2,7,NA,5,6,1,7,91,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7231.974056,7722.665474,3,91,15,15,5,4,4,1,1,0,1,39,2,5,1,5 +66597,7,2,2,54,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,4,NA,1,2,2,1,2,2,1,2,2,1,30236.240945,31437.061964,2,96,7,7,4.04,1,1,0,0,0,2,54,1,2,4,NA +66598,7,2,1,37,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,69324.74001,85851.040558,2,95,15,15,4.63,5,5,1,2,0,2,36,1,5,1,3 +66599,7,2,2,31,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,6,2,1,2,2,1,2,2,1,2,2,1,66503.043118,73915.916489,2,98,7,7,1.61,4,4,1,1,0,1,43,NA,NA,6,NA +66600,7,2,2,64,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,10325.56467,10786.590089,1,96,14,14,5,3,2,0,0,1,2,64,1,4,3,NA +66601,7,2,2,1,20,5,6,2,NA,20,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,3600.631978,3772.844478,3,90,10,10,2.41,5,5,1,2,0,1,44,2,4,1,5 +66602,7,2,2,40,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,105873.555835,110835.841786,1,98,15,15,4.34,4,4,1,1,0,1,41,1,5,1,5 +66603,7,2,2,34,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,2,2,1,2,2,1,2,2,1,2,2,1,24919.497762,30093.052062,1,98,3,3,0.5,5,5,0,3,0,2,56,1,3,3,NA +66604,7,2,2,1,19,5,7,1,NA,20,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8892.555701,9937.38353,1,98,7,7,1.52,4,4,2,0,0,1,30,1,3,1,4 +66605,7,2,2,11,NA,4,4,2,11,142,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9122.654131,9410.759793,1,96,15,15,5,2,2,0,1,0,2,47,1,5,3,NA +66606,7,2,2,0,5,3,3,1,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,20261.925369,19711.566478,2,103,15,15,5,3,3,1,0,0,1,31,1,5,1,5 +66607,7,1,1,67,NA,2,2,NA,NA,NA,2,NA,2,2,8,NA,3,1,NA,1,2,2,2,2,2,NA,NA,NA,NA,7379.175826,0,1,96,14,14,5,2,2,0,0,1,1,67,2,3,1,NA +66608,7,2,2,18,NA,5,6,2,18,219,2,NA,2,2,3,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,8501.305782,9245.625446,1,93,7,7,1.64,5,5,0,2,0,1,47,2,5,1,1 +66609,7,2,1,49,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,26792.151435,27749.707744,1,97,3,3,0.73,3,3,0,0,0,2,50,1,4,1,3 +66610,7,2,2,3,NA,5,6,1,3,39,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7483.230909,7475.326886,2,96,14,14,4.32,3,3,1,0,0,2,33,2,5,1,5 +66611,7,2,2,15,NA,2,2,1,15,189,NA,NA,2,2,3,10,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,18556.092615,19088.608674,1,103,6,6,0.93,5,5,0,1,0,1,39,2,3,1,3 +66612,7,2,1,64,NA,2,2,2,NA,NA,2,NA,2,1,5,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,10739.724778,10911.761454,2,99,15,15,5,2,2,0,0,2,1,64,2,5,1,4 +66613,7,2,1,9,NA,5,6,2,9,112,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9928.619925,10708.884665,1,91,12,12,NA,4,4,0,2,0,1,43,2,5,1,5 +66614,7,2,2,44,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,126334.218747,128844.689973,1,95,9,9,4.08,2,2,0,0,0,1,51,NA,NA,1,3 +66615,7,2,2,16,NA,4,4,2,16,193,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,14085.742306,14155.614592,1,96,8,8,2.17,4,4,1,1,0,2,41,1,3,1,3 +66616,7,2,1,5,NA,1,1,1,5,64,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,2,2,2,NA,NA,NA,NA,10274.893484,10739.35317,2,103,8,8,1.29,7,7,3,1,0,2,53,2,2,4,NA +66617,7,2,2,11,NA,4,4,2,11,139,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12754.235811,13157.031697,1,97,7,7,1.74,4,4,0,3,0,2,32,1,4,5,NA +66618,7,2,2,11,NA,5,6,2,12,145,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10699.45895,11230.540406,1,97,14,14,2.87,5,5,0,3,0,2,40,2,5,1,5 +66619,7,2,2,72,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,72551.269339,74475.92188,1,95,6,6,2.04,2,2,0,0,2,2,72,1,3,1,NA +66620,7,2,1,64,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,157269.814945,159287.072954,1,92,15,15,5,3,3,0,0,2,2,61,1,5,1,5 +66621,7,2,1,0,2,3,3,2,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9570.577309,9932.368407,1,95,1,1,0.1,5,5,2,1,0,1,35,1,9,1,3 +66622,7,2,1,9,NA,5,7,1,9,114,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,41342.668304,42524.849071,1,102,8,8,1.91,5,5,1,2,0,2,38,1,5,1,4 +66623,7,2,1,62,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,7289.557268,7804.776102,3,90,12,12,NA,4,4,0,0,1,1,62,2,4,3,NA +66624,7,2,2,6,NA,4,4,1,6,82,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8504.389189,8682.552645,2,93,6,6,1.72,2,2,0,1,0,2,29,1,4,3,NA +66625,7,2,1,4,NA,5,6,1,4,59,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7812.10492,8436.863602,1,95,4,4,0.62,5,5,2,0,2,2,29,2,3,5,NA +66626,7,2,1,6,NA,5,6,1,7,84,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8095.170809,8542.249827,1,100,15,15,5,3,3,0,1,0,1,38,1,5,1,5 +66627,7,2,1,17,NA,4,4,2,17,206,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11023.237662,11433.168046,1,99,6,6,0.96,5,5,1,2,0,2,35,1,4,1,2 +66628,7,2,2,41,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,133853.800452,133985.238945,3,91,8,8,3.4,2,2,0,0,0,1,33,2,5,1,4 +66629,7,1,2,0,11,2,2,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,5263.118333,0,3,90,4,4,0.74,4,4,1,1,0,1,32,2,4,1,2 +66630,7,2,1,58,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,14897.510053,15360.906039,1,101,14,14,5,2,2,0,0,0,1,58,2,3,1,1 +66631,7,2,2,69,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,10192.188896,10604.379638,1,99,3,3,1.01,1,1,0,0,1,2,69,1,2,3,NA +66632,7,2,1,58,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,174520.785302,181786.280703,1,95,8,8,3.47,2,2,0,0,0,1,58,1,2,1,4 +66633,7,2,1,41,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,19564.598892,20184.074944,3,92,15,15,5,3,3,1,0,0,1,41,2,5,1,3 +66634,7,2,1,9,NA,5,6,2,9,110,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10810.913614,11522.32071,1,97,15,15,4.07,5,5,0,3,0,1,42,2,5,1,5 +66635,7,2,1,78,NA,5,6,2,NA,NA,2,NA,2,2,8,NA,5,1,NA,1,2,1,1,2,1,1,2,2,NA,8637.841003,9256.016034,1,96,9,9,3.97,2,2,0,0,1,1,78,2,5,1,5 +66636,7,2,2,19,NA,4,4,1,19,232,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,16537.460749,16413.673958,2,100,8,8,2.67,3,3,0,0,1,1,61,1,3,1,4 +66637,7,2,2,1,16,4,4,1,NA,17,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7382.686927,7498.263904,2,100,3,3,0.39,7,7,3,3,0,2,30,1,2,5,NA +66638,7,2,2,9,NA,1,1,2,9,117,NA,NA,1,1,NA,3,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,15225.935813,15598.502882,2,94,77,77,NA,5,5,1,1,0,1,41,2,2,1,2 +66639,7,2,1,10,NA,1,1,1,10,130,NA,NA,1,1,NA,4,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,8828.580268,9491.612368,2,103,77,77,NA,7,7,0,4,0,1,38,2,1,6,NA +66640,7,2,2,32,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,85420.170155,90189.982607,1,91,7,7,2.05,3,3,0,1,0,2,32,1,3,1,NA +66641,7,2,2,46,NA,3,3,2,NA,NA,2,NA,2,1,8,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,21224.321717,21245.16306,1,94,7,7,0.94,7,7,1,4,0,2,46,2,5,1,5 +66642,7,2,1,41,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,126717.185106,132638.866244,2,91,14,14,4.19,3,3,0,1,0,2,31,1,4,1,3 +66643,7,2,1,39,NA,5,6,2,NA,NA,2,NA,2,2,6,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,15875.759889,17102.194972,1,96,6,6,1.34,3,3,1,0,0,2,42,2,4,6,NA +66644,7,2,2,63,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,32647.160346,32536.716665,1,99,4,4,1.16,2,2,0,0,2,2,63,1,5,6,NA +66645,7,2,1,13,NA,5,6,2,13,157,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6666.045669,7317.485505,3,90,13,13,NA,3,3,0,2,0,2,41,2,3,4,NA +66646,7,2,2,70,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,81416.374938,85457.008484,1,97,15,15,5,1,1,0,0,1,2,70,1,4,2,NA +66647,7,2,1,19,NA,3,3,1,19,229,2,NA,2,1,99,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,110478.18082,109645.964567,2,101,3,3,1.15,2,1,0,0,0,1,20,2,4,5,NA +66648,7,2,2,7,NA,4,4,1,7,85,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10654.944111,10939.993817,1,100,4,4,0.99,2,2,0,1,0,1,36,2,4,4,NA +66649,7,2,2,53,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,4,NA,1,2,2,1,2,2,1,2,2,1,15521.115746,15096.339697,2,100,7,7,1.34,5,5,0,2,0,2,53,1,4,4,NA +66650,7,2,1,25,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,16088.355002,16260.034828,1,96,1,1,0.2,2,2,0,0,0,1,25,1,2,5,NA +66651,7,2,1,10,NA,2,2,1,10,120,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,19735.224235,20204.314213,2,102,8,8,1.91,5,5,0,3,0,1,39,1,3,1,3 +66652,7,2,1,17,NA,4,4,2,17,215,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,9313.795042,9381.627752,1,96,77,77,NA,7,7,1,3,0,1,56,1,3,1,4 +66653,7,2,1,42,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,19436.026093,20405.866121,2,97,5,5,1.08,3,3,0,1,0,2,45,1,4,6,NA +66654,7,2,1,47,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,28542.421068,28714.346279,2,101,5,5,1.5,2,2,0,0,0,1,47,1,4,3,NA +66655,7,2,2,39,NA,5,6,2,NA,NA,2,NA,2,2,5,NA,3,6,2,1,2,2,1,2,2,NA,NA,NA,NA,11608.998717,11632.703325,3,90,77,77,NA,7,7,1,2,0,1,41,2,3,6,NA +66656,7,1,2,41,NA,2,2,NA,NA,NA,2,NA,2,1,4,NA,2,3,3,2,2,2,1,2,2,NA,NA,NA,NA,34999.007145,0,1,90,1,1,0.32,2,2,0,1,0,2,41,2,2,3,NA +66657,7,2,2,16,NA,3,3,2,16,199,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,58352.457563,59447.870488,1,99,8,8,2.81,3,3,0,1,0,1,19,1,4,NA,NA +66658,7,2,2,14,NA,5,6,2,14,171,NA,NA,2,1,4,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10963.340882,11440.408955,2,91,15,15,5,4,4,0,2,1,2,56,1,5,1,5 +66659,7,2,1,7,NA,1,1,2,7,93,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,18107.947773,18211.90239,1,97,10,10,2.32,6,6,0,4,0,1,42,1,4,1,4 +66660,7,2,1,37,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,18289.793332,19167.642325,1,99,2,2,0.31,4,4,1,0,1,2,67,1,3,3,NA +66661,7,2,1,68,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,20250.944593,20440.871021,2,95,6,6,1.36,3,3,0,0,2,2,60,1,5,1,4 +66662,7,2,1,36,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,18955.147124,22251.142446,1,90,2,2,0.63,2,2,0,0,1,1,36,1,4,5,NA +66663,7,2,1,62,NA,5,6,2,NA,NA,2,NA,2,1,9,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,9355.567184,9645.104203,2,97,15,15,5,2,2,0,0,1,2,58,2,5,1,5 +66664,7,2,2,0,8,4,4,1,NA,10,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4439.36229,4769.277094,2,100,3,3,0.27,7,7,2,1,0,2,41,1,2,5,NA +66665,7,2,2,27,NA,3,3,1,NA,NA,2,NA,2,2,2,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,116919.871791,121727.422593,2,92,10,8,4.59,2,1,0,0,0,2,27,2,5,1,NA +66666,7,2,1,1,17,3,3,2,NA,18,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,28617.223132,30780.732491,1,101,3,3,0.63,3,3,1,0,0,2,47,1,1,3,NA +66667,7,2,2,11,NA,3,3,2,12,144,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,80369.555824,80128.103294,1,97,15,15,5,4,4,1,1,0,2,33,1,5,1,3 +66668,7,2,2,64,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,99831.393624,101809.075589,1,100,15,15,5,2,2,0,0,2,1,79,1,5,1,4 +66669,7,2,2,63,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,137143.403965,141946.841153,2,91,15,15,5,2,2,0,0,2,1,65,1,5,1,5 +66670,7,2,1,53,NA,5,6,2,NA,NA,2,NA,2,2,4,NA,5,1,NA,1,2,1,1,2,2,1,2,1,3,13537.092442,13488.188749,1,90,8,8,1.43,7,7,2,0,0,1,23,2,4,1,3 +66671,7,2,1,46,NA,2,2,1,NA,NA,2,NA,2,1,5,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,28726.575428,29019.719154,2,100,14,14,3.58,4,4,0,1,0,1,46,2,5,1,5 +66672,7,2,1,60,NA,1,1,2,NA,NA,1,1,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,2,2,2,2,8961.035147,9135.681188,2,94,15,15,5,2,2,0,0,1,1,60,1,5,1,5 +66673,7,2,2,25,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,50915.06085,50887.683329,3,92,9,9,2.22,5,5,1,0,2,1,66,2,1,1,1 +66674,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,3,NA,1,2,2,1,2,2,1,2,2,NA,35334.703093,40990.264786,1,101,3,3,0.9,1,1,0,0,1,2,80,1,1,3,NA +66675,7,2,1,4,NA,2,2,1,4,54,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,18754.85406,20094.472571,2,102,6,6,1.12,4,4,1,1,0,1,38,2,2,1,3 +66676,7,2,2,10,NA,4,4,1,10,129,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,1,2,1,2,2,1,8362.256577,9003.967662,2,100,5,1,0,3,1,0,1,0,2,50,1,2,5,NA +66677,7,2,2,18,NA,2,2,2,18,219,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,2,2,2,1,2,2,1,18368.872199,19023.186366,2,91,10,10,2.95,4,4,0,1,0,2,18,1,3,NA,NA +66678,7,2,1,21,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,137038.746155,146586.432966,2,101,4,3,0.92,2,1,0,0,0,1,21,1,4,5,NA +66679,7,2,1,30,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,21280.199633,23174.199432,1,97,15,15,4.84,6,6,2,0,0,1,53,NA,NA,1,NA +66680,7,2,2,56,NA,4,4,2,NA,NA,2,NA,2,1,7,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,15892.013862,19604.056525,3,90,12,12,NA,2,2,0,0,0,2,56,2,4,1,5 +66681,7,2,2,23,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,6,1,1,2,2,1,2,2,1,2,2,1,26999.643202,25671.572746,2,102,5,3,0.63,5,4,2,1,0,1,24,1,4,6,NA +66682,7,2,2,6,NA,2,2,1,6,74,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,14580.994397,14937.78024,2,93,4,4,0.97,3,3,0,1,0,1,38,2,3,1,3 +66683,7,2,1,58,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,4,NA,1,2,2,1,2,2,1,2,2,NA,27609.8026,29259.766266,2,101,10,10,2.91,4,4,0,1,0,2,51,1,2,5,NA +66684,7,2,1,16,NA,5,6,1,16,193,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,7669.677276,8194.5967,2,92,15,15,4.59,4,4,0,2,0,2,48,1,5,1,5 +66685,7,2,1,29,NA,1,1,1,NA,NA,2,NA,2,2,5,NA,2,6,NA,2,2,2,2,2,2,2,2,2,2,33592.259589,37970.446859,1,103,13,13,NA,4,4,2,0,0,2,27,2,2,6,NA +66686,7,2,1,50,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,130229.183917,130070.387937,2,103,77,77,NA,2,1,0,0,0,1,50,1,5,5,NA +66687,7,2,2,53,NA,2,2,1,NA,NA,2,NA,2,1,6,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,22969.116046,23497.145655,2,93,10,10,5,1,1,0,0,0,2,53,2,5,5,NA +66688,7,2,2,19,NA,5,7,1,19,230,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,NA,NA,NA,NA,15318.952876,15275.788411,1,98,2,1,0.18,4,1,0,0,0,2,20,NA,NA,5,NA +66689,7,1,2,71,NA,1,1,NA,NA,NA,2,NA,2,2,6,NA,1,1,NA,2,2,2,1,2,2,NA,NA,NA,NA,22927.30561,0,1,101,5,5,0.51,7,7,0,3,2,1,75,2,1,1,1 +66690,7,2,1,65,NA,1,1,1,NA,NA,2,NA,2,2,7,NA,1,1,NA,2,2,2,2,2,2,2,2,2,2,14067.170863,14844.985608,2,102,4,4,0.67,4,4,0,0,2,2,20,1,1,NA,NA +66691,7,2,1,1,20,4,4,1,NA,20,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10232.679671,10655.495346,2,97,7,7,1.72,5,5,1,2,0,1,32,1,4,1,4 +66692,7,2,2,1,17,1,1,1,NA,18,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,11582.174418,12474.053558,2,102,5,5,0.59,7,7,1,3,0,1,37,2,1,6,NA +66693,7,2,1,18,NA,5,6,2,19,229,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11506.937395,12095.740214,1,97,9,9,1.78,6,6,0,1,1,1,45,2,3,1,3 +66694,7,2,1,1,13,2,2,2,NA,14,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10487.35151,11236.440262,2,95,14,14,4.45,3,3,1,0,0,2,29,1,5,1,5 +66695,7,2,1,60,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,21102.441005,21214.570635,1,98,2,2,0.67,1,1,0,0,1,1,60,1,3,3,NA +66696,7,2,1,11,NA,3,3,2,11,137,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,19926.440922,21167.339982,1,94,7,7,0.94,7,7,1,4,0,2,46,2,5,1,5 +66697,7,2,2,13,NA,3,3,1,13,161,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,61800.07471,62604.355485,1,102,8,8,1.6,7,7,0,4,0,2,39,1,4,1,4 +66698,7,2,1,21,NA,3,3,2,NA,NA,2,NA,2,1,6,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,100807.076657,102674.431164,1,97,15,15,5,4,4,0,0,1,1,60,1,5,1,5 +66699,7,2,1,33,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,105412.227726,111169.022023,2,101,7,7,1.88,4,4,0,2,0,2,36,1,4,1,5 +66700,7,2,1,10,NA,4,4,1,10,124,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7005.767895,7244.406666,2,95,15,15,3.85,7,7,0,3,1,2,62,1,4,2,NA +66701,7,2,1,75,NA,2,2,1,NA,NA,2,NA,2,1,8,NA,1,1,NA,2,2,2,1,2,2,1,2,2,NA,13928.293734,14290.365569,2,92,5,5,1.36,2,2,0,0,2,1,75,2,1,1,1 +66702,7,2,1,47,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,NA,NA,NA,1,2,2,1,18533.049642,19445.722605,1,99,13,13,NA,4,4,1,0,0,2,26,1,4,4,NA +66703,7,2,1,2,NA,5,7,1,2,28,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8375.75457,9394.325143,2,95,15,15,5,3,3,1,0,0,1,50,1,5,1,NA +66704,7,1,2,28,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,4,5,3,1,2,2,1,2,2,NA,NA,NA,NA,15967.106149,0,2,103,1,1,0.04,2,2,0,1,0,2,28,1,4,5,NA +66705,7,2,2,3,NA,4,4,2,3,36,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9727.363166,10265.541082,2,97,3,3,0.4,6,6,2,3,0,2,25,1,2,5,NA +66706,7,2,1,8,NA,5,6,2,8,102,NA,NA,2,1,3,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7923.925927,8546.646915,1,94,7,7,1.79,4,4,0,1,0,1,59,2,4,1,4 +66707,7,2,1,13,NA,1,1,1,13,161,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,24902.864049,25040.491572,1,94,5,5,0.94,4,4,0,2,0,2,37,2,3,1,2 +66708,7,2,2,55,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,20842.960361,20272.538073,3,91,12,12,NA,2,2,0,0,0,1,52,1,5,1,5 +66709,7,1,1,57,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,19478.845078,0,2,95,2,2,0.46,3,3,0,0,0,2,48,1,2,1,2 +66710,7,2,1,66,NA,5,6,2,NA,NA,2,NA,2,1,3,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,9082.311855,9548.677283,1,96,7,7,1.83,3,3,0,0,1,1,66,2,5,1,3 +66711,7,1,2,11,NA,5,6,NA,NA,NA,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5885.567617,0,1,93,9,9,1.77,7,7,0,2,0,2,56,NA,NA,5,NA +66712,7,2,1,31,NA,5,6,2,NA,NA,2,NA,2,1,4,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,14221.330587,14963.406508,3,90,12,12,NA,4,4,0,0,1,1,62,2,4,3,NA +66713,7,2,2,60,NA,3,3,1,NA,NA,2,NA,2,1,6,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,35354.773526,36055.159401,2,103,5,5,1.2,3,3,0,0,2,1,66,2,2,1,2 +66714,7,2,2,21,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,54951.692454,55140.36098,2,102,15,15,3.92,5,5,0,0,0,1,19,1,4,NA,NA +66715,7,2,1,64,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,9535.353518,9609.942052,2,101,9,9,4.08,2,2,0,0,2,2,67,1,5,1,3 +66716,7,2,1,30,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,21317.283165,21013.422419,2,96,4,4,0.65,5,5,0,3,0,1,30,1,4,1,2 +66717,7,2,2,23,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,2,6,3,1,2,2,1,2,2,1,2,2,1,35710.33222,42634.350272,1,90,3,3,0.43,4,4,2,0,0,1,31,1,3,6,NA +66718,7,2,2,56,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,36950.912612,36817.49814,1,97,3,3,1.16,1,1,0,0,0,2,56,1,3,3,NA +66719,7,2,2,9,NA,3,3,2,9,111,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,55469.656717,57246.428971,1,101,9,9,2.6,4,4,0,2,0,2,38,1,4,1,4 +66720,7,2,1,58,NA,4,4,2,NA,NA,2,NA,2,1,6,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,15044.515884,14996.530888,3,90,15,15,4.89,5,5,0,0,0,2,57,2,3,1,3 +66721,7,2,2,47,NA,5,6,2,NA,NA,2,NA,2,2,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,12977.791943,13644.504126,2,100,15,15,5,3,3,0,1,0,1,48,2,5,1,5 +66722,7,2,2,41,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,110070.015649,114078.798472,3,91,15,15,5,4,4,1,1,0,2,41,1,5,1,5 +66723,7,2,1,14,NA,4,4,1,14,178,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17606.165994,18260.901254,2,101,6,6,0.96,5,5,0,4,0,2,36,1,4,4,NA +66724,7,2,1,31,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,22188.836739,23630.941535,1,95,6,6,1.35,3,3,1,0,0,1,31,1,5,1,5 +66725,7,2,1,57,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,124263.643735,125259.229556,2,95,8,8,3.53,2,2,0,0,0,1,57,1,4,1,4 +66726,7,2,1,18,NA,5,7,2,18,217,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,21852.102821,22875.024578,3,91,5,5,0.65,7,7,0,4,0,2,39,1,3,4,NA +66727,7,2,1,11,NA,5,7,2,11,135,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8246.426933,9050.014459,1,99,10,10,3.51,3,3,0,1,0,2,44,1,3,1,5 +66728,7,2,2,71,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,3,1,NA,1,2,1,1,2,1,1,2,1,NA,13750.49328,15781.175386,2,92,4,4,1.14,2,2,0,0,2,1,72,2,3,1,3 +66729,7,2,2,64,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,137143.403965,141946.841153,2,91,15,15,5,2,2,0,0,2,1,68,1,5,1,5 +66730,7,2,1,9,NA,5,7,1,9,117,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11661.909323,12350.149476,1,92,15,15,5,4,4,0,2,0,1,41,2,5,1,5 +66731,7,2,1,46,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,117009.557742,134978.408148,2,99,14,14,5,1,1,0,0,0,1,46,1,5,5,NA +66732,7,2,1,16,NA,5,6,1,16,200,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,9099.087557,9564.682199,2,102,12,12,NA,3,3,0,1,0,1,57,2,5,1,5 +66733,7,2,2,80,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,20131.904783,20903.590301,1,92,15,15,5,2,2,0,0,2,2,80,1,5,1,NA +66734,7,2,2,16,NA,5,6,1,16,201,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,1,1,2,2,1,5760.953091,5914.685125,2,92,8,8,1.91,5,5,0,2,1,2,47,2,1,1,3 +66735,7,2,1,24,NA,5,7,1,NA,NA,2,NA,2,1,4,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,27271.751091,27454.884133,2,101,6,4,1.74,3,1,0,0,0,1,21,1,4,5,NA +66736,7,2,2,55,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,16178.54595,16391.328992,1,93,15,15,5,3,3,0,0,1,1,63,1,5,1,5 +66737,7,2,2,14,NA,2,2,2,14,173,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,2,2,2,1,2,2,1,15087.58237,15620.049499,1,96,15,15,5,4,4,0,2,0,1,36,2,3,1,4 +66738,7,2,1,59,NA,2,2,2,NA,NA,2,NA,2,1,9,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,27240.276328,26969.79863,1,90,15,15,5,2,2,0,0,1,2,63,1,5,1,5 +66739,7,2,1,9,NA,5,6,1,9,116,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,5438.768263,5891.907372,2,92,15,15,5,4,4,0,2,0,2,41,1,5,1,5 +66740,7,2,2,0,7,3,3,1,NA,8,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,20899.681083,21326.972731,1,92,10,10,2.1,6,6,1,1,0,2,29,1,4,1,2 +66741,7,2,2,73,NA,3,3,2,NA,NA,2,NA,2,1,8,NA,4,3,NA,1,2,2,1,2,2,1,2,2,NA,19901.857177,20582.498016,2,94,1,1,0.08,1,1,0,0,1,2,73,2,4,3,NA +66742,7,2,1,4,NA,4,4,2,4,56,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7431.820906,7738.904727,1,99,7,7,1.53,5,5,2,0,0,2,37,1,4,1,3 +66743,7,2,2,68,NA,2,2,1,NA,NA,2,NA,2,2,4,NA,1,4,NA,2,2,2,2,2,2,2,2,1,2,8725.210615,9440.710379,2,93,4,4,0.94,3,3,0,1,1,2,68,2,1,4,NA +66744,7,2,1,80,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,10479.637868,11727.843054,2,98,77,77,NA,1,1,0,0,1,1,80,1,2,2,NA +66745,7,2,2,16,NA,1,1,1,16,197,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,26325.414456,27702.295836,3,92,10,10,3.77,3,3,0,1,0,2,52,1,4,6,NA +66746,7,2,2,23,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,97925.559493,100647.602701,1,94,6,6,1.31,3,3,0,0,0,2,46,1,5,6,NA +66747,7,2,1,59,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,152467.08796,157587.268357,1,94,9,9,3.97,2,2,0,0,0,1,59,1,3,5,NA +66748,7,2,1,73,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,NA,9662.124837,9885.036833,2,92,3,3,1.01,1,1,0,0,1,1,73,1,4,3,NA +66749,7,2,2,56,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,4,NA,1,2,2,1,2,2,1,2,2,1,16741.034883,16841.712651,2,95,2,2,0.7,1,1,0,0,0,2,56,1,3,4,NA +66750,7,2,2,73,NA,2,2,2,NA,NA,2,NA,2,1,6,NA,2,3,NA,2,2,2,1,2,2,2,2,2,NA,20922.745102,23195.943223,1,93,15,15,2.96,7,7,0,1,1,2,18,1,2,NA,NA +66751,7,2,2,9,NA,5,6,2,9,114,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,7722.982971,8635.133042,1,93,8,8,2.24,4,4,0,2,0,1,44,2,5,1,4 +66752,7,2,2,51,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,21491.090123,20964.324934,1,97,14,14,5,3,3,0,0,0,2,51,1,5,1,4 +66753,7,2,2,2,NA,3,3,2,2,27,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,20820.221848,22126.060024,1,95,6,6,0.81,6,6,2,2,0,1,30,1,3,1,4 +66754,7,2,1,47,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,19371.546331,19651.186711,2,95,12,12,NA,2,2,0,1,0,1,47,1,4,2,NA +66755,7,2,2,33,NA,1,1,2,NA,NA,2,NA,2,2,3,NA,1,6,3,2,2,2,2,2,2,1,2,2,2,27127.983961,26396.013964,2,90,6,6,0.96,5,5,1,1,0,1,39,2,2,1,NA +66756,7,1,1,11,NA,2,2,NA,NA,NA,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11567.189008,0,2,90,14,14,3.06,5,5,1,2,0,1,42,1,4,1,5 +66757,7,1,2,59,NA,5,6,NA,NA,NA,2,NA,2,1,99,NA,5,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,12649.084278,0,3,90,77,77,NA,2,2,0,0,1,1,65,2,3,1,5 +66758,7,2,2,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,60071.993203,65791.533402,1,95,99,99,NA,1,1,0,0,1,2,80,1,4,2,NA +66759,7,2,2,57,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,12449.932013,12144.773422,3,90,7,7,2.23,3,3,0,0,0,2,51,1,4,3,NA +66760,7,1,2,32,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,2,1,3,1,2,2,1,2,2,NA,NA,NA,NA,25241.487585,0,2,97,3,3,0.33,6,6,2,0,0,2,32,1,2,1,3 +66761,7,2,1,2,NA,2,2,1,2,28,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,10057.661774,10071.252045,2,93,12,77,NA,3,1,1,1,0,2,43,1,5,3,NA +66762,7,2,1,16,NA,4,4,2,16,195,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11252.388648,11221.862262,1,99,7,7,1.89,3,3,0,1,0,1,50,1,5,1,2 +66763,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,54095.581484,61529.339683,2,91,7,7,1.61,4,4,0,0,3,1,65,1,3,6,NA +66764,7,2,1,2,NA,1,1,1,2,35,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12005.116852,11690.420322,3,92,14,14,2.29,7,7,2,0,0,2,50,2,1,1,9 +66765,7,2,1,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,1,2,1,1,2,NA,NA,NA,NA,40859.270352,45390.978638,2,101,8,8,4.22,1,1,0,0,1,1,80,1,3,2,NA +66766,7,2,1,39,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,94698.084211,103561.845332,1,101,14,14,4.5,3,3,0,1,0,1,39,1,2,1,5 +66767,7,2,2,1,21,1,1,1,NA,21,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12260.86913,13033.834526,3,92,5,5,0.81,5,5,3,0,0,2,23,1,4,5,NA +66768,7,2,2,7,NA,4,4,1,7,85,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8282.497467,8610.715242,2,96,4,4,0.57,6,6,0,3,0,2,29,1,3,4,NA +66769,7,2,2,24,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,18101.423817,17611.874146,2,99,9,9,2.43,4,4,0,2,0,2,49,1,3,3,NA +66770,7,2,2,22,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,59974.233027,60510.443557,2,97,6,6,2.85,2,1,0,0,0,1,22,1,3,6,NA +66771,7,2,2,31,NA,2,2,2,NA,NA,2,NA,2,2,5,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,37439.743351,39040.415193,1,98,3,3,0.4,7,7,2,3,0,2,31,2,5,1,2 +66772,7,2,1,0,9,3,3,2,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7907.070371,7770.374311,2,95,2,2,0.26,3,3,1,0,0,2,54,1,3,2,NA +66773,7,1,1,24,NA,4,4,NA,NA,NA,2,NA,2,2,2,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,16052.583048,0,2,99,77,77,NA,3,3,0,1,0,2,46,NA,NA,77,NA +66774,7,2,2,17,NA,1,1,1,18,216,2,NA,2,2,4,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,26325.414456,26852.811114,3,92,13,13,NA,4,4,0,2,0,2,50,2,1,5,NA +66775,7,2,1,7,NA,1,1,2,7,95,NA,NA,1,1,NA,2,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,15039.041447,16539.35823,3,91,7,7,1.23,6,6,2,2,0,1,36,2,1,1,1 +66776,7,2,2,2,NA,4,4,1,2,27,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7382.686927,8250.113235,2,100,14,14,4.59,3,3,1,0,0,1,30,NA,NA,1,4 +66777,7,2,1,39,NA,2,2,1,NA,NA,2,NA,2,1,3,NA,1,1,NA,2,2,2,1,2,2,2,2,1,2,37631.514869,37347.497931,2,93,3,3,0.43,4,4,0,0,0,1,45,2,2,6,NA +66778,7,2,1,11,NA,4,4,2,11,142,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14125.862146,14370.909235,1,97,15,15,5,4,4,0,1,0,1,40,1,4,1,4 +66779,7,2,1,14,NA,5,6,1,14,176,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,1,1,2,2,1,6121.087833,6878.034577,2,92,3,3,0.4,6,6,0,1,2,1,78,2,1,1,1 +66780,7,2,1,0,2,1,1,1,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,5588.585837,5533.355248,1,102,6,6,0.8,7,7,3,3,0,2,34,2,3,1,1 +66781,7,2,1,68,NA,2,2,2,NA,NA,2,NA,2,1,8,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,11243.205109,11633.337706,1,90,4,4,1.12,2,2,0,0,2,1,68,2,4,1,1 +66782,7,2,2,19,NA,4,4,2,19,236,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,10848.628906,11198.221038,1,99,4,4,0.41,7,7,2,4,0,2,43,1,4,4,NA +66783,7,2,2,0,0,3,3,2,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10692.488346,11331.751026,1,101,4,4,0.78,4,4,1,2,0,2,32,1,3,3,NA +66784,7,2,1,9,NA,4,4,1,9,109,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9261.557132,9701.953496,2,100,7,7,1.34,5,5,0,2,0,2,53,1,4,4,NA +66785,7,2,2,60,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,1,1,NA,1,2,1,1,2,1,1,2,2,NA,18002.759054,18633.946783,2,102,15,15,3.82,5,5,0,1,2,1,60,2,2,1,1 +66786,7,2,1,13,NA,5,6,2,13,163,NA,NA,2,1,3,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7046.884472,7540.251296,2,100,4,4,0.44,7,7,1,2,2,1,71,2,1,1,1 +66787,7,2,2,8,NA,2,2,1,8,99,NA,NA,1,1,NA,2,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,12307.832776,12608.996083,2,93,5,5,0.89,4,4,0,2,0,1,42,NA,NA,6,NA +66788,7,2,1,31,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,39040.678458,39049.131011,2,98,99,99,NA,4,4,1,0,1,2,68,1,9,2,NA +66789,7,2,2,38,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,30505.56355,32886.600907,1,97,6,6,1.03,6,6,2,2,0,2,38,1,5,1,4 +66790,7,2,1,4,NA,4,4,1,4,59,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10040.033098,11070.778245,1,100,3,3,0.73,3,3,2,0,0,2,39,1,3,5,NA +66791,7,2,2,21,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,23845.8146,22808.13483,1,98,12,77,NA,4,1,0,0,0,1,21,1,4,6,NA +66792,7,2,2,4,NA,2,2,2,4,54,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11429.37307,12618.334582,2,90,6,6,1.35,3,3,1,0,0,1,31,1,3,1,4 +66793,7,2,1,50,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,16851.334496,17382.882475,2,101,7,7,2.64,2,2,0,0,1,2,70,1,3,4,NA +66794,7,2,1,10,NA,5,6,2,10,131,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6850.601671,7388.972861,3,91,14,14,4.03,4,4,0,2,0,1,51,2,4,1,5 +66795,7,2,1,23,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,34810.007519,37700.123082,1,94,3,3,0.37,5,5,0,3,0,2,29,1,4,4,NA +66796,7,2,1,70,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,79632.40863,82653.579173,1,95,9,9,4.08,2,2,0,0,2,2,65,1,5,1,3 +66797,7,2,2,30,NA,4,4,2,NA,NA,2,NA,2,1,4,NA,4,1,1,1,2,2,1,2,2,1,2,2,1,27303.803575,27793.15685,1,96,7,7,1.52,4,4,0,2,0,2,30,2,4,1,5 +66798,7,2,2,56,NA,2,2,1,NA,NA,2,NA,2,2,6,NA,4,1,NA,1,2,2,1,2,2,2,2,2,2,34082.505027,35315.234687,2,92,2,2,0.4,3,3,0,0,0,1,50,2,4,1,4 +66799,7,2,1,6,NA,4,4,2,6,76,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10665.048307,10792.905577,1,96,8,8,2.78,3,3,0,2,0,2,34,1,4,3,NA +66800,7,2,1,11,NA,1,1,1,11,135,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13927.458372,13742.678011,2,98,4,4,0.75,4,4,0,2,0,2,33,1,2,5,NA +66801,7,2,1,7,NA,3,3,2,7,91,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,57057.523607,61384.115788,1,101,14,14,4.21,4,4,1,1,0,2,37,1,5,1,5 +66802,7,2,2,43,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,NA,NA,NA,NA,26763.110196,28578.287397,2,94,5,5,1.3,3,3,0,1,0,1,43,1,3,6,NA +66803,7,2,2,22,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,1,1,2,2,1,2,2,NA,NA,NA,NA,43813.24867,44924.427845,1,98,4,4,0.66,4,4,2,0,0,2,22,1,4,6,NA +66804,7,2,1,74,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,12824.368043,13581.00423,2,101,3,3,1.13,1,1,0,0,1,1,74,1,1,2,NA +66805,7,2,2,2,NA,4,4,1,3,36,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7382.686927,8048.181894,2,100,14,4,0.43,7,7,1,3,1,2,62,1,3,5,NA +66806,7,1,2,29,NA,5,6,NA,NA,NA,2,NA,1,1,NA,NA,5,1,3,1,2,2,1,2,2,NA,NA,NA,NA,14698.806915,0,2,99,15,15,5,2,2,0,0,0,1,30,NA,NA,1,5 +66807,7,2,1,29,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,1,1,2,2,1,9177.295801,9603.338468,2,92,3,3,0.45,4,4,0,0,1,1,64,2,1,1,1 +66808,7,2,1,63,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,5950.162866,6182.885443,2,95,5,5,1.05,3,3,0,1,1,1,63,1,2,1,3 +66809,7,1,1,68,NA,2,2,NA,NA,NA,2,NA,2,1,6,NA,3,2,NA,2,2,2,1,2,2,NA,NA,NA,NA,9693.846555,0,2,93,5,5,1.04,4,4,0,1,1,1,68,2,3,2,NA +66810,7,2,1,14,NA,4,4,1,15,180,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,16147.713323,16532.569027,1,92,NA,1,0.18,4,3,0,2,0,2,56,1,4,4,NA +66811,7,2,1,29,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,9177.295801,9548.31812,2,92,77,77,NA,4,4,0,0,1,1,20,1,2,5,NA +66812,7,2,1,15,NA,4,4,1,15,186,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10569.808278,10821.723266,2,92,10,10,4.76,2,2,0,1,0,2,40,1,5,4,NA +66813,7,2,1,9,NA,4,4,2,9,111,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8655.162127,9330.305761,2,95,10,10,3.67,3,3,0,1,0,1,43,1,4,1,4 +66814,7,1,1,34,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,23284.536512,0,1,97,7,7,1.74,4,4,2,0,0,1,34,1,5,1,5 +66815,7,1,1,4,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,58116.402634,0,1,97,15,15,5,5,5,2,0,1,1,43,1,5,1,5 +66816,7,2,1,0,8,1,1,1,NA,10,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,2,2,2,NA,NA,NA,NA,4461.618312,4741.503802,2,103,8,8,1.29,7,7,3,1,0,2,53,2,2,4,NA +66817,7,2,2,72,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,22820.082463,26177.958982,1,94,2,2,0.83,1,1,0,0,1,2,72,1,3,2,NA +66818,7,2,2,8,NA,3,3,2,8,105,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,39976.778207,40067.73727,2,100,15,15,5,3,3,0,1,0,1,38,1,4,1,4 +66819,7,2,1,20,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,102928.893739,104528.537732,1,101,6,6,0.97,7,7,2,1,0,1,43,1,2,1,NA +66820,7,1,2,11,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7710.907339,0,2,99,6,6,0.94,7,7,0,4,0,2,32,1,3,1,3 +66821,7,2,2,30,NA,2,2,1,NA,NA,2,NA,2,2,5,NA,3,1,2,2,2,2,1,2,2,2,2,2,2,41791.57979,45058.092516,2,102,6,6,1.12,4,4,1,1,0,1,38,2,2,1,3 +66822,7,2,1,19,NA,5,6,1,19,230,2,NA,2,1,3,14,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,8431.995003,8807.000735,1,95,3,3,0.71,3,3,0,0,0,1,57,2,2,1,4 +66823,7,2,2,5,NA,5,6,2,5,71,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8173.816615,8894.95474,1,97,15,15,5,4,4,1,1,0,1,44,2,5,1,5 +66824,7,2,2,14,NA,2,2,1,14,175,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18728.878486,20545.934985,2,93,10,10,3.4,3,3,0,1,0,1,51,1,3,1,4 +66825,7,2,1,8,NA,2,2,2,8,107,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11546.167056,12698.029578,1,90,7,7,1.56,4,4,1,1,0,2,37,1,2,77,NA +66826,7,2,2,61,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,11355.3308,11862.334174,1,96,9,9,3.97,2,2,0,0,2,1,72,1,4,1,5 +66827,7,2,1,11,NA,5,6,2,11,140,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,9175.735601,9896.833095,3,91,15,15,5,4,4,0,2,0,1,44,2,5,1,5 +66828,7,2,1,25,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,116839.212439,120894.200639,2,97,9,9,4.08,2,2,0,0,0,2,24,1,4,1,3 +66829,7,2,1,8,NA,5,6,2,8,103,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6262.834446,6786.531245,3,90,15,15,5,4,4,0,2,0,2,41,2,5,1,5 +66830,7,2,2,12,NA,5,6,1,12,154,NA,NA,2,1,4,6,NA,NA,NA,1,1,1,1,2,1,1,2,2,1,5668.184078,6218.795289,2,92,99,2,0.31,7,4,3,3,1,1,61,2,1,1,3 +66831,7,2,1,0,0,1,1,1,NA,0,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,2,2,2,NA,NA,NA,NA,7222.23638,7675.3005,1,94,5,5,0.57,7,7,2,1,0,1,58,2,1,1,1 +66832,7,2,1,75,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,7608.031426,7606.53553,1,99,5,5,1.84,1,1,0,0,1,1,75,1,5,2,NA +66833,7,2,2,39,NA,2,2,2,NA,NA,2,NA,2,1,6,NA,3,1,2,2,2,2,1,2,2,1,2,2,2,41067.133288,41493.788594,2,91,3,3,0.73,3,3,0,0,0,2,22,2,2,5,NA +66834,7,2,1,31,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,14366.887416,15220.688498,3,90,15,15,5,5,5,0,1,1,2,61,1,5,2,NA +66835,7,2,2,56,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,NA,15800.216306,15663.050285,2,99,2,2,0.19,6,6,0,1,0,1,59,1,2,5,NA +66836,7,2,1,22,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,35522.958395,37225.553122,1,102,13,1,0,2,1,0,0,0,1,22,1,4,5,NA +66837,7,2,1,24,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,16489.238752,16479.116235,1,96,6,6,1.21,4,4,2,0,0,1,24,1,4,1,3 +66838,7,2,2,65,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,152978.138087,155477.549686,1,101,7,7,3.13,1,1,0,0,1,2,65,1,4,2,NA +66839,7,2,2,25,NA,5,6,2,NA,NA,2,NA,2,2,1,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,11696.173591,12195.620792,1,93,15,1,0.41,6,1,0,0,0,1,34,2,5,5,NA +66840,7,2,2,10,NA,3,3,1,10,123,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,61059.578287,60876.138307,1,98,15,15,4.34,4,4,0,2,0,2,52,1,3,1,5 +66841,7,2,1,3,NA,5,7,1,3,46,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,26980.605125,29855.353305,1,94,2,2,0.3,5,5,1,2,0,1,23,1,1,6,NA +66842,7,1,2,0,9,4,4,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,3861.876549,0,1,96,15,15,4.81,5,5,1,2,0,1,33,1,5,1,3 +66843,7,2,1,5,NA,5,7,1,5,63,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10859.969359,11974.89205,1,98,7,7,1.52,4,4,2,0,0,1,30,1,3,1,4 +66844,7,2,1,18,NA,4,4,1,18,221,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,16147.713323,16270.487634,1,92,77,77,NA,5,5,1,2,0,2,41,1,3,5,NA +66845,7,2,1,1,15,3,3,1,NA,16,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,47507.757497,53600.040598,1,101,14,14,3.15,5,5,2,1,0,1,35,1,4,1,5 +66846,7,2,1,2,NA,4,4,1,3,36,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6376.965739,7031.647494,2,100,8,8,2.7,3,3,1,0,0,2,41,1,4,1,3 +66847,7,2,1,31,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,16505.268729,17550.815541,3,91,14,14,4.32,3,3,1,0,0,1,31,2,3,1,4 +66848,7,2,2,52,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,141821.601523,151144.430607,1,90,15,15,5,4,4,0,2,1,2,52,1,5,1,NA +66849,7,2,1,0,11,5,7,2,NA,12,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7317.981812,7846.84086,1,97,15,15,3.7,5,5,1,1,0,2,21,1,4,5,NA +66850,7,2,2,71,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,19603.448069,21893.680196,2,98,5,5,0.59,7,7,2,1,2,2,71,1,2,1,1 +66851,7,2,2,46,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,143866.32507,144700.959982,1,97,15,15,5,1,1,0,0,0,2,46,1,4,2,NA +66852,7,2,1,4,NA,4,4,2,4,53,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8569.438441,9098.434789,2,99,7,7,1.19,6,6,1,3,0,2,38,1,3,5,NA +66853,7,2,1,2,NA,2,2,1,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11030.983881,11818.903113,2,93,7,7,1.56,4,4,1,1,0,1,35,2,4,1,4 +66854,7,2,2,34,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,NA,NA,NA,NA,26021.868354,25835.926172,2,96,3,3,0.47,6,6,0,4,0,1,36,1,4,1,4 +66855,7,2,1,20,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,17606.560681,17743.688949,2,95,6,6,1.7,2,2,0,0,0,2,54,1,4,2,NA +66856,7,2,2,2,NA,1,1,1,3,36,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,12871.484115,13281.030392,2,102,5,5,0.89,4,4,1,1,0,2,28,2,2,1,2 +66857,7,2,2,15,NA,5,6,2,15,181,NA,NA,1,1,NA,10,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6486.356303,6952.179218,1,91,7,7,1.57,4,4,0,3,0,2,38,2,2,3,NA +66858,7,2,2,6,NA,4,4,1,6,83,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8362.256577,8929.488766,2,100,7,7,2.37,3,3,0,1,1,2,45,1,5,1,NA +66859,7,2,1,2,NA,4,4,2,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6441.733603,6839.385512,1,91,6,6,0.99,5,5,3,0,0,2,33,2,3,1,4 +66860,7,2,1,21,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,51965.135941,60918.873896,2,101,2,1,0.37,2,1,0,0,0,1,21,1,4,5,NA +66861,7,2,1,21,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,17583.693727,17478.873252,2,95,6,6,1.36,3,3,0,1,1,2,62,1,4,5,NA +66862,7,2,1,10,NA,4,4,2,10,128,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9699.683862,9681.447258,2,101,2,2,0.27,6,6,0,3,0,2,45,1,2,5,NA +66863,7,2,1,77,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,70642.066815,74773.070249,2,96,12,12,NA,2,2,0,0,2,1,77,1,5,1,4 +66864,7,2,1,16,NA,4,4,1,16,196,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11666.009872,12200.765691,2,100,14,4,0.43,7,7,1,3,1,2,62,1,3,5,NA +66865,7,2,2,15,NA,1,1,1,15,184,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,22424.988432,22856.096824,1,94,5,5,0.87,4,4,0,2,0,2,41,2,4,1,1 +66866,7,2,1,5,NA,4,4,1,5,61,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8385.172131,8641.288503,2,93,5,5,1.04,4,4,1,1,0,1,29,1,3,6,NA +66867,7,1,1,18,NA,1,1,NA,NA,NA,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,NA,NA,NA,NA,22721.243258,0,2,102,7,7,1.04,7,7,1,2,0,2,37,2,1,1,2 +66868,7,2,1,8,NA,5,6,2,8,100,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9928.619925,10708.884665,1,91,15,15,5,4,4,1,1,0,1,43,2,5,1,5 +66869,7,2,2,54,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,24719.680932,24496.884814,1,97,15,15,5,2,2,0,0,0,1,59,1,5,1,5 +66870,7,2,2,12,NA,1,1,1,12,153,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,22424.988432,24600.637711,1,94,15,15,4.37,7,7,0,4,1,1,58,1,4,1,5 +66871,7,2,1,26,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,32375.321924,32878.474997,1,95,7,6,2.6,5,1,1,2,0,1,26,1,4,6,NA +66872,7,2,1,37,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,22424.102245,23525.946014,1,92,14,14,3.47,4,4,0,2,0,1,37,1,5,1,5 +66873,7,2,2,54,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,163102.567998,168673.834909,1,99,12,12,NA,2,2,0,0,0,1,55,1,5,1,4 +66874,7,2,2,31,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,53955.606082,55085.619185,2,100,15,15,5,4,4,1,1,0,1,29,1,4,1,4 +66875,7,2,2,69,NA,5,6,2,NA,NA,2,NA,2,2,4,NA,4,1,NA,1,2,1,1,2,1,1,2,1,3,10760.495249,11342.54557,3,90,4,4,1.22,2,2,0,0,2,2,69,2,4,1,1 +66876,7,2,2,62,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,134694.414609,139412.076132,2,91,15,15,5,3,3,0,0,2,2,62,1,4,1,4 +66877,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,56180.550638,64695.241485,2,98,5,5,1.63,2,2,0,0,2,1,80,1,3,1,3 +66878,7,2,2,15,NA,1,1,1,15,180,NA,NA,2,2,4,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,21062.314667,21780.985882,3,91,3,3,0.39,6,6,1,1,0,1,39,2,1,6,NA +66879,7,2,2,42,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,139800.409559,144765.126463,1,100,15,15,4.56,4,4,0,2,0,2,42,1,4,1,3 +66880,7,2,1,24,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,18452.546861,18969.498532,1,93,12,12,NA,3,3,0,1,0,2,48,1,3,5,NA +66881,7,2,2,40,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,20303.639991,20411.004471,1,97,15,15,2.33,7,7,2,4,0,2,40,2,5,1,4 +66882,7,2,2,22,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,50922.951701,51648.728485,1,92,15,15,5,3,3,0,0,1,1,57,1,3,1,4 +66883,7,2,1,35,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,109181.566304,117126.933999,2,91,7,7,2.31,2,2,0,0,0,2,58,1,5,3,NA +66884,7,2,2,35,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,20691.085146,20754.703375,2,91,4,4,1.22,2,2,0,0,0,1,53,1,4,1,4 +66885,7,2,1,76,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,6856.239408,7260.756717,2,95,5,5,0.87,4,4,0,0,2,2,77,1,2,1,1 +66886,7,2,1,5,NA,2,2,2,5,71,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14318.290734,14771.527769,3,91,6,6,0.83,6,6,1,3,0,1,37,1,4,1,4 +66887,7,1,2,6,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9122.654131,0,1,96,9,9,2.18,5,5,1,1,0,1,26,1,4,1,4 +66888,7,2,2,1,18,4,4,1,NA,19,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7281.670423,7938.059494,2,96,4,4,0.4,7,7,3,2,0,2,25,1,2,5,NA +66889,7,2,1,59,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,19541.667675,22573.12843,2,95,1,1,0.36,1,1,0,0,0,1,59,1,5,5,NA +66890,7,2,1,14,NA,1,1,2,14,178,NA,NA,2,2,4,8,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,22044.437334,22214.434256,1,97,8,8,1.45,6,6,2,2,0,2,36,2,2,1,1 +66891,7,2,2,15,NA,3,3,2,15,191,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,132630.209478,136474.31291,1,97,15,15,5,4,4,0,2,0,1,49,1,5,1,5 +66892,7,2,2,1,16,3,3,1,NA,16,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,46281.468826,49830.1764,1,92,9,4,1,7,3,2,1,0,1,45,1,4,2,NA +66893,7,2,1,60,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,168185.448935,169079.116739,1,95,9,9,4.01,2,2,0,0,1,1,60,1,3,1,3 +66894,7,1,2,1,12,5,6,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4938.043177,0,1,91,9,9,2.97,3,3,1,0,0,1,31,2,5,1,5 +66895,7,2,1,10,NA,2,2,2,10,121,NA,NA,2,2,3,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10490.055059,10676.813132,3,90,4,4,0.63,5,5,0,3,0,1,45,2,4,1,4 +66896,7,2,1,64,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,8886.717016,9234.294003,2,101,3,3,0.78,3,3,0,0,1,1,64,1,2,1,3 +66897,7,2,2,28,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,1,1,2,2,1,2,2,1,2,2,1,18097.801029,17642.065425,2,100,9,9,3.24,3,3,1,0,0,1,32,1,3,1,4 +66898,7,2,2,45,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,24056.374863,23398.009058,2,99,6,6,2.6,1,1,0,0,0,2,45,1,5,5,NA +66899,7,2,2,11,NA,1,1,1,11,141,NA,NA,1,1,NA,5,NA,NA,NA,2,1,1,1,2,1,1,2,2,1,22662.992756,24846.804377,2,98,13,13,NA,5,5,0,2,0,1,48,2,1,1,2 +66900,7,2,2,10,NA,4,4,1,10,121,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12120.418061,13050.526646,2,101,1,1,0.15,3,3,0,2,0,2,58,1,3,5,NA +66901,7,2,2,68,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,11449.435533,12331.980143,2,99,6,6,1.98,2,2,0,0,2,1,77,1,3,1,3 +66902,7,2,2,32,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,1,1,2,2,1,2,2,1,2,2,1,25691.564623,26900.812132,1,90,3,3,0.63,3,3,1,1,0,2,32,1,4,5,NA +66903,7,2,2,39,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,74517.751389,74746.868777,2,94,7,7,1.17,6,6,0,3,0,1,40,1,3,1,5 +66904,7,2,1,27,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,11507.810748,11238.9991,2,99,NA,77,NA,7,7,1,0,1,2,51,1,2,1,3 +66905,7,2,2,25,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,18801.993237,20649.846581,2,96,8,5,2.2,2,1,0,0,0,2,25,2,5,5,NA +66906,7,2,2,11,NA,4,4,2,11,135,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10888.493631,11627.08662,1,101,1,1,0.21,3,3,0,2,0,2,32,1,4,5,NA +66907,7,2,2,37,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,2,1,2,1,2,2,1,2,2,NA,NA,NA,NA,11105.558187,11128.234812,3,91,14,14,2.5,6,6,1,1,1,2,37,2,2,1,5 +66908,7,2,1,52,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,17824.805721,17767.952896,2,92,2,2,0.57,2,2,0,0,0,2,56,1,3,2,NA +66909,7,2,2,27,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,2,1,2,2,1,2,2,1,2,2,1,52280.406546,52747.829022,1,95,3,1,0.28,2,1,0,0,0,1,27,1,3,5,NA +66910,7,1,2,8,NA,1,1,NA,NA,NA,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14465.997114,0,2,96,3,3,0.24,7,7,2,3,1,2,40,1,3,3,NA +66911,7,2,1,40,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,3,NA,1,2,2,1,2,2,1,2,2,1,22697.846242,22639.540149,2,100,4,4,1.47,2,1,0,0,0,2,38,1,3,2,NA +66912,7,2,2,14,NA,5,7,2,14,172,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6386.337576,6452.948976,1,93,15,15,4.59,4,4,0,2,0,2,45,1,5,1,5 +66913,7,2,1,9,NA,2,2,2,9,119,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8516.07921,8708.134582,3,90,14,14,3.69,4,4,0,2,0,2,49,1,4,1,4 +66914,7,2,2,51,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,3,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,12162.017722,12226.329772,2,92,12,9,5,7,1,0,0,2,1,53,2,3,1,3 +66915,7,2,1,51,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,32461.799549,32422.216998,1,101,4,4,0.99,2,2,0,0,0,2,51,1,5,1,2 +66916,7,2,1,1,23,4,4,1,NA,24,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6376.965739,6859.539552,1,96,5,5,0.53,7,7,2,2,0,2,38,1,9,6,NA +66917,7,2,1,7,NA,1,1,1,7,89,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16747.549238,17012.570163,2,96,7,7,1.34,5,5,0,2,0,1,24,2,2,5,NA +66918,7,2,1,72,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,32916.648979,34960.567692,2,103,15,15,3.44,7,7,0,1,2,2,79,1,3,2,NA +66919,7,2,2,13,NA,1,1,1,13,158,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,27070.679378,27847.54398,1,92,14,14,3.15,5,5,1,2,0,1,34,1,4,1,4 +66920,7,2,1,77,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,17113.447343,18123.138698,2,101,6,6,2.04,2,2,0,0,2,1,77,1,1,1,2 +66921,7,2,2,34,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,38679.12951,52110.643741,1,98,3,3,0.86,2,2,0,1,0,2,34,1,4,5,NA +66922,7,2,2,12,NA,4,4,2,12,149,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12180.874919,12414.982997,1,91,15,15,5,6,6,1,2,0,2,42,2,5,1,5 +66923,7,2,2,47,NA,5,6,1,NA,NA,2,NA,2,2,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,17623.300255,17855.084956,1,100,15,15,5,3,3,0,0,0,1,47,2,5,1,5 +66924,7,2,1,36,NA,2,2,2,NA,NA,2,NA,2,1,6,NA,3,1,NA,1,2,2,2,2,2,NA,NA,NA,NA,28519.067294,31362.329476,1,96,15,15,5,4,4,0,2,0,1,36,2,3,1,4 +66925,7,2,2,23,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,46764.716703,54568.74353,1,99,2,2,0.46,1,1,0,0,0,2,23,1,5,5,NA +66926,7,2,1,51,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,175544.769665,178639.415011,1,91,15,15,5,2,1,0,0,0,1,51,1,3,1,NA +66927,7,2,1,20,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,51965.135941,52673.460841,2,101,1,1,0.11,2,1,0,0,0,1,19,NA,NA,NA,NA +66928,7,2,2,64,NA,5,6,1,NA,NA,2,NA,2,1,1,NA,1,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,7118.69664,7393.452915,1,103,77,77,NA,6,6,0,2,2,1,70,NA,NA,1,1 +66929,7,2,2,63,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,12331.419303,12882.003985,2,95,14,14,5,2,2,0,0,2,1,73,1,5,1,4 +66930,7,2,1,41,NA,1,1,2,NA,NA,2,NA,2,2,5,NA,3,1,NA,2,2,2,2,2,2,2,2,2,2,31640.296506,31576.726829,2,94,15,15,5,3,3,0,0,0,1,41,2,3,1,NA +66931,7,2,1,16,NA,3,3,2,16,194,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,68148.957861,67253.324127,1,93,15,15,3.92,5,5,0,1,0,2,54,1,5,1,5 +66932,7,2,1,60,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,4,NA,1,2,2,1,2,2,1,2,2,1,10420.275705,10501.786379,2,96,7,7,2.58,2,2,0,0,1,2,55,1,4,3,NA +66933,7,2,1,34,NA,5,6,1,NA,NA,2,NA,2,7,77,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,16770.056318,16992.484825,1,103,12,12,NA,2,2,0,0,0,1,34,2,5,1,5 +66934,7,2,2,12,NA,5,6,1,13,156,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7952.410952,8162.028124,2,98,9,9,2.29,5,5,0,2,0,1,36,1,4,1,4 +66935,7,2,1,1,19,5,7,2,NA,20,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6370.584728,7024.611386,2,94,10,10,3.51,3,3,1,0,0,2,30,2,5,1,NA +66936,7,2,1,28,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,3,1,NA,1,2,2,1,2,1,1,2,2,3,14313.345971,14892.009983,3,91,6,6,1.12,4,4,0,0,2,1,69,2,3,1,1 +66937,7,2,1,37,NA,3,3,1,NA,NA,2,NA,2,2,6,NA,2,5,NA,1,2,2,2,2,2,1,2,2,1,63557.943986,66218.577849,2,103,12,12,NA,3,3,0,0,1,1,60,2,2,1,2 +66938,7,2,2,62,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,1,1,NA,1,2,1,NA,NA,NA,1,2,1,NA,17248.011865,22917.917651,1,97,14,14,2.29,7,7,1,2,2,1,40,2,1,1,1 +66939,7,1,2,15,NA,2,2,NA,NA,NA,NA,NA,2,2,3,10,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,18053.382334,0,1,90,10,10,3.67,3,3,0,1,0,2,40,2,2,77,NA +66940,7,2,2,14,NA,1,1,1,14,168,NA,NA,1,1,NA,7,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,20117.170449,20520.192725,1,94,2,2,0.27,5,5,0,4,0,2,47,2,1,4,NA +66941,7,2,1,25,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,42077.383821,43345.097117,1,102,14,14,4.32,3,3,1,0,0,1,25,1,4,1,4 +66942,7,2,2,43,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,1,1,2,1,2,2,1,2,2,1,2,2,1,20562.749362,20582.941069,2,95,6,6,0.9,6,6,1,1,0,1,49,1,1,1,1 +66943,7,2,2,46,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,27934.372045,29727.618806,1,101,7,2,0.67,3,1,0,0,1,2,69,1,4,2,NA +66944,7,2,1,72,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,79754.311902,85970.307401,1,97,6,6,2.15,2,2,0,0,2,1,72,1,5,1,NA +66945,7,2,2,57,NA,1,1,1,NA,NA,2,NA,2,2,7,NA,1,1,NA,2,2,2,1,2,2,2,2,2,2,24646.971819,24775.50368,1,102,6,6,1.48,3,3,0,0,1,2,57,2,1,1,4 +66946,7,2,1,32,NA,5,7,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,19384.896286,21271.615575,1,94,6,6,1.33,4,4,2,0,0,2,29,1,2,1,4 +66947,7,2,1,51,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,29883.483388,30470.971906,1,102,9,9,3.74,2,2,0,0,0,2,45,1,4,1,2 +66948,7,2,1,14,NA,5,6,1,15,180,NA,NA,2,1,3,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6140.97758,6391.148404,1,100,5,5,0.74,6,6,0,3,0,1,40,2,3,1,4 +66949,7,2,2,54,NA,5,7,1,NA,NA,2,NA,2,1,7,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,21760.356138,21875.42365,1,92,14,14,5,2,2,0,0,0,1,56,2,4,1,4 +66950,7,2,2,48,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,111065.717962,123974.675785,2,94,3,3,0.54,4,4,0,1,0,2,48,1,3,1,3 +66951,7,2,2,8,NA,1,1,1,8,97,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,1,2,2,2,2,2,2,17053.854294,17496.484818,3,92,7,7,0.93,7,7,1,3,0,2,20,1,3,1,1 +66952,7,2,2,4,NA,3,3,2,4,53,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,27257.164734,28409.87702,1,101,6,6,0.87,6,6,2,2,0,2,23,1,4,6,NA +66953,7,2,1,10,NA,1,1,1,10,124,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13837.588743,14876.800627,1,92,8,8,2.62,3,3,0,1,0,1,41,2,3,1,9 +66954,7,2,2,27,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,81857.569857,83650.947594,2,92,15,10,5,4,1,0,0,0,1,28,1,5,5,NA +66955,7,2,1,38,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,39040.678458,39049.131011,2,98,15,15,5,3,3,0,1,0,1,38,1,4,1,3 +66956,7,2,2,21,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,2,1,2,2,1,2,2,1,2,2,1,41018.498876,43893.586815,2,98,3,3,0.54,3,3,1,0,0,1,23,1,3,1,2 +66957,7,2,1,62,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,136361.754972,134969.826866,1,98,6,6,1.75,2,2,0,0,2,1,62,1,4,1,3 +66958,7,2,1,52,NA,3,3,1,NA,NA,2,NA,2,2,5,NA,3,1,NA,2,2,2,1,2,2,2,2,2,2,24127.240234,24937.486066,2,93,6,6,1.65,2,2,0,0,0,1,52,2,3,1,5 +66959,7,2,2,43,NA,1,1,1,NA,NA,2,NA,2,2,5,NA,1,5,2,2,2,2,2,2,2,1,2,2,2,33767.584626,33943.679708,2,102,6,3,0.54,6,4,0,4,0,2,43,2,1,5,NA +66960,7,2,1,1,20,5,6,1,NA,21,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8674.760516,9729.693026,1,94,10,10,3.04,4,4,2,0,0,2,30,1,4,1,5 +66961,7,2,1,36,NA,5,6,2,NA,NA,2,NA,2,2,4,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,19144.719218,19850.422567,1,101,10,10,3.67,3,3,1,0,0,1,36,2,5,1,5 +66962,7,2,1,1,22,4,4,1,NA,24,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5930.749873,6003.089312,2,93,7,7,1.83,3,3,1,0,0,2,34,2,3,1,3 +66963,7,1,2,70,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,64383.454106,0,1,90,12,12,NA,2,2,0,0,2,1,75,1,5,1,4 +66964,7,2,2,27,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,100264.332334,101647.830414,1,99,7,7,4.09,1,1,0,0,0,2,27,1,5,5,NA +66965,7,2,1,2,NA,3,3,1,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,21718.301271,24503.405153,1,94,5,5,0.74,5,5,1,1,0,2,24,1,3,1,4 +66966,7,2,2,14,NA,1,1,2,14,170,NA,NA,2,2,4,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,19850.979841,20551.555585,1,97,3,3,0.5,5,5,0,2,0,1,56,2,2,6,NA +66967,7,2,1,33,NA,2,2,2,NA,NA,2,NA,2,2,2,NA,2,6,NA,2,2,2,2,2,2,NA,NA,NA,NA,39073.76885,38778.866765,2,99,99,3,0.79,4,2,0,0,0,2,42,2,4,5,NA +66968,7,2,2,11,NA,1,1,1,11,139,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,21075.336925,21477.798111,1,92,14,14,3.15,5,5,1,2,0,1,34,1,4,1,4 +66969,7,2,1,10,NA,1,1,1,10,125,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8828.580268,8822.70874,1,103,7,7,0.51,7,7,3,4,0,1,54,2,1,1,1 +66970,7,2,1,18,NA,1,1,2,18,222,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,26704.187335,27112.370182,1,95,8,5,1.36,3,2,0,0,0,1,50,1,9,6,NA +66971,7,2,2,8,NA,5,6,1,8,107,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9620.269705,10273.007637,2,91,15,15,4.63,7,7,1,2,0,1,36,2,4,1,3 +66972,7,1,1,1,13,4,4,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6376.965739,0,2,100,2,2,0.25,4,4,2,1,0,2,39,1,2,5,NA +66973,7,2,2,49,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,111065.717962,111174.779569,2,94,10,10,4.42,2,2,0,0,0,2,49,1,4,1,1 +66974,7,2,1,72,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,11034.04089,11599.454609,2,95,5,5,1.45,2,2,0,0,2,1,72,1,3,1,3 +66975,7,2,1,17,NA,2,2,1,17,205,2,NA,2,1,4,9,NA,NA,NA,1,2,2,2,2,2,1,2,2,1,18206.126374,19392.083527,2,93,3,3,0.58,4,4,0,1,1,1,65,2,1,3,NA +66976,7,2,1,24,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,35338.972549,37196.45724,2,90,6,6,1.21,4,4,0,0,0,2,59,2,1,6,NA +66977,7,2,2,10,NA,4,4,2,10,124,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8579.490652,8919.477637,2,97,4,4,0.57,5,5,1,3,0,2,33,1,3,5,NA +66978,7,2,1,7,NA,5,6,2,7,86,NA,NA,2,2,3,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9928.619925,10758.848877,1,91,14,14,3.69,4,4,1,1,0,2,29,2,5,1,5 +66979,7,2,2,16,NA,5,6,2,16,200,NA,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,1,1,2,2,1,7588.544207,8133.521636,3,91,6,6,1.34,4,4,0,2,0,1,52,2,3,1,1 +66980,7,2,1,7,NA,5,6,2,7,88,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9928.619925,10758.848877,1,91,2,2,0.32,3,3,1,1,0,2,28,1,4,77,NA +66981,7,2,1,42,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,27356.080541,27921.272721,1,101,4,4,0.84,3,3,0,1,0,1,42,1,4,1,4 +66982,7,2,2,73,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,21924.837493,22597.469895,2,95,7,7,1.13,6,6,0,3,1,1,52,1,4,1,4 +66983,7,2,2,9,NA,4,4,1,9,113,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,8362.256577,9003.967662,2,100,1,1,0.08,5,5,1,2,0,2,19,1,3,NA,NA +66984,7,2,1,75,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,53663.609619,56801.747638,2,93,10,10,3.61,3,3,0,0,2,1,75,1,4,1,4 +66985,7,2,2,77,NA,2,2,1,NA,NA,2,NA,2,1,8,NA,3,2,NA,1,2,2,1,2,2,2,2,1,NA,18241.877822,19614.829564,2,93,3,3,0.66,2,2,0,0,2,2,69,2,4,3,NA +66986,7,2,1,9,NA,5,6,1,9,116,NA,NA,1,1,NA,4,NA,NA,NA,1,1,1,1,2,1,1,2,2,1,6254.093492,6623.185563,2,92,5,5,0.64,7,7,1,2,1,1,66,2,1,1,3 +66987,7,2,1,0,8,5,6,2,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5507.575232,5738.278852,1,97,15,15,4.84,6,6,2,0,0,1,53,NA,NA,1,NA +66988,7,2,2,40,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,19870.689174,19326.875638,1,96,3,3,0.93,2,2,0,1,0,2,40,1,5,5,NA +66989,7,2,2,1,14,1,1,1,NA,15,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11512.764389,11879.078775,2,98,2,2,0.35,3,3,2,0,0,2,20,1,4,5,NA +66990,7,2,2,22,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,2,1,2,2,1,2,2,1,2,2,1,18097.801029,17527.360027,1,96,12,12,NA,7,7,1,0,1,2,59,1,3,1,1 +66991,7,2,1,24,NA,5,6,2,NA,NA,2,NA,2,2,2,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,14313.345971,14703.033095,3,91,10,10,4.42,2,2,0,0,0,1,47,2,2,1,NA +66992,7,2,1,7,NA,3,3,2,7,86,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,42986.51011,44926.997612,2,94,14,14,2.83,6,6,0,4,0,2,38,1,2,1,2 +66993,7,2,2,38,NA,2,2,2,NA,NA,2,NA,2,2,2,NA,2,6,2,2,2,2,2,2,2,NA,NA,NA,NA,32982.479382,32092.542799,2,99,99,3,0.79,4,2,0,0,0,2,42,2,4,5,NA +66994,7,2,1,52,NA,2,2,1,NA,NA,2,NA,2,2,3,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,25264.512558,25333.955786,2,93,15,15,5,2,2,0,0,0,1,52,2,5,1,5 +66995,7,2,2,37,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,76827.086279,81170.917712,2,99,15,15,5,2,2,0,0,0,2,37,1,5,1,5 +66996,7,2,1,22,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,25651.892165,25827.388922,1,97,14,14,5,3,3,0,0,0,2,51,1,5,1,4 +66997,7,2,2,15,NA,4,4,1,15,185,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,19770.196972,20174.150218,2,102,10,10,3.78,3,3,0,1,0,1,33,1,3,5,NA +66998,7,2,2,5,NA,4,4,2,5,66,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10771.85499,12037.490455,2,97,4,4,0.81,4,4,1,1,0,2,51,1,3,4,NA +66999,7,2,2,15,NA,4,4,1,15,191,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13801.622751,14246.373765,1,100,10,10,2.59,5,5,0,1,0,2,40,1,5,1,NA +67000,7,2,1,49,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,18533.049642,19320.837782,1,99,15,8,4.59,4,1,0,2,0,1,49,1,4,6,NA +67001,7,2,1,76,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,63147.363155,65543.108264,1,91,8,8,3.4,2,2,0,0,2,2,74,1,4,1,2 +67002,7,2,1,39,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,21317.283165,22287.043754,2,96,5,5,1.08,3,3,0,1,0,2,41,1,3,1,NA +67003,7,2,1,68,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,105401.67423,106753.633419,2,92,15,15,5,1,1,0,0,1,1,68,1,5,3,NA +67004,7,2,2,4,NA,1,1,1,4,54,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,18078.669459,18848.958225,1,101,2,2,0.26,5,5,3,0,0,2,26,1,2,1,3 +67005,7,2,1,19,NA,4,4,2,19,239,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11351.725436,11256.943498,2,95,8,8,1.61,6,6,1,3,0,2,48,1,3,5,NA +67006,7,2,2,2,NA,4,4,2,2,26,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7348.24433,7906.792868,2,95,8,8,1.61,6,6,1,3,0,2,48,1,3,5,NA +67007,7,2,2,40,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,19247.348846,19527.962249,2,101,9,9,3.74,2,2,0,0,0,2,40,2,4,1,2 +67008,7,2,2,17,NA,4,4,1,17,210,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,16659.324602,16705.662179,1,92,77,77,NA,5,5,1,2,0,2,41,1,3,5,NA +67009,7,2,2,33,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,90299.161173,96625.186997,1,92,6,6,1.57,3,3,0,1,0,1,29,1,4,6,NA +67010,7,2,2,3,NA,2,2,2,3,45,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,11009.851855,11478.955249,1,93,13,3,0.54,6,3,2,1,0,1,23,NA,NA,5,NA +67011,7,2,2,67,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,1,4,NA,1,2,2,1,2,2,1,2,2,1,7869.59899,8538.749518,2,100,2,2,0.72,1,1,0,0,1,2,67,1,1,4,NA +67012,7,2,2,34,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,14138.631841,14167.501749,3,92,8,8,0.91,7,7,3,3,1,1,61,NA,NA,1,4 +67013,7,2,1,11,NA,4,4,2,11,132,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9699.683862,9867.948233,2,97,14,14,3.91,4,4,1,1,0,1,38,1,4,1,5 +67014,7,2,2,48,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,18696.216547,18746.863759,2,100,5,5,0.95,4,4,0,0,1,2,53,1,3,5,NA +67015,7,2,2,22,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,14516.765165,13843.248577,3,90,7,7,2.23,3,3,0,0,0,2,51,1,4,3,NA +67016,7,2,2,11,NA,3,3,2,11,136,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,48532.852397,48387.04619,1,98,14,14,3.9,4,4,0,3,0,2,31,1,4,1,NA +67017,7,2,1,11,NA,3,3,2,11,139,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,82670.203859,85919.643529,1,97,15,15,5,5,5,0,3,0,2,47,2,5,1,5 +67018,7,1,1,5,NA,2,2,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,2,2,2,NA,NA,NA,NA,17458.543556,0,2,91,6,6,1.3,4,4,1,1,0,2,27,1,4,6,NA +67019,7,2,1,6,NA,5,7,1,6,83,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7101.095162,7528.512272,2,96,15,15,5,4,4,1,1,0,2,35,2,5,1,5 +67020,7,2,1,78,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,74473.849242,78828.927467,2,98,14,14,5,2,2,0,0,2,1,78,1,5,1,3 +67021,7,2,1,50,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,15599.953109,16099.73574,1,99,7,7,1.89,3,3,0,1,0,1,50,1,5,1,2 +67022,7,2,1,80,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,35813.944922,38588.040359,1,100,8,8,2.97,2,2,0,0,1,2,54,1,4,3,NA +67023,7,2,1,62,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,8746.76562,8644.133303,2,97,15,15,5,3,3,0,0,3,2,80,1,3,2,NA +67024,7,2,2,12,NA,3,3,2,12,146,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,71303.309206,77744.474592,2,94,15,15,5,5,5,0,2,0,1,53,1,5,1,5 +67025,7,2,2,78,NA,2,2,2,NA,NA,2,NA,2,1,NA,NA,1,1,NA,2,2,2,1,2,2,1,2,2,NA,17318.187297,23904.945555,2,90,2,2,0.89,1,1,0,0,1,2,78,2,1,1,NA +67026,7,2,1,40,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,35406.972937,38657.357615,2,98,12,12,NA,3,3,0,1,0,2,34,1,4,1,3 +67027,7,2,2,15,NA,1,1,2,16,192,NA,NA,2,1,4,10,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,18166.909002,19929.443801,2,94,7,7,1.33,6,6,0,1,0,1,55,2,2,1,1 +67028,7,2,2,6,NA,1,1,1,6,75,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10118.363218,10311.586628,1,103,7,7,0.51,7,7,3,4,0,1,54,2,1,1,1 +67029,7,2,2,2,NA,5,6,2,2,29,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4938.043177,5373.703942,1,91,5,5,0.89,4,4,2,0,0,1,39,1,4,1,5 +67030,7,2,1,6,NA,4,4,1,6,79,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8714.559478,8865.734494,2,96,12,10,2.17,7,6,2,3,0,1,29,1,4,3,NA +67031,7,2,2,18,NA,4,4,2,18,219,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12857.456314,12921.235691,2,97,5,5,0.92,5,5,0,3,0,2,54,1,3,2,NA +67032,7,2,2,32,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,21351.921325,21766.153521,2,92,6,6,1.35,3,3,1,0,0,2,32,1,5,1,5 +67033,7,2,1,3,NA,4,4,1,3,45,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10615.626123,11270.93481,1,100,8,8,1.61,6,6,1,3,0,1,29,1,5,6,NA +67034,7,2,2,37,NA,1,1,2,NA,NA,2,NA,2,2,4,NA,2,1,2,1,2,2,1,2,2,2,2,2,2,35353.005268,34399.106917,2,94,12,12,NA,4,4,0,2,0,1,47,2,2,1,2 +67035,7,2,2,3,NA,1,1,1,3,40,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,13196.707564,14212.912965,2,96,8,8,1.33,7,7,2,1,1,1,62,2,1,1,1 +67036,7,2,2,16,NA,2,2,2,16,202,NA,NA,1,1,NA,11,NA,NA,NA,2,2,2,2,2,2,1,2,2,1,12536.713942,13553.99602,3,90,12,12,NA,2,2,0,1,0,2,40,2,2,1,NA +67037,7,2,2,66,NA,2,2,2,NA,NA,2,NA,2,1,6,NA,1,1,NA,2,2,2,2,2,2,1,2,2,2,13676.984152,18290.186018,2,91,4,4,0.67,5,4,2,0,2,2,66,2,1,1,NA +67038,7,2,1,11,NA,3,3,2,11,143,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13713.949705,16784.308768,1,99,6,6,1.12,4,4,0,2,0,1,39,1,3,1,3 +67039,7,2,2,31,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,63630.652053,80950.199865,3,90,9,9,3.64,2,2,0,0,0,1,27,2,4,1,5 +67040,7,2,2,19,NA,1,1,2,19,232,2,NA,1,1,NA,15,NA,NA,NA,2,2,2,2,2,2,2,2,2,2,18368.872199,18722.003928,2,94,9,1,0.14,3,1,0,0,0,2,48,2,2,6,NA +67041,7,2,2,36,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,42468.064168,44382.588967,2,101,3,3,0.54,3,3,0,2,0,2,36,1,3,5,NA +67042,7,2,2,9,NA,5,6,1,9,115,NA,NA,1,1,NA,3,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,8022.905544,9049.556422,2,92,6,6,1.34,4,4,1,1,0,1,40,2,3,1,3 +67043,7,2,1,21,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,17583.693727,17703.992112,2,95,15,15,5,3,3,0,0,0,1,59,NA,NA,6,NA +67044,7,2,2,19,NA,5,7,2,19,231,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11975.458482,12291.118947,1,97,15,15,5,6,6,0,3,0,1,47,1,5,1,5 +67045,7,2,2,1,13,3,3,1,NA,15,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,19168.30863,20370.539296,1,94,3,3,0.39,6,6,2,2,0,2,25,1,4,1,2 +67046,7,2,1,66,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,7514.993062,7713.03043,2,90,7,7,2.38,2,2,0,0,1,1,66,1,4,5,NA +67047,7,2,2,54,NA,2,2,1,NA,NA,2,NA,2,2,3,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,35630.227837,35816.036445,2,102,8,8,4.59,1,1,0,0,0,2,54,2,5,5,NA +67048,7,2,2,12,NA,5,7,1,12,148,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12427.929278,12265.18624,1,102,15,15,5,4,4,0,2,0,2,40,2,5,1,4 +67049,7,2,2,78,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,10072.885959,10826.303506,2,100,13,13,NA,1,1,0,0,1,2,78,1,2,2,NA +67050,7,2,2,8,NA,1,1,2,8,105,NA,NA,1,1,NA,3,NA,NA,NA,2,1,2,2,2,2,1,2,2,2,13231.432201,13813.796743,2,97,13,13,NA,3,3,0,1,0,1,28,2,2,1,1 +67051,7,2,2,37,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,13379.422066,13458.148951,2,103,14,14,3.48,5,5,0,2,1,1,43,1,4,1,5 +67052,7,2,1,56,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,28585.875492,29232.915291,1,94,2,2,0.75,1,1,0,0,0,1,56,1,2,3,NA +67053,7,2,1,67,NA,2,2,1,NA,NA,2,NA,2,1,7,NA,1,2,NA,2,2,2,1,2,2,1,2,1,2,8017.002318,8145.424458,2,93,7,7,1.74,4,4,0,0,1,2,44,2,3,1,4 +67054,7,2,2,8,NA,1,1,1,8,104,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17458.526997,18973.577367,1,94,6,6,0.97,6,6,1,3,0,1,40,1,3,1,4 +67055,7,2,2,71,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,28244.319428,29210.271354,1,94,4,4,1.24,2,2,0,0,2,2,71,1,2,1,4 +67056,7,2,1,54,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,11551.71585,11723.869749,2,92,12,12,NA,7,7,2,4,0,1,54,2,2,1,5 +67057,7,2,1,0,2,4,4,2,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6423.674397,6522.268756,1,96,14,14,4.19,3,3,1,0,0,1,44,1,4,6,NA +67058,7,2,1,42,NA,4,4,2,NA,NA,2,NA,2,2,7,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,17602.101156,18151.242681,1,96,15,15,5,4,4,0,1,0,1,42,2,4,1,4 +67059,7,2,2,29,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,4,2,1,2,2,1,2,2,NA,NA,NA,NA,53799.276134,54280.27834,1,94,3,3,0.37,5,5,0,3,0,2,29,1,4,4,NA +67060,7,2,2,16,NA,4,4,2,16,198,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11478.437608,11446.094627,1,96,6,6,1.21,4,4,0,2,0,2,41,1,4,4,NA +67061,7,2,2,36,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,1,1,2,2,1,2,2,1,2,2,1,36955.110877,37344.656251,1,100,14,14,4.45,3,3,1,0,0,1,33,1,4,1,4 +67062,7,2,2,1,14,3,3,1,NA,15,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,46813.021927,47428.160802,1,94,8,8,2.62,3,3,1,0,0,2,26,1,4,5,NA +67063,7,2,1,15,NA,3,3,1,15,188,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,84860.612577,85065.529717,2,98,15,15,5,4,4,0,2,0,1,48,1,3,1,4 +67064,7,2,1,31,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,94433.586146,97510.682342,1,91,14,14,3.06,5,5,2,0,0,2,30,1,5,1,5 +67065,7,2,1,36,NA,4,4,1,NA,NA,2,NA,2,2,4,NA,4,4,NA,1,2,2,1,2,2,1,2,2,1,23654.723526,31640.766843,1,100,4,4,0.99,2,2,0,1,0,1,36,2,4,4,NA +67066,7,2,1,65,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,26087.95381,26422.577042,1,94,4,4,1.24,2,2,0,0,2,2,71,1,2,1,4 +67067,7,2,1,23,NA,2,2,1,NA,NA,2,NA,2,2,3,NA,3,6,NA,2,2,2,NA,NA,NA,2,2,1,2,38474.772527,42632.210531,2,93,3,3,0.43,4,4,0,0,0,1,45,2,2,6,NA +67068,7,2,1,32,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,17879.023129,20112.694262,2,90,2,2,0.87,1,1,0,0,0,1,32,1,5,5,NA +67069,7,2,1,19,NA,3,3,2,19,235,2,NA,1,1,NA,66,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,69216.263169,70543.167563,1,91,15,15,5,3,3,0,0,0,2,50,1,4,1,4 +67070,7,2,2,64,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,14809.997435,15471.247979,2,95,4,4,0.76,4,4,0,1,2,1,80,1,1,2,NA +67071,7,2,2,16,NA,3,3,2,16,194,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,135393.338842,139317.527763,1,97,14,14,3.9,4,4,0,2,0,1,47,1,3,1,5 +67072,7,2,1,11,NA,2,2,1,11,133,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11971.590477,11920.833512,2,100,14,14,3.58,4,4,0,1,0,1,46,2,5,1,5 +67073,7,2,1,24,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,42894.724338,43561.362107,1,98,6,3,0.9,2,1,0,0,0,1,24,1,5,5,NA +67074,7,2,2,37,NA,2,2,1,NA,NA,2,NA,2,1,5,NA,4,1,2,2,2,2,1,2,2,NA,NA,NA,NA,41791.57979,40949.069487,2,102,7,7,1.53,5,5,1,2,0,2,37,2,4,1,4 +67075,7,2,2,14,NA,3,3,1,15,181,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,114661.989457,116814.464785,2,101,14,14,4.86,3,3,0,1,0,1,53,1,4,1,5 +67076,7,2,2,10,NA,3,3,1,10,130,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,23170.920553,22863.220381,3,91,2,2,0.33,4,4,0,3,0,2,31,1,4,4,NA +67077,7,1,2,4,NA,5,7,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5878.066175,0,1,91,15,15,5,5,5,2,1,0,1,40,1,5,1,5 +67078,7,2,2,75,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,28175.708676,28476.609384,1,94,3,3,0.92,1,1,0,0,1,2,75,1,4,1,NA +67079,7,2,1,53,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,20397.472757,21204.731618,1,90,6,6,2.15,2,2,0,0,1,2,79,NA,NA,77,NA +67080,7,2,2,11,NA,3,3,2,11,140,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14287.66096,14320.169639,2,97,7,7,1.92,3,3,0,1,0,1,57,1,4,1,4 +67081,7,2,2,50,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,1,1,NA,2,2,2,2,2,2,NA,NA,NA,NA,22916.776688,24567.079865,1,102,5,5,0.62,7,7,1,3,0,1,49,2,2,1,1 +67082,7,2,1,18,NA,1,1,1,18,224,2,NA,1,1,NA,66,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,22768.423624,22766.421142,2,98,5,5,1.61,2,2,0,0,0,2,44,2,4,3,NA +67083,7,2,1,26,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,111284.977736,116509.217288,3,91,15,15,5,4,4,0,0,1,1,60,NA,NA,4,NA +67084,7,2,2,5,NA,3,3,2,5,65,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,27528.66901,30383.138359,1,95,5,5,1.19,3,3,1,1,0,1,47,1,2,3,NA +67085,7,1,2,80,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,46498.414015,0,1,90,6,6,1.65,2,2,0,0,1,1,55,1,4,77,NA +67086,7,2,1,8,NA,1,1,1,9,108,NA,NA,2,2,3,2,NA,NA,NA,2,1,1,1,2,1,1,2,2,1,17882.621856,17720.218058,2,98,3,3,0.4,6,6,1,2,0,2,29,2,1,4,NA +67087,7,2,2,27,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,15267.012422,14516.051827,1,99,6,6,0.6,7,7,2,1,1,2,69,1,3,2,NA +67088,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,51218.356583,59416.206008,2,98,12,12,NA,2,2,0,0,1,2,80,1,2,2,NA +67089,7,2,2,29,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,NA,NA,NA,NA,24654.107413,23987.341621,1,100,6,6,1.39,4,4,0,3,0,2,29,1,4,5,NA +67090,7,2,2,0,4,2,2,2,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,6752.982789,6610.907942,1,93,12,7,2,4,3,1,0,0,1,43,2,1,1,5 +67091,7,2,2,12,NA,2,2,1,12,149,NA,NA,1,1,NA,6,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,15809.066118,17342.845429,2,93,3,3,0.52,5,5,0,2,0,1,41,2,4,1,4 +67092,7,2,1,76,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,NA,63054.867183,67969.319596,1,90,14,8,4.03,2,1,0,0,2,1,76,1,5,6,NA +67093,7,2,1,10,NA,1,1,1,10,126,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,16288.924956,16868.808147,1,101,3,3,0.41,5,5,0,2,1,2,36,2,4,4,NA +67094,7,2,1,60,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,6038.685119,6085.921613,1,96,15,15,5,2,2,0,0,2,1,60,1,5,1,3 +67095,7,2,1,50,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,28585.875492,28917.983006,1,91,5,5,1.2,3,3,0,0,1,1,58,1,2,1,2 +67096,7,2,1,11,NA,1,1,1,11,141,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11399.23838,11295.714433,1,103,5,5,0.71,6,6,2,2,0,2,31,2,2,1,2 +67097,7,2,2,7,NA,1,1,2,7,85,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15225.935813,15373.8033,2,94,7,7,1.88,4,4,0,2,0,2,28,1,4,4,NA +67098,7,2,2,62,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,NA,9793.924718,10548.859356,2,100,14,4,0.43,7,7,1,3,1,2,62,1,3,5,NA +67099,7,2,1,7,NA,2,2,1,7,94,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,12231.897958,14410.652577,1,100,3,3,0.39,5,5,1,2,0,1,32,2,1,6,NA +67100,7,2,2,29,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,4,3,2,1,2,2,1,2,2,1,2,2,1,20247.768461,26123.76716,2,93,6,6,1.72,2,2,0,1,0,2,29,1,4,3,NA +67101,7,2,2,8,NA,1,1,1,8,101,NA,NA,1,1,NA,2,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,20495.125801,21365.773499,3,92,4,4,0.46,7,7,1,2,0,2,31,2,2,1,1 +67102,7,2,2,13,NA,3,3,2,13,162,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,133500.800632,137370.136946,1,98,5,5,1.39,2,2,0,1,0,1,46,1,4,3,NA +67103,7,2,2,3,NA,2,2,2,3,38,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,11429.37307,12618.334582,2,90,5,5,1.19,3,3,1,0,1,2,60,2,1,4,NA +67104,7,2,1,8,NA,4,4,2,8,106,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9699.683862,9892.534359,2,97,5,5,1.08,3,3,1,1,0,2,27,1,3,5,NA +67105,7,2,2,43,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,34954.173075,36984.739503,2,98,2,2,0.35,3,3,0,1,0,2,43,1,3,1,3 +67106,7,2,1,21,NA,2,2,2,NA,NA,2,NA,2,2,4,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,35338.972549,36508.861705,2,90,2,2,0.25,5,5,0,1,0,2,41,2,4,1,NA +67107,7,2,1,77,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,NA,9662.124837,10964.58979,2,95,2,2,0.6,1,1,0,0,1,1,77,1,3,3,NA +67108,7,2,1,6,NA,1,1,1,6,75,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,11881.117946,11935.814841,1,102,6,6,0.96,5,5,0,2,0,1,32,2,2,1,3 +67109,7,2,2,29,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,47348.206546,48810.979214,1,92,14,14,3.9,4,4,2,0,0,2,29,1,4,1,4 +67110,7,2,2,7,NA,4,4,1,7,90,NA,NA,2,1,3,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7140.212598,7289.797115,2,93,12,12,NA,4,4,1,1,0,2,27,2,4,1,4 +67111,7,2,1,11,NA,1,1,1,11,141,NA,NA,2,2,2,4,NA,NA,NA,2,1,2,2,2,2,1,2,2,2,13870.762641,14200.45921,2,102,7,7,1.33,6,6,1,3,0,1,34,2,2,1,1 +67112,7,2,2,64,NA,1,1,1,NA,NA,2,NA,2,1,8,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,9581.703872,9981.600708,2,96,15,15,5,2,2,0,0,2,1,66,1,5,1,5 +67113,7,2,2,55,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,183805.817006,191979.640064,1,93,15,15,5,2,2,0,0,0,1,58,2,5,1,5 +67114,7,2,1,6,NA,5,6,1,6,73,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7241.695104,8178.415743,1,102,15,15,4.59,4,4,1,1,0,1,35,1,5,1,5 +67115,7,2,1,59,NA,2,2,1,NA,NA,2,NA,2,1,7,NA,5,4,NA,1,2,2,1,2,2,1,2,2,1,28247.128624,28689.709737,2,93,9,9,2.6,4,4,0,0,0,2,58,2,4,4,NA +67116,7,2,2,31,NA,1,1,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,43270.789623,48694.023669,2,99,10,10,5,2,1,0,0,0,2,31,1,5,5,NA +67117,7,2,2,25,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,47973.37979,50072.031476,1,101,2,2,0.22,4,4,1,0,0,2,25,1,4,6,NA +67118,7,2,2,33,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,2,1,2,2,1,2,2,1,2,2,1,88056.562286,93150.302158,2,91,6,6,1.34,4,4,1,2,0,2,33,1,4,3,NA +67119,7,2,2,46,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,110369.721342,112542.856633,1,94,6,6,1.31,3,3,0,0,0,2,46,1,5,6,NA +67120,7,1,2,30,NA,5,6,NA,NA,NA,2,NA,1,1,NA,NA,5,5,3,1,2,2,1,2,2,NA,NA,NA,NA,19305.389921,0,1,93,10,10,5,1,1,0,0,0,2,30,1,5,5,NA +67121,7,2,1,39,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,19091.246741,19659.303383,1,91,5,5,0.89,4,4,2,0,0,1,39,1,4,1,5 +67122,7,2,1,17,NA,4,4,1,17,205,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12296.68269,12194.010773,1,102,7,7,2.72,2,2,0,1,0,2,49,1,4,5,NA +67123,7,2,2,33,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,32501.623429,43787.968887,2,97,5,5,1.63,2,2,1,0,0,2,33,1,3,5,NA +67124,7,2,2,8,NA,3,3,1,8,103,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,23170.920553,22863.220381,1,94,4,4,1.06,2,2,0,1,0,2,26,1,4,5,NA +67125,7,2,1,2,NA,2,2,2,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8331.647763,8595.381151,2,90,15,15,4.2,5,5,1,0,0,2,50,NA,NA,6,NA +67126,7,2,2,22,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,16239.242782,17454.103497,2,101,99,99,NA,3,1,0,0,0,2,22,1,4,5,NA +67127,7,2,1,18,NA,4,4,1,19,228,2,NA,1,1,NA,12,NA,NA,NA,1,2,2,NA,NA,NA,1,2,2,1,14650.502937,14679.468181,2,102,14,14,3.25,5,5,1,1,0,2,32,1,4,1,3 +67128,7,2,2,47,NA,4,4,2,NA,NA,2,NA,2,1,7,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,18811.641937,20880.310604,2,90,3,3,1.04,1,1,0,0,0,2,47,2,4,5,NA +67129,7,2,2,24,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,18723.98095,17927.802584,2,95,10,10,2.32,6,6,1,2,0,1,44,1,4,1,4 +67130,7,2,2,10,NA,2,2,1,10,121,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15352.601806,15746.071667,2,102,15,12,NA,5,4,0,3,0,1,42,2,4,6,NA +67131,7,2,1,8,NA,3,3,1,8,103,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18834.739821,20852.023287,1,94,5,5,1.2,3,3,0,1,0,1,49,1,4,5,NA +67132,7,2,2,32,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,1,1,2,2,1,2,2,1,2,2,1,36598.587714,38321.205688,1,97,7,7,1.74,4,4,0,3,0,2,32,1,4,5,NA +67133,7,2,1,33,NA,1,1,1,NA,NA,2,NA,2,2,5,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,32856.012738,32608.038024,2,103,77,77,NA,5,5,1,2,0,2,30,1,2,1,2 +67134,7,2,1,29,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,40333.47326,40883.249623,2,99,9,9,4.92,1,1,0,0,0,1,29,1,5,5,NA +67135,7,2,2,58,NA,4,4,2,NA,NA,2,NA,2,2,2,NA,1,2,NA,1,2,1,1,2,2,NA,NA,NA,NA,17277.829496,17117.256291,1,98,15,15,5,6,6,3,0,0,1,37,2,5,1,4 +67136,7,2,2,11,NA,5,7,2,11,137,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18348.624469,20109.577944,2,90,77,77,NA,6,6,0,4,0,2,41,NA,NA,4,NA +67137,7,2,1,67,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,1,1,NA,2,2,2,1,2,2,2,2,2,2,8479.54701,8948.405799,2,98,6,6,2.04,2,2,0,0,2,2,66,1,1,1,1 +67138,7,2,2,8,NA,2,2,2,8,102,NA,NA,2,1,3,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15583.587534,16935.930722,1,93,15,15,5,4,4,0,2,0,1,50,1,5,1,5 +67139,7,2,2,0,1,1,1,2,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8907.98929,8720.575629,1,95,1,1,0,3,3,1,0,0,2,21,1,2,6,NA +67140,7,1,2,12,NA,5,7,NA,NA,NA,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5268.765205,0,1,99,9,9,2.68,4,4,0,2,0,1,43,2,3,1,NA +67141,7,2,2,72,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,72114.232586,74326.626155,2,96,12,12,NA,2,2,0,0,2,1,77,1,5,1,4 +67142,7,2,1,2,NA,4,4,2,2,25,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6992.24593,7710.094516,2,97,1,1,0.33,2,2,1,0,0,2,24,1,2,5,NA +67143,7,2,1,33,NA,2,2,2,NA,NA,2,NA,2,2,4,NA,3,5,NA,2,2,2,2,2,2,2,2,2,2,34887.439952,34624.133414,2,94,14,8,3.06,5,2,0,0,0,1,24,2,4,5,NA +67144,7,2,1,54,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,13629.653758,14595.525499,1,90,15,15,5,5,5,0,3,0,2,46,2,4,1,5 +67145,7,2,2,0,9,4,4,2,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,3320.8855,3567.679794,2,99,NA,77,NA,7,7,1,0,1,2,51,1,2,1,3 +67146,7,2,2,7,NA,3,3,2,7,87,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,24070.467912,25563.654853,1,95,6,6,1.09,5,5,0,3,0,1,31,1,4,1,4 +67147,7,2,1,1,22,4,4,2,NA,23,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6347.215153,6541.084247,2,95,6,6,1.3,4,4,1,1,0,1,38,1,4,1,4 +67148,7,2,2,68,NA,2,2,2,NA,NA,2,NA,2,1,9,NA,3,2,NA,2,2,2,2,2,2,1,2,2,2,9716.805546,10855.679158,2,90,2,2,0.64,1,1,0,0,1,2,68,2,3,2,NA +67149,7,2,2,65,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,9518.80186,9943.806181,2,100,6,6,2.31,2,2,0,0,2,2,65,1,4,1,2 +67150,7,2,1,0,7,4,4,2,NA,8,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6246.568228,6909.306675,2,95,1,1,0.13,2,2,1,0,0,2,22,1,3,5,NA +67151,7,2,1,5,NA,4,4,1,5,60,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10040.033098,10162.494907,1,100,1,1,0.26,2,2,1,0,0,2,28,1,3,5,NA +67152,7,2,2,10,NA,1,1,1,10,124,NA,NA,1,1,NA,3,NA,NA,NA,2,1,1,1,2,1,1,2,2,1,14414.529053,14932.182215,2,96,3,3,0.46,5,5,1,2,0,1,37,1,1,1,2 +67153,7,2,2,23,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,18097.801029,17538.193115,2,100,3,3,0.27,7,7,2,1,0,2,41,1,2,5,NA +67154,7,2,1,4,NA,5,7,2,4,58,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10276.262805,11525.953064,1,97,15,15,4.77,4,4,1,1,0,1,41,2,4,1,5 +67155,7,2,2,2,NA,5,6,1,2,27,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7128.631964,7757.55827,3,91,15,15,5,4,4,1,1,0,1,39,2,5,1,5 +67156,7,2,2,10,NA,2,2,1,10,123,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12307.832776,13375.906079,2,93,10,10,2.26,6,6,0,4,0,1,34,1,4,1,3 +67157,7,2,2,18,NA,5,6,2,18,222,2,NA,2,1,3,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,6937.463063,7435.682574,3,90,99,99,NA,4,4,0,1,0,1,40,2,3,6,NA +67158,7,2,1,14,NA,2,2,1,14,178,NA,NA,2,2,3,9,NA,NA,NA,2,1,2,1,2,2,1,2,1,2,14117.225999,14174.690553,2,93,4,4,0.56,5,5,0,2,0,1,37,NA,NA,1,1 +67159,7,2,1,80,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,1,1,2,1,1,2,2,NA,11550.158096,12419.035396,2,92,5,5,1.08,3,3,0,0,2,1,46,NA,NA,5,NA +67160,7,2,2,15,NA,4,4,2,15,185,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12209.74498,12444.407921,2,90,14,14,4.25,4,4,0,2,1,2,45,2,5,5,NA +67161,7,1,2,80,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,48113.658256,0,1,90,5,5,2.15,1,1,0,0,1,2,80,1,3,2,NA +67162,7,2,1,4,NA,5,6,2,4,54,NA,NA,2,2,1,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8402.098771,9423.873047,3,91,5,5,1.08,3,3,1,0,0,1,29,2,5,1,5 +67163,7,2,1,4,NA,1,1,2,4,52,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,14505.510202,14964.673559,2,94,4,4,0.73,5,5,2,1,0,1,35,2,1,6,NA +67164,7,2,2,13,NA,5,6,1,13,165,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10142.281747,10534.471105,3,91,15,15,5,4,4,0,2,0,1,44,2,5,1,5 +67165,7,2,2,46,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,35126.205635,35160.69801,1,101,2,2,0.66,1,1,0,0,0,2,46,1,4,3,NA +67166,7,2,2,9,NA,2,2,2,9,116,NA,NA,2,1,3,2,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,16099.075547,16268.329655,1,93,5,5,0.84,5,5,1,2,0,2,52,2,1,3,NA +67167,7,2,1,8,NA,2,2,2,8,107,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9390.522479,10327.334743,2,90,3,3,0.7,3,3,1,1,0,2,25,1,1,1,NA +67168,7,2,2,11,NA,3,3,1,11,142,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18800.96526,18551.296274,1,94,3,3,0.37,5,5,0,3,0,2,29,1,4,4,NA +67169,7,2,1,30,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,27572.205373,27179.185736,1,100,7,7,3.58,1,1,0,0,0,1,30,1,5,5,NA +67170,7,2,1,13,NA,2,2,2,13,163,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,16033.31661,17623.465787,2,90,5,5,0.76,5,5,0,4,0,2,32,1,2,3,NA +67171,7,2,2,51,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,4,NA,1,2,2,1,2,2,1,2,2,1,19060.786733,19662.793534,2,97,4,4,0.81,4,4,1,0,0,2,51,1,2,4,NA +67172,7,2,1,5,NA,1,1,1,5,63,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,19885.456648,19912.326587,1,92,10,10,3.04,4,4,2,0,0,2,37,2,5,1,5 +67173,7,2,2,21,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,4,5,3,1,2,2,1,2,2,1,2,2,1,19463.594852,21649.931723,3,92,6,6,1.6,3,3,0,0,1,2,77,1,3,99,NA +67174,7,2,2,25,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,1,1,2,2,1,2,2,1,2,2,1,100264.332334,116996.29597,1,99,7,7,3.63,1,1,0,0,0,2,25,1,5,5,NA +67175,7,2,1,49,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,31540.022655,31610.470938,2,94,NA,77,NA,2,1,0,0,0,1,49,1,3,3,NA +67176,7,2,1,17,NA,4,4,2,17,206,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11834.781205,12120.23702,2,90,8,8,2.59,3,3,0,2,0,2,35,1,4,6,NA +67177,7,2,2,74,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,66567.821082,69187.508251,1,94,3,3,0.88,2,2,0,0,1,2,74,1,2,2,NA +67178,7,2,1,4,NA,1,1,1,4,53,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,17865.135763,18430.646082,3,92,3,3,0.51,5,5,1,2,0,2,34,2,1,6,NA +67179,7,2,2,20,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,3,1,2,2,1,2,2,NA,NA,NA,NA,30275.274308,28786.080652,2,101,2,2,0.51,1,1,0,0,0,2,20,1,4,5,NA +67180,7,2,2,78,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,14534.533756,15507.238104,1,96,6,6,2.06,2,2,0,0,2,1,68,2,3,1,2 +67181,7,2,1,40,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,27356.080541,28721.124083,1,101,7,7,1.82,4,4,2,0,0,2,27,1,2,1,3 +67182,7,2,2,44,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,19130.246369,19076.4893,1,98,10,10,3.77,3,3,0,1,0,1,48,NA,NA,1,4 +67183,7,2,2,52,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,21143.964074,20709.49715,1,100,15,15,3.7,5,5,0,3,0,1,51,1,5,1,5 +67184,7,2,1,42,NA,1,1,2,NA,NA,1,2,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,31640.296506,31176.023929,2,94,15,9,5,2,1,0,0,0,1,42,1,4,6,NA +67185,7,2,2,51,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,5,1,NA,1,2,2,1,2,1,1,2,2,NA,24178.173487,24760.288626,1,92,7,7,2.1,3,3,0,0,0,1,24,2,4,5,NA +67186,7,2,1,6,NA,2,2,1,7,85,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11971.590477,11920.833512,2,100,14,14,3.58,4,4,1,1,0,1,33,1,4,1,5 +67187,7,2,2,15,NA,1,1,1,15,188,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12996.753859,13369.730018,1,103,7,7,0.51,7,7,3,4,0,1,54,2,1,1,1 +67188,7,2,2,13,NA,4,4,1,13,161,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14166.687432,14623.20249,1,100,6,6,1.39,4,4,0,3,0,2,29,1,4,5,NA +67189,7,2,2,70,NA,5,6,1,NA,NA,2,NA,2,1,8,NA,3,2,NA,1,2,1,1,2,1,1,2,2,NA,12813.709202,14706.046404,2,103,4,4,1.43,1,1,0,0,1,2,70,2,3,2,NA +67190,7,2,2,36,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,77778.949308,79987.938327,1,101,14,14,4.5,3,3,0,1,0,1,39,1,2,1,5 +67191,7,2,2,33,NA,3,3,1,NA,NA,2,NA,2,7,2,NA,2,1,2,1,2,2,1,2,2,1,2,2,1,29733.812317,32603.623062,1,101,6,6,1.65,2,2,0,0,0,1,47,1,4,1,2 +67192,7,2,2,55,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,126117.5094,130777.186989,2,98,8,8,2.7,3,3,0,0,1,2,71,NA,NA,2,NA +67193,7,2,1,37,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,18289.793332,19321.216647,1,99,8,8,1.76,5,5,0,2,1,1,37,1,4,1,3 +67194,7,2,1,51,NA,4,4,2,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,21762.20618,21775.974398,1,91,10,10,2.56,5,5,0,3,0,1,51,2,5,1,4 +67195,7,2,1,49,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,133542.212862,137840.368471,1,94,9,9,3.97,2,2,0,0,0,1,49,1,3,1,3 +67196,7,2,2,5,NA,1,1,1,5,69,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11859.546176,12772.78418,1,102,8,8,1.33,7,7,1,4,0,2,32,1,3,1,2 +67197,7,2,2,73,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,66253.989241,66961.54455,1,101,15,15,5,2,2,0,0,2,2,73,1,4,1,4 +67198,7,2,1,50,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,32461.799549,32721.879701,1,101,3,3,0.66,2,2,0,0,1,1,67,1,2,3,NA +67199,7,2,1,41,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,15574.704266,15518.439557,2,92,15,15,5,2,2,0,0,0,2,36,1,5,1,5 +67200,7,2,1,30,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,97074.465027,101633.534325,1,93,15,8,4.41,3,1,0,0,0,1,30,1,5,5,NA +67201,7,2,1,40,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,20953.00978,22383.074498,2,97,3,3,0.46,5,5,0,3,0,1,40,1,2,1,3 +67202,7,2,1,11,NA,5,6,2,11,133,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8423.270513,9127.622487,1,90,15,15,5,5,5,0,3,0,2,46,2,4,1,5 +67203,7,2,1,33,NA,4,4,2,NA,NA,2,NA,2,1,7,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,17879.023129,20112.694262,2,90,5,5,2.02,1,1,0,0,0,1,33,2,3,5,NA +67204,7,2,1,22,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,20333.447198,20233.229833,1,98,6,6,1.72,2,2,0,0,0,2,53,1,5,2,NA +67205,7,2,1,5,NA,5,7,2,5,68,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8100.706553,8491.571292,1,98,14,14,3.9,4,4,2,0,0,1,39,1,5,1,4 +67206,7,2,1,8,NA,5,7,1,8,105,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,21087.869274,22876.159598,1,101,5,5,1.26,3,3,0,1,1,2,42,1,3,5,NA +67207,7,2,2,10,NA,4,4,2,10,122,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7136.421849,7489.546444,1,90,9,9,1.65,7,7,0,4,0,1,36,1,4,1,4 +67208,7,2,1,67,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,7117.971973,7173.650989,2,100,6,6,2.31,2,2,0,0,2,2,65,1,4,1,2 +67209,7,2,2,80,NA,3,3,1,NA,NA,2,NA,2,1,9,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,51644.110977,57877.507418,1,102,5,5,1.84,1,1,0,0,1,2,80,2,5,2,NA +67210,7,2,2,63,NA,4,4,1,NA,NA,2,NA,2,1,4,NA,3,1,NA,1,2,1,1,2,2,1,1,1,NA,10585.751811,11058.394307,2,93,6,6,1.13,4,4,0,0,2,1,60,2,3,1,3 +67211,7,2,1,3,NA,4,4,2,3,47,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8973.990262,9895.291699,2,95,3,3,0.43,4,4,2,0,0,2,23,1,2,5,NA +67212,7,1,2,67,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,125706.50355,0,3,91,14,14,5,2,1,0,0,1,2,67,1,5,5,NA +67213,7,2,1,4,NA,4,4,2,4,52,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9304.437652,10259.663981,2,97,1,1,0.27,2,2,1,0,0,2,20,1,2,5,NA +67214,7,2,1,39,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,99283.360764,103932.649449,3,91,14,14,5,1,1,0,0,0,1,39,1,5,5,NA +67215,7,2,1,20,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,1,5,NA,1,2,2,2,2,2,1,2,2,1,40899.412129,44211.773156,1,94,5,5,0.57,7,7,2,1,0,1,58,2,1,1,1 +67216,7,2,2,0,7,1,1,1,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6744.839779,7193.080406,1,103,5,5,1.02,4,4,2,0,0,1,25,1,2,1,4 +67217,7,2,1,41,NA,1,1,1,NA,NA,2,NA,2,2,3,NA,2,6,NA,2,2,2,2,2,2,2,2,2,2,37402.70356,39087.586144,2,102,7,7,1.89,3,3,0,1,0,1,41,2,2,6,NA +67218,7,2,1,0,8,3,3,2,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13392.309303,13804.825901,1,99,15,15,5,5,5,3,0,0,2,34,1,5,1,5 +67219,7,2,2,32,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,61212.189461,64753.083655,3,90,15,15,5,3,3,1,0,0,1,31,1,5,1,5 +67220,7,2,1,33,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,106105.629898,111686.437619,1,100,14,9,4.92,3,1,1,0,0,1,33,1,5,5,NA +67221,7,2,1,22,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,17583.693727,17293.36291,2,95,9,9,1.81,6,6,1,1,0,2,56,1,4,3,NA +67222,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,62796.637452,70136.543572,2,102,6,6,1.15,5,5,0,0,2,1,80,1,5,1,1 +67223,7,2,1,40,NA,5,6,1,NA,NA,2,NA,2,1,3,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,18898.73153,22670.159935,1,100,5,5,0.74,6,6,0,3,0,1,40,2,3,1,4 +67224,7,2,1,2,NA,4,4,2,3,36,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6760.288309,6966.774293,1,96,99,99,NA,4,4,1,1,0,2,35,2,3,1,3 +67225,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,8318.523894,9127.657215,3,90,3,3,1.07,1,1,0,0,1,1,80,1,5,2,NA +67226,7,2,2,43,NA,4,4,2,NA,NA,2,NA,2,2,6,NA,3,5,2,1,2,2,1,2,2,NA,NA,NA,NA,14831.744106,14871.922635,3,90,5,5,0.87,4,4,0,0,0,2,43,2,3,5,NA +67227,7,2,2,17,NA,4,4,2,17,208,2,NA,2,2,4,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11072.776368,11285.58755,3,90,9,9,4.1,2,2,0,1,0,2,41,2,5,5,NA +67228,7,2,1,41,NA,5,6,2,NA,NA,2,NA,2,1,5,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,14823.307875,15546.691363,1,96,8,8,2.62,3,3,0,1,0,1,41,2,3,1,5 +67229,7,2,1,65,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,138075.879417,141933.339512,2,91,7,7,1.61,4,4,0,0,3,1,65,1,3,6,NA +67230,7,2,1,59,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,25969.864445,26997.658596,1,97,15,15,5,2,2,0,0,0,1,59,1,5,1,5 +67231,7,2,1,18,NA,4,4,1,18,219,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,16147.713323,16532.569027,1,92,5,5,0.95,4,4,0,2,0,2,33,1,4,5,NA +67232,7,2,2,48,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,35933.117795,36141.582386,1,98,1,1,0.18,1,1,0,0,0,2,48,1,5,1,NA +67233,7,2,2,7,NA,4,4,2,7,92,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8757.841043,9034.425418,2,97,2,2,0.49,3,3,0,1,0,2,27,1,4,5,NA +67234,7,2,1,12,NA,1,1,1,12,149,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,20705.832333,21431.576705,1,100,9,9,2.02,6,6,0,3,1,2,39,1,4,1,5 +67235,7,2,1,6,NA,4,4,2,6,74,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14125.862146,14295.209168,1,97,5,5,0.91,4,4,0,3,0,2,44,1,4,5,NA +67236,7,2,2,48,NA,1,1,1,NA,NA,2,NA,2,2,77,NA,2,1,NA,2,2,2,2,2,2,2,2,2,2,43535.993088,43763.029589,2,102,77,77,NA,3,3,0,0,0,2,48,2,2,1,3 +67237,7,2,2,51,NA,1,1,2,NA,NA,2,NA,2,2,3,NA,1,4,NA,2,2,2,1,2,2,2,2,2,2,23953.14388,24078.057488,1,90,12,12,NA,4,4,0,0,0,1,54,2,4,1,2 +67238,7,2,2,15,NA,5,6,1,15,189,NA,NA,2,1,4,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7382.152016,8028.485773,1,94,14,14,2.78,6,5,0,2,1,1,61,1,4,1,5 +67239,7,2,2,50,NA,2,2,2,NA,NA,2,NA,2,1,5,NA,1,4,NA,2,2,2,2,2,1,NA,NA,NA,NA,24004.6026,28934.42641,2,91,4,4,0.94,3,3,0,1,0,2,50,2,1,4,NA +67240,7,2,2,5,NA,1,1,1,5,63,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,19235.084509,21236.049482,3,92,8,8,2,4,4,2,0,0,1,30,1,4,1,4 +67241,7,1,1,80,NA,3,3,NA,NA,NA,1,1,1,1,NA,NA,3,99,NA,1,1,2,1,2,2,NA,NA,NA,NA,14359.447628,0,1,97,4,4,0.81,3,3,0,0,2,1,80,1,3,99,NA +67242,7,2,1,2,NA,4,4,1,2,35,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8009.966208,8832.297541,2,96,6,6,1.35,3,3,1,1,0,2,23,1,2,5,NA +67243,7,2,2,68,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,7869.59899,8538.749518,1,96,3,3,0.68,2,2,0,0,1,2,68,1,2,3,NA +67244,7,2,2,13,NA,3,3,1,13,158,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,28650.637159,30356.286382,2,100,2,2,0.38,3,3,0,2,0,2,35,1,4,5,NA +67245,7,2,1,27,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,2,5,NA,1,2,2,1,2,1,1,2,2,1,9177.295801,9548.31812,2,92,77,77,NA,4,4,0,0,0,1,27,2,2,5,NA +67246,7,2,1,15,NA,3,3,2,15,185,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,68701.580401,72973.564721,2,94,15,15,5,5,5,0,2,0,1,53,1,5,1,5 +67247,7,2,1,8,NA,5,6,2,8,102,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8151.552109,8792.161653,1,90,14,14,3.33,5,5,1,2,0,1,41,1,5,1,5 +67248,7,2,2,14,NA,1,1,1,14,174,NA,NA,2,2,4,7,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,15690.47168,16407.081535,1,102,5,5,0.62,7,7,1,3,0,1,49,2,2,1,1 +67249,7,2,2,58,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,16663.192678,16751.306683,2,92,NA,4,1.65,2,1,0,0,1,2,58,2,4,5,NA +67250,7,2,2,43,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,5,6,2,1,2,2,1,2,2,1,2,2,1,42424.587753,44729.774642,2,102,4,4,1.38,2,1,0,0,0,2,43,1,5,6,NA +67251,7,2,2,7,NA,4,4,2,8,96,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,1,2,NA,NA,NA,NA,7814.742747,7984.793423,2,95,2,2,0.26,4,4,0,2,0,2,44,NA,NA,5,NA +67252,7,2,2,24,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,16844.740449,17983.530016,3,91,3,3,1.1,1,1,0,0,0,2,24,1,5,5,NA +67253,7,2,2,10,NA,3,3,2,10,121,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,44941.581862,44344.776378,2,94,10,10,2.91,4,4,0,2,0,2,38,1,4,1,4 +67254,7,2,1,8,NA,1,1,1,9,108,NA,NA,2,2,2,2,NA,NA,NA,2,1,2,2,2,2,2,2,2,2,13870.762641,13985.149896,2,102,6,4,1.02,6,2,0,4,0,2,43,2,1,5,NA +67255,7,2,2,38,NA,3,3,2,NA,NA,2,NA,2,1,4,NA,3,1,2,1,2,2,1,2,2,1,1,2,NA,53830.599426,56664.989337,1,99,77,77,NA,4,4,1,1,0,1,31,2,3,1,3 +67256,7,2,1,10,NA,1,1,1,11,132,NA,NA,2,2,3,4,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,15456.524105,16140.282926,1,100,99,99,NA,6,6,0,1,0,2,22,2,3,1,3 +67257,7,2,2,9,NA,5,6,2,9,112,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8556.454265,9137.012028,1,90,15,15,5,5,5,0,2,0,1,47,2,5,1,5 +67258,7,2,2,73,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,54256.870337,62240.534341,2,94,6,6,2.04,2,2,0,0,2,1,75,1,3,1,3 +67259,7,2,1,45,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,90081.78624,90194.909743,2,100,15,15,4.5,6,6,0,4,0,1,45,1,5,1,5 +67260,7,2,1,3,NA,3,3,1,3,47,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,27542.701065,31074.71228,1,94,7,7,1.29,6,6,1,3,0,1,38,1,3,1,2 +67261,7,2,1,57,NA,3,3,2,NA,NA,2,NA,2,1,99,NA,1,5,NA,1,2,2,1,2,2,1,2,2,1,20160.790176,25538.533486,3,90,77,99,NA,2,1,0,0,1,1,62,2,5,3,NA +67262,7,1,2,68,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,2,4,NA,1,2,1,1,2,1,NA,NA,NA,NA,9793.924718,0,2,100,2,2,0.39,3,3,0,0,1,2,45,1,2,5,NA +67263,7,2,2,3,NA,1,1,1,3,42,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,15979.952759,16987.381382,2,102,6,6,1.03,5,5,1,1,0,1,37,1,2,1,2 +67264,7,2,2,77,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,81062.798322,86779.337922,1,101,4,4,1.61,1,1,0,0,1,2,77,1,2,2,NA +67265,7,2,2,0,5,4,4,2,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4681.626184,4732.744026,1,96,6,6,1.31,4,3,1,0,0,2,27,2,4,1,3 +67266,7,2,1,36,NA,1,1,1,NA,NA,2,NA,2,1,5,NA,1,1,NA,2,2,2,1,2,2,2,2,2,2,51543.062078,51154.050295,3,92,7,7,1.3,5,5,1,2,0,2,33,2,2,1,1 +67267,7,1,1,10,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10524.718724,0,1,96,77,77,NA,2,2,0,1,0,2,35,1,3,3,NA +67268,7,2,2,18,NA,3,3,2,18,217,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,NA,NA,NA,NA,100004.689924,107460.712122,1,90,12,12,NA,2,2,0,0,0,2,45,2,3,4,NA +67269,7,2,1,59,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,21762.20618,22687.256739,1,91,15,15,5,4,4,0,1,0,2,51,2,4,1,5 +67270,7,2,2,42,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,34874.122648,36144.248604,3,92,6,6,1.41,4,3,0,1,0,1,41,1,4,1,4 +67271,7,2,2,4,NA,4,4,2,4,54,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8833.042831,9629.276723,1,99,4,4,0.41,7,7,2,4,0,2,43,1,4,4,NA +67272,7,2,2,11,NA,3,3,1,12,144,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18417.272091,18465.044105,1,94,5,5,1.04,4,4,0,2,0,2,29,1,3,1,3 +67273,7,2,1,44,NA,1,1,1,NA,NA,2,NA,2,2,6,NA,1,1,NA,2,2,2,1,2,2,2,2,2,2,31740.385214,31855.807763,2,96,5,5,0.78,5,5,0,2,0,1,37,2,1,5,NA +67274,7,2,2,46,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,1,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,19150.604366,19251.871661,3,91,14,9,2.68,6,4,0,0,2,1,48,2,1,1,1 +67275,7,2,1,77,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,16603.347511,18119.902269,2,98,3,3,0.88,2,2,0,0,2,1,77,1,1,1,3 +67276,7,2,2,60,NA,2,2,2,NA,NA,2,NA,2,2,6,NA,2,3,NA,2,2,2,2,2,2,1,2,2,2,9716.805546,10855.679158,2,90,7,7,1.34,5,5,0,1,2,1,61,2,1,4,NA +67277,7,2,2,4,NA,5,6,1,4,59,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5307.591514,5454.53335,2,102,3,3,0.38,5,5,3,0,0,2,30,2,2,1,4 +67278,7,2,1,2,NA,2,2,1,2,29,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12493.910388,13386.323284,2,98,1,1,0.14,3,2,2,0,0,2,27,1,3,6,NA +67279,7,2,2,32,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,21765.629914,22790.091994,2,90,2,2,0.38,4,4,1,2,0,2,32,1,4,5,NA +67280,7,2,1,27,NA,1,1,1,NA,NA,1,1,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,37911.437415,38428.199561,2,103,12,6,2.24,2,1,0,0,0,1,27,1,4,5,NA +67281,7,2,2,42,NA,1,1,2,NA,NA,2,NA,2,2,77,NA,2,6,2,2,2,2,2,2,2,2,2,2,2,31235.666551,35013.570975,2,94,77,77,NA,3,3,0,1,0,2,42,2,2,6,NA +67282,7,2,2,8,NA,1,1,1,8,102,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,2,2,2,1,2,2,2,13028.403003,13395.598637,2,96,6,6,1.11,5,5,0,3,0,2,32,2,3,1,2 +67283,7,2,2,56,NA,5,6,2,NA,NA,2,NA,2,1,5,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,12441.719186,12605.354834,1,96,15,15,5,5,5,0,0,0,1,58,2,5,1,5 +67284,7,2,2,12,NA,5,6,1,12,147,NA,NA,2,2,1,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6370.316505,6496.587233,2,94,8,8,1.8,6,6,0,1,2,1,74,2,5,1,5 +67285,7,2,2,70,NA,2,2,2,NA,NA,2,NA,2,1,9,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,22166.463682,23916.215243,3,91,6,6,2.89,1,1,0,0,1,2,70,2,5,2,NA +67286,7,2,2,6,NA,4,4,2,6,75,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6655.097829,7106.52929,2,99,15,15,4.9,7,7,1,4,0,2,53,1,5,1,5 +67287,7,2,2,10,NA,5,6,1,10,128,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7932.110938,8316.610099,3,92,8,8,0.91,7,7,3,3,1,1,61,NA,NA,1,4 +67288,7,2,1,24,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,17446.328105,17921.312041,1,92,15,15,5,2,2,0,0,0,2,49,1,5,3,NA +67289,7,2,1,5,NA,5,6,1,5,69,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7042.228842,7898.630137,2,103,14,14,3.47,4,4,1,0,1,1,47,2,5,1,5 +67290,7,2,1,25,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,34099.599202,35276.751365,1,94,7,1,0.09,5,1,0,0,0,1,46,1,4,1,4 +67291,7,2,2,74,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,35160.494695,36239.184013,1,100,4,4,1.16,2,2,0,0,2,1,74,1,3,1,5 +67292,7,2,1,8,NA,4,4,1,8,107,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9022.8939,9530.778148,2,100,6,6,0.99,5,5,0,3,0,2,40,1,3,1,3 +67293,7,2,1,53,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,132969.642582,137509.365878,2,91,15,15,5,4,4,0,2,0,1,53,1,5,1,4 +67294,7,1,2,44,NA,2,2,NA,NA,NA,2,NA,2,1,5,NA,3,1,3,1,2,2,1,2,2,NA,NA,NA,NA,32606.880052,0,2,93,6,6,1.48,4,4,0,1,0,1,53,2,2,1,3 +67295,7,2,2,4,NA,5,6,2,4,52,NA,NA,2,2,2,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4938.043177,4932.827461,1,91,14,14,4.32,3,3,1,0,0,1,34,2,5,1,3 +67296,7,2,2,15,NA,4,4,2,15,182,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12265.19283,12230.632995,2,97,2,2,0.21,7,7,2,3,0,2,32,1,4,5,NA +67297,7,2,1,29,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,123110.069898,136669.986833,1,101,8,4,1.34,2,1,0,0,0,2,20,1,4,6,NA +67298,7,2,2,24,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,17377.366864,16840.035727,2,99,6,6,1.11,5,5,1,2,0,2,41,1,2,5,NA +67299,7,2,2,7,NA,2,2,2,7,84,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15148.721588,16225.089736,2,91,2,2,0.42,3,3,1,1,0,2,27,1,3,5,NA +67300,7,2,1,72,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,71709.98031,77299.00621,2,91,9,9,2.6,4,4,0,0,2,1,72,1,4,1,5 +67301,7,1,2,18,NA,3,3,NA,NA,NA,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,NA,NA,NA,NA,45824.798023,0,1,97,1,1,0.09,2,1,0,0,0,1,24,1,3,6,NA +67302,7,2,2,3,NA,4,4,1,3,41,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16749.124902,18717.057678,2,97,1,1,0.13,4,4,2,0,1,2,62,1,2,4,NA +67303,7,2,1,8,NA,3,3,2,8,104,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,82670.203859,85919.643529,1,97,15,15,5,5,5,0,3,0,2,47,2,5,1,5 +67304,7,2,2,12,NA,2,2,1,12,151,NA,NA,2,2,2,5,NA,NA,NA,2,1,2,2,2,2,1,2,1,2,12712.538972,13945.896408,2,93,6,6,0.93,5,5,1,2,0,1,40,2,4,1,4 +67305,7,2,2,20,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,29040.300396,28462.118402,2,101,3,1,0.22,3,1,0,0,0,2,20,2,4,5,NA +67306,7,2,1,51,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,4,NA,1,2,2,1,2,2,1,2,2,1,19186.370211,20284.349464,2,97,2,2,0.27,4,4,0,2,0,1,51,1,2,4,NA +67307,7,2,1,20,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,21022.682584,21611.637105,1,100,3,3,0.43,4,4,2,0,0,1,20,1,3,6,NA +67308,7,2,1,21,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,10131.732483,10407.573345,2,103,12,3,1.07,5,1,0,1,0,2,47,NA,NA,3,NA +67309,7,2,1,72,NA,2,2,1,NA,NA,2,NA,2,2,2,NA,5,1,NA,2,2,1,2,2,2,2,2,2,NA,15435.262366,15704.333986,2,93,9,9,3.14,3,3,0,0,2,1,43,NA,NA,5,NA +67310,7,2,1,46,NA,2,2,1,NA,NA,2,NA,2,1,NA,NA,2,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,49060.272708,48961.70392,1,92,14,5,1.88,3,1,0,1,0,2,39,2,4,6,NA +67311,7,2,2,27,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,50915.06085,52488.027702,3,92,8,8,2,4,4,2,0,0,1,30,1,4,1,4 +67312,7,2,1,45,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,152858.509804,160001.813639,1,95,9,9,2.66,4,4,0,2,0,1,45,1,3,1,3 +67313,7,2,1,11,NA,1,1,1,11,136,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17882.621856,18280.794545,3,92,8,8,1.55,6,6,1,3,0,2,38,1,5,1,4 +67314,7,2,1,62,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,40561.050563,40941.458273,2,101,3,3,0.98,2,2,0,0,2,1,62,1,4,1,3 +67315,7,2,2,51,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,15521.115746,15890.452621,2,100,7,7,1.79,4,4,0,1,0,2,51,1,3,3,NA +67316,7,2,2,48,NA,1,1,1,NA,NA,2,NA,2,1,7,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,32208.300114,33976.532975,1,102,6,6,1.34,4,4,0,1,0,2,48,2,3,1,1 +67317,7,2,1,0,10,4,4,1,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6275.847063,6372.172481,2,100,14,14,3.58,4,4,1,1,0,2,31,1,5,1,4 +67318,7,2,1,26,NA,4,4,2,NA,NA,2,NA,2,2,2,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,12364.328404,12075.509308,1,96,10,10,1.8,7,7,1,1,0,1,57,2,1,1,3 +67319,7,2,1,6,NA,4,4,2,6,76,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8065.706636,8519.712345,2,99,1,1,0.03,3,3,0,1,0,2,56,1,3,5,NA +67320,7,2,1,19,NA,2,2,2,19,230,2,NA,1,1,NA,12,NA,NA,NA,2,2,2,2,2,2,1,2,2,1,14081.782012,14782.02856,2,90,7,7,1.34,5,5,0,1,2,1,61,2,1,4,NA +67321,7,2,1,53,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,24930.322327,24899.923342,2,91,4,4,1.22,2,2,0,0,0,1,53,1,4,1,4 +67322,7,2,1,20,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,NA,NA,NA,1,2,2,1,20308.910079,25155.898326,1,90,NA,NA,NA,2,2,0,0,0,2,40,NA,NA,5,NA +67323,7,2,2,10,NA,1,1,1,10,122,NA,NA,2,2,3,3,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,20495.125801,21027.07407,3,92,3,3,0.52,5,5,2,1,0,2,29,2,1,1,3 +67324,7,2,1,7,NA,5,6,2,7,95,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7193.657603,7758.988679,2,90,14,14,4.32,3,3,0,1,0,1,48,2,4,1,5 +67325,7,2,2,15,NA,1,1,1,15,182,NA,NA,1,1,NA,8,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,16781.078148,17658.768186,2,103,77,77,NA,5,5,0,2,0,2,45,2,4,5,NA +67326,7,2,2,47,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,24126.537834,25148.058527,2,97,5,5,0.76,5,5,1,1,0,2,47,1,4,5,NA +67327,7,2,1,75,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,53149.251154,62614.383127,2,94,6,6,2.04,2,2,0,0,2,1,75,1,3,1,3 +67328,7,2,2,6,NA,5,6,1,6,76,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9007.62445,9504.796896,2,102,15,15,3.92,5,5,1,2,0,1,34,2,5,1,5 +67329,7,2,2,61,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,13934.943848,14557.124186,2,96,3,3,0.47,4,4,1,0,1,2,61,1,4,3,NA +67330,7,2,1,46,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,108408.375382,114958.410267,2,98,6,6,1.25,4,4,1,0,1,1,46,1,2,6,NA +67331,7,2,2,15,NA,4,4,2,15,188,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14417.957956,14453.467189,1,96,15,15,5,4,4,0,2,0,1,46,1,5,1,5 +67332,7,2,2,45,NA,5,6,1,NA,NA,2,NA,2,2,3,NA,5,5,NA,1,2,1,1,2,1,1,2,1,3,13749.025709,14311.068456,1,103,7,7,1.89,3,3,0,1,0,2,45,2,5,5,NA +67333,7,2,1,42,NA,4,4,2,NA,NA,2,NA,2,2,4,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,17602.101156,17988.968846,1,96,7,7,1.52,4,4,0,2,0,2,30,2,4,1,5 +67334,7,1,2,32,NA,1,1,NA,NA,NA,2,NA,2,2,3,NA,3,1,3,2,2,2,2,2,2,NA,NA,NA,NA,35353.005268,0,2,94,4,4,0.72,4,4,1,1,0,1,30,2,1,1,3 +67335,7,2,2,30,NA,3,3,2,NA,NA,2,NA,2,2,2,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,26074.980194,26960.560427,1,93,12,2,0.69,4,1,0,0,0,2,25,2,5,5,NA +67336,7,2,2,7,NA,5,6,1,7,88,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9054.387575,9459.329211,2,100,14,14,4.03,4,4,0,2,0,1,48,2,5,1,5 +67337,7,2,2,73,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,NA,64463.340883,65151.773075,1,91,15,14,5,3,2,0,0,2,2,73,1,4,3,NA +67338,7,2,1,24,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,15971.744676,15898.343344,2,96,4,4,0.57,6,6,0,3,0,2,29,1,3,4,NA +67339,7,2,1,70,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,86445.94283,91501.124576,2,102,9,9,4.08,2,2,0,0,2,1,70,1,5,1,5 +67340,7,2,2,58,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,4,NA,1,2,2,1,2,2,NA,NA,NA,NA,15521.115746,15096.339697,2,100,5,5,1.07,4,4,0,1,0,2,36,1,3,5,NA +67341,7,2,1,74,NA,1,1,2,NA,NA,2,NA,1,1,NA,NA,1,1,NA,2,2,2,1,2,2,1,2,2,NA,14472.233702,14665.217659,1,98,8,8,3.3,2,2,0,0,2,1,74,1,1,1,3 +67342,7,2,2,48,NA,5,6,1,NA,NA,2,NA,2,2,3,NA,1,1,NA,1,2,1,1,2,1,1,2,1,3,12770.403552,13002.937616,1,103,4,4,0.82,3,3,0,0,0,1,48,2,4,1,1 +67343,7,2,1,58,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,29903.342494,29807.964765,1,95,6,4,1.74,2,1,0,0,0,2,48,1,4,3,NA +67344,7,2,1,60,NA,2,2,2,NA,NA,2,NA,2,2,3,NA,5,1,NA,2,2,2,1,2,2,1,2,2,1,9691.985299,9847.238527,1,93,5,5,1.43,2,2,0,0,1,1,60,2,5,1,4 +67345,7,2,2,2,NA,4,4,2,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6555.231326,6846.316857,1,99,6,6,1.35,3,3,1,1,0,2,42,1,4,4,NA +67346,7,2,1,80,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,NA,40859.270352,45390.978638,2,101,12,12,NA,1,1,0,0,1,1,80,1,3,3,NA +67347,7,2,1,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,38321.717684,40488.857872,1,92,6,6,2.04,2,2,0,0,2,2,71,1,4,1,1 +67348,7,2,1,16,NA,5,6,2,16,197,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,6666.045669,7317.485505,3,90,77,77,NA,5,5,0,2,0,1,46,2,3,1,3 +67349,7,2,1,42,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,23160.426103,23797.470648,2,98,10,10,3.78,3,3,0,0,0,2,46,1,4,1,4 +67350,7,2,1,2,NA,4,4,1,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8431.543376,9297.155306,2,96,14,14,3.58,4,4,2,0,0,1,36,1,4,1,5 +67351,7,2,1,10,NA,5,7,1,11,133,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,20857.728985,21677.56405,2,98,3,3,0.38,5,5,0,4,0,2,39,1,4,5,NA +67352,7,2,2,40,NA,3,3,2,NA,NA,2,NA,2,2,3,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,25784.374025,27218.997103,1,90,7,7,2.1,3,3,1,0,0,2,40,2,5,1,4 +67353,7,2,1,61,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,8883.460927,9371.520203,2,92,15,15,5,2,2,0,0,2,1,61,1,5,1,5 +67354,7,1,2,18,NA,5,6,NA,NA,NA,2,NA,2,1,4,11,NA,NA,NA,1,2,2,1,2,2,NA,NA,NA,NA,9758.609905,0,3,91,14,2,0.83,2,1,0,0,1,2,67,1,5,5,NA +67355,7,2,2,22,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,32455.694722,32314.335903,1,103,7,7,0.51,7,7,3,4,0,1,54,2,1,1,1 +67356,7,2,2,49,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,80418.665565,96911.831087,2,97,15,15,4.97,5,5,1,0,0,1,48,1,4,1,3 +67357,7,2,1,23,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,36154.496177,37370.445999,2,101,1,1,0.14,3,1,0,0,0,1,23,1,4,5,NA +67358,7,2,1,7,NA,4,4,2,7,87,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9554.261994,9836.582126,2,90,8,8,1.67,6,6,1,1,0,1,52,1,3,1,5 +67359,7,2,1,74,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,59027.291951,62692.518829,1,103,15,15,5,2,2,0,0,2,1,74,1,5,1,5 +67360,7,2,1,10,NA,1,1,1,10,131,NA,NA,2,2,4,3,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,11159.151566,11226.781631,1,102,5,5,0.98,4,4,1,1,0,2,42,2,2,6,NA +67361,7,2,1,59,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,32185.399379,40770.619238,2,91,4,4,1.19,2,2,0,0,0,1,59,1,1,1,3 +67362,7,2,2,47,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,1,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,13219.753222,13289.658517,2,92,8,8,1.91,5,5,0,2,1,2,47,2,1,1,3 +67363,7,2,1,61,NA,2,2,2,NA,NA,2,NA,2,2,5,NA,1,4,NA,2,2,2,2,2,2,1,2,2,2,8609.250304,9380.869295,2,90,7,7,1.34,5,5,0,1,2,1,61,2,1,4,NA +67364,7,2,2,19,NA,3,3,1,19,231,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,22916.593117,23588.294062,1,102,4,4,0.97,3,3,0,1,0,2,19,1,2,NA,NA +67365,7,2,2,58,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,16033.091438,16307.204086,1,96,15,15,5,3,3,0,0,1,2,62,1,4,3,NA +67366,7,2,2,5,NA,3,3,1,6,72,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,64434.313673,68475.614831,1,101,5,5,0.89,5,5,1,2,0,1,31,1,2,1,1 +67367,7,2,2,32,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,3,1,2,2,2,2,2,2,2,NA,NA,NA,NA,35464.8385,41544.401264,2,96,6,6,1.11,5,5,0,3,0,2,32,2,3,1,2 +67368,7,2,2,23,NA,2,2,1,NA,NA,2,NA,2,2,5,NA,3,5,2,2,2,2,2,2,2,1,2,2,1,41646.508203,41998.067158,3,91,4,4,0.81,3,3,0,0,1,1,64,2,1,1,1 +67369,7,2,2,3,NA,4,4,2,3,38,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9445.424546,10163.382174,2,99,6,6,1.15,5,5,1,2,0,2,34,1,4,77,NA +67370,7,2,1,41,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,4,1,NA,1,2,1,1,2,1,1,2,2,3,19184.316833,20543.822351,1,97,15,15,5,4,4,2,0,0,2,35,2,4,1,4 +67371,7,2,1,13,NA,4,4,1,13,163,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9188.45337,9407.445906,2,95,15,15,3.85,7,7,0,3,1,2,62,1,4,2,NA +67372,7,2,2,0,8,1,1,2,NA,10,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6588.463421,6449.849868,2,95,12,6,1.98,4,2,1,0,0,2,25,1,4,77,NA +67373,7,2,2,64,NA,2,2,1,NA,NA,2,NA,2,2,2,NA,2,1,NA,2,2,2,2,2,2,2,2,2,2,10746.81867,11542.921605,2,100,99,99,NA,6,6,1,1,2,1,37,2,3,1,3 +67374,7,1,1,10,NA,5,6,NA,NA,NA,NA,NA,2,1,3,4,NA,NA,NA,1,1,2,1,2,1,NA,NA,NA,NA,8014.738552,0,3,92,77,77,NA,7,7,2,4,1,1,62,NA,NA,1,NA +67375,7,2,2,45,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,18490.479848,18318.636758,2,100,7,7,1.38,5,5,1,0,0,2,45,1,2,3,NA +67376,7,2,2,57,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,38254.514187,37933.750372,1,98,2,2,0.72,1,1,0,0,0,2,57,1,4,3,NA +67377,7,2,1,0,2,3,3,2,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9570.577309,9932.368407,1,95,2,2,0.18,6,6,1,2,2,2,69,1,2,1,2 +67378,7,2,1,9,NA,2,2,2,9,108,NA,NA,1,1,NA,2,NA,NA,NA,2,1,2,2,2,1,NA,NA,NA,NA,13217.721247,13882.368076,2,91,4,4,0.94,3,3,0,1,0,2,50,2,1,4,NA +67379,7,2,2,12,NA,2,2,1,12,148,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,2,2,2,1,2,2,1,23968.380373,25913.276293,2,91,14,7,2.91,3,2,0,1,0,1,40,2,3,6,NA +67380,7,2,2,58,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,16165.962054,15723.538094,2,99,12,5,1.88,6,1,0,0,0,2,57,1,5,2,NA +67381,7,2,1,50,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,32720.69734,32680.7991,1,95,2,2,0.74,1,1,0,0,0,1,50,1,4,3,NA +67382,7,2,2,18,NA,4,4,1,18,221,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,18163.985724,18905.695776,2,101,4,4,0.86,3,3,0,1,0,2,18,1,2,NA,NA +67383,7,2,2,13,NA,4,4,2,13,165,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10401.399206,10736.579564,2,99,9,9,2.43,4,4,0,2,0,2,49,1,3,3,NA +67384,7,2,1,19,NA,3,3,2,20,NA,2,NA,1,1,NA,12,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,99249.131685,98501.502244,1,101,14,14,3.25,4,4,0,1,0,1,48,1,4,1,2 +67385,7,2,1,47,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,18116.816149,18405.984579,2,90,99,4,1.16,5,2,0,0,1,1,43,NA,NA,1,NA +67386,7,2,2,46,NA,2,2,1,NA,NA,2,NA,2,2,6,NA,1,4,NA,2,2,2,1,2,2,NA,NA,NA,NA,27654.660303,28156.17371,2,103,77,77,NA,4,4,0,0,0,2,46,2,1,4,NA +67387,7,1,1,74,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,8601.453077,0,2,97,4,4,0.53,7,7,0,2,2,1,74,1,2,1,2 +67388,7,2,1,35,NA,1,1,1,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,2,2,2,2,54095.173154,55399.110059,1,92,10,10,4.63,2,2,0,0,0,1,35,2,5,1,4 +67389,7,2,1,62,NA,2,2,2,NA,NA,2,NA,2,2,6,NA,1,2,NA,2,2,2,2,2,2,1,2,2,2,10585.549682,13806.559103,1,90,13,13,NA,2,2,0,0,1,1,62,2,1,2,NA +67390,7,2,2,56,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,121463.203322,122574.38549,2,95,9,9,4.92,1,1,0,0,0,2,56,1,5,3,NA +67391,7,2,2,30,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,1,1,2,2,1,2,2,1,2,2,1,73849.700988,79023.338367,3,91,14,14,5,3,3,1,0,0,2,30,1,4,1,5 +67392,7,2,1,41,NA,2,2,1,NA,NA,2,NA,2,2,1,NA,5,1,NA,2,2,2,2,2,2,2,2,2,2,33029.272844,32544.619181,2,93,9,9,1.49,7,7,0,3,0,2,41,2,5,1,5 +67393,7,2,2,29,NA,2,2,1,NA,NA,2,NA,2,1,6,NA,5,5,2,1,2,2,2,2,2,1,2,2,1,35424.746838,35546.372478,2,93,10,10,3.67,3,3,0,0,0,2,56,2,4,6,NA +67394,7,2,2,8,NA,5,7,2,8,101,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8746.306586,9472.024073,1,91,3,3,0.66,4,4,1,2,0,2,33,1,3,5,NA +67395,7,2,2,55,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,16741.034883,16850.233711,2,95,3,3,0.66,2,2,0,0,0,2,55,1,2,1,NA +67396,7,2,1,4,NA,1,1,1,4,53,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,16118.799226,16847.423074,3,92,4,4,0.46,7,7,1,2,0,2,31,2,2,1,1 +67397,7,2,1,20,NA,4,4,2,NA,NA,2,NA,2,2,2,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,12364.328404,12075.509308,1,96,10,10,1.8,7,7,1,1,0,1,57,2,1,1,3 +67398,7,2,2,2,NA,4,4,2,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5847.515059,6374.625564,2,99,2,2,0.19,7,7,3,1,0,2,43,1,2,4,NA +67399,7,2,2,55,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,11428.6913,11636.794359,2,103,7,7,1.65,4,4,0,1,1,2,55,2,3,1,NA +67400,7,2,1,61,NA,5,6,2,NA,NA,2,NA,2,2,2,NA,5,1,NA,1,2,2,NA,NA,NA,NA,NA,NA,NA,9355.567184,9645.104203,2,100,14,14,3.06,5,5,1,0,1,2,31,2,5,1,5 +67401,7,2,1,5,NA,1,1,1,5,70,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,17865.135763,18076.339981,3,92,1,1,0,5,5,3,0,0,1,26,1,2,1,2 +67402,7,2,2,59,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,16181.169973,15883.791498,2,100,7,7,2.72,2,2,0,0,0,2,59,1,4,3,NA +67403,7,2,1,15,NA,1,1,1,15,191,NA,NA,1,1,NA,9,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,24325.638415,24460.075857,3,92,5,5,1.05,3,3,1,1,0,2,38,2,3,5,NA +67404,7,1,2,63,NA,5,6,NA,NA,NA,2,NA,2,1,6,NA,4,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,18002.759054,0,2,102,5,5,1.36,2,2,0,0,2,1,70,2,5,1,4 +67405,7,2,1,5,NA,1,1,1,5,68,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,11388.091908,11522.723578,2,103,5,5,0.89,5,5,1,3,0,2,34,2,1,99,NA +67406,7,2,1,48,NA,1,1,2,NA,NA,2,NA,2,2,2,NA,5,5,NA,2,2,2,1,2,2,1,2,2,2,36475.684097,37047.191703,1,93,15,15,5,3,2,0,1,0,2,46,2,5,5,NA +67407,7,2,1,64,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,153565.050575,166235.02721,1,97,15,15,5,3,3,0,0,1,1,64,1,3,1,3 +67408,7,2,2,52,NA,5,6,2,NA,NA,2,NA,2,2,4,NA,3,1,NA,1,2,1,1,2,2,NA,NA,NA,NA,14647.161643,15007.506342,1,90,8,8,1.43,7,7,2,0,0,1,23,2,4,1,3 +67409,7,2,2,45,NA,3,3,2,NA,NA,2,NA,2,1,6,NA,3,4,NA,1,2,2,1,2,2,NA,NA,NA,NA,123440.03559,156711.394658,1,90,12,12,NA,2,2,0,0,0,2,45,2,3,4,NA +67410,7,2,2,18,NA,1,1,2,18,220,2,NA,2,2,2,11,NA,NA,NA,2,2,2,1,2,2,2,2,2,2,19557.287652,19949.093379,2,94,99,99,NA,3,3,1,0,0,2,18,2,2,NA,NA +67411,7,2,1,43,NA,2,2,2,NA,NA,2,NA,2,2,5,NA,1,6,NA,2,2,2,1,2,2,2,2,2,2,27127.17615,26729.126657,3,90,7,7,1.48,5,5,0,1,0,1,43,2,1,6,NA +67412,7,2,1,77,NA,3,3,1,NA,NA,2,NA,2,2,2,NA,4,1,NA,1,1,1,1,1,2,1,2,1,NA,17775.981268,18879.758897,1,92,4,4,1.1,2,2,0,0,2,2,69,2,4,1,4 +67413,7,2,1,80,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,32485.015568,36087.933902,2,101,6,6,1.62,3,3,0,0,2,1,80,1,3,1,3 +67414,7,2,2,77,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,13045.741791,13445.321496,1,99,3,3,1.07,1,1,0,0,1,2,77,1,2,2,NA +67415,7,1,1,5,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,NA,NA,NA,NA,NA,NA,NA,9016.053035,0,2,100,NA,NA,NA,3,3,1,0,0,1,29,NA,NA,1,NA +67416,7,2,1,4,NA,4,4,2,4,54,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9304.437652,9417.927146,2,97,2,2,0.45,3,3,1,0,0,1,24,1,2,1,3 +67417,7,2,2,58,NA,5,6,2,NA,NA,2,NA,2,1,8,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,19329.435508,19798.346555,2,97,15,15,5,2,2,0,0,1,2,58,2,5,1,5 +67418,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,35434.580514,39416.921733,1,95,2,2,0.87,1,1,0,0,1,2,80,1,2,2,NA +67419,7,2,1,4,NA,4,4,1,4,52,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10291.033925,11347.547701,1,100,14,14,4.45,3,3,1,0,0,1,33,1,4,1,4 +67420,7,2,1,22,NA,2,2,1,NA,NA,2,NA,2,2,2,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,49741.714519,52356.235161,2,91,14,14,4.71,3,3,0,0,0,1,28,2,1,1,2 +67421,7,2,2,6,NA,1,1,1,6,73,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15962.145468,16664.698857,2,98,9,9,3.08,3,3,0,1,0,1,35,2,1,1,3 +67422,7,2,1,19,NA,3,3,2,19,238,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,83180.831932,83381.692822,2,100,14,14,3.06,5,5,0,0,0,1,55,1,5,1,5 +67423,7,2,2,3,NA,3,3,2,3,39,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,25881.48305,27865.988236,1,94,7,7,0.94,7,7,1,4,0,2,46,2,5,1,5 +67424,7,2,2,32,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,42468.064168,46720.900929,2,101,3,3,0.65,3,3,0,1,0,2,54,1,3,5,NA +67425,7,2,1,37,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,2,2,2,1,2,2,1,2,2,1,41241.224595,41716.316195,2,102,6,6,1.03,5,5,1,1,0,1,37,1,2,1,2 +67426,7,1,2,24,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,4,1,3,1,2,2,1,2,2,NA,NA,NA,NA,112992.533921,0,1,91,8,8,2.51,3,3,1,0,0,2,24,1,4,1,3 +67427,7,2,1,24,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,14313.345971,14977.822328,3,91,15,15,5,3,3,0,0,2,2,61,1,5,1,5 +67428,7,1,1,72,NA,3,3,NA,NA,NA,1,1,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,68460.271241,0,1,102,9,9,4.08,2,2,0,0,1,1,44,1,3,3,NA +67429,7,2,2,65,NA,2,2,2,NA,NA,2,NA,2,1,8,NA,2,6,NA,2,2,2,1,2,2,1,2,2,2,9716.805546,12994.252166,2,90,4,4,1.47,1,1,0,0,1,2,65,2,2,6,NA +67430,7,2,1,8,NA,5,6,2,8,99,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10105.916709,10900.114748,1,91,6,6,1.25,4,4,1,1,0,1,26,2,4,6,NA +67431,7,2,1,61,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,2,1,NA,1,2,1,NA,NA,NA,1,2,1,3,5526.665646,5830.301859,2,92,12,NA,NA,7,1,0,0,2,1,53,2,3,1,3 +67432,7,2,2,10,NA,4,4,1,10,124,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11195.065587,11638.702248,2,96,2,2,0.43,3,3,0,2,0,2,50,1,2,5,NA +67433,7,2,1,65,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,5,3,NA,2,2,2,NA,NA,NA,2,2,2,2,13473.930124,13736.530204,2,98,4,4,0.48,6,6,2,0,2,2,65,2,1,2,NA +67434,7,2,1,56,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,184986.088848,184760.524604,1,92,15,15,5,2,2,0,0,0,2,56,1,4,1,5 +67435,7,2,1,80,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,1,NA,12101.489198,12967.543396,1,93,3,3,0.82,2,2,0,0,2,1,80,2,5,1,1 +67436,7,2,2,23,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,19783.396474,19410.189178,2,92,14,4,1.38,2,1,0,0,0,1,29,1,5,6,NA +67437,7,2,2,0,2,3,3,2,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16423.151355,15977.062092,1,99,9,9,3.24,3,3,1,0,0,1,29,1,5,1,5 +67438,7,2,1,61,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,6943.972932,7268.809657,2,92,5,5,1.32,2,2,0,0,1,2,51,1,2,1,2 +67439,7,2,2,36,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,21619.283038,21663.427812,2,102,8,8,1.72,5,5,0,2,1,1,63,2,5,1,5 +67440,7,1,2,61,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,16913.219568,0,2,98,77,77,NA,1,1,0,0,1,2,61,1,4,2,NA +67441,7,2,1,80,NA,3,3,2,NA,NA,2,NA,2,1,9,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,36829.543424,39682.305625,1,93,15,15,5,2,2,0,0,2,2,75,1,5,1,5 +67442,7,2,2,39,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,28187.999204,29187.28099,1,99,7,7,2.72,2,2,0,0,0,2,39,1,5,5,NA +67443,7,2,1,4,NA,1,1,1,4,51,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,16169.123686,17324.04909,1,100,13,13,NA,4,4,1,1,0,1,28,2,1,1,1 +67444,7,2,1,3,NA,5,6,2,3,41,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9459.753034,9916.192713,2,91,10,10,3.04,4,4,1,1,0,1,37,2,5,1,5 +67445,7,2,2,38,NA,1,1,1,NA,NA,2,NA,2,1,6,NA,2,1,2,1,2,2,1,2,2,2,2,2,2,32097.38481,33203.6204,2,100,4,4,0.81,4,4,0,2,0,1,56,1,4,1,2 +67446,7,2,1,30,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,19835.707828,24564.335286,1,94,6,6,1.18,5,5,1,2,0,1,30,1,3,1,3 +67447,7,2,2,57,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,140431.173819,139253.659476,1,94,8,8,3.47,2,2,0,0,1,2,80,1,1,2,NA +67448,7,2,1,4,NA,4,4,2,4,51,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7629.74403,7646.343205,1,99,4,4,0.53,7,7,3,1,0,2,26,1,1,5,NA +67449,7,2,2,48,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,111065.717962,115110.76456,2,91,15,15,5,4,4,0,2,0,2,48,1,5,1,5 +67450,7,2,1,55,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,166897.201244,166693.693828,2,91,15,6,2.24,7,1,0,0,1,1,49,NA,NA,5,NA +67451,7,2,2,18,NA,1,1,2,19,228,2,NA,2,2,3,12,NA,NA,NA,2,2,2,1,2,2,1,2,2,1,16594.391299,17940.930507,3,91,6,6,0.89,7,7,1,1,0,1,59,2,1,1,1 +67452,7,2,2,60,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,134694.414609,139412.076132,2,91,15,10,5,3,1,0,0,1,1,47,1,5,5,NA +67453,7,2,1,0,1,3,3,1,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,23912.171644,23498.78217,1,94,9,9,2.39,4,4,2,0,0,2,30,2,4,1,3 +67454,7,2,2,76,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,53103.835249,56432.29308,2,92,6,6,2.02,2,2,0,0,2,2,76,1,3,1,NA +67455,7,2,1,70,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,87101.243392,95057.097172,1,101,6,6,1.65,2,2,0,0,2,1,70,1,3,1,1 +67456,7,2,1,7,NA,4,4,2,7,93,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9699.683862,9681.447258,2,100,13,13,NA,4,4,0,2,0,2,28,1,2,6,NA +67457,7,2,1,49,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,31010.243793,30930.584862,3,92,6,6,0.74,7,7,2,1,0,2,46,1,2,1,4 +67458,7,2,1,9,NA,5,6,1,10,121,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7921.96624,8581.996701,1,92,7,7,2.31,2,2,0,1,0,2,26,1,4,5,NA +67459,7,2,2,24,NA,4,4,1,NA,NA,2,NA,2,2,4,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,17427.779559,17080.798702,2,93,6,6,1.13,4,4,0,0,2,1,60,2,3,1,3 +67460,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,44341.489734,49693.466543,2,103,5,5,1.79,1,1,0,0,1,2,80,1,4,2,NA +67461,7,2,2,0,11,3,3,2,NA,12,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10692.488346,11331.751026,1,101,1,1,0.08,3,3,1,0,0,2,19,1,2,NA,NA +67462,7,2,2,38,NA,1,1,1,NA,NA,2,NA,2,2,3,NA,3,3,2,1,2,1,1,2,1,2,2,2,NA,35464.8385,46825.562506,2,96,3,3,0.95,2,2,0,1,0,2,38,2,3,3,NA +67463,7,2,1,28,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,124091.929364,131797.624562,1,95,15,15,5,3,3,1,0,0,1,28,1,5,1,5 +67464,7,2,1,10,NA,3,3,1,10,125,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,41165.805324,42583.611962,2,100,10,10,3.13,4,4,0,2,0,1,45,1,4,1,4 +67465,7,1,2,58,NA,4,4,NA,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,15519.323571,0,2,99,10,10,3.67,3,3,0,0,1,1,64,2,4,1,5 +67466,7,2,1,55,NA,2,2,1,NA,NA,2,NA,2,2,2,NA,2,1,NA,2,2,2,1,2,2,NA,NA,NA,NA,23431.677775,24302.344664,2,93,5,5,1.26,3,3,0,1,0,1,55,2,2,1,2 +67467,7,1,1,80,NA,3,3,NA,NA,NA,1,1,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,39280.460347,0,2,91,4,4,1.39,1,1,0,0,1,1,80,1,3,2,NA +67468,7,2,2,17,NA,5,6,1,17,212,2,NA,2,1,4,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,9416.499309,9568.799193,1,100,15,15,5,4,4,0,1,0,1,44,2,5,1,5 +67469,7,2,1,23,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,14313.345971,14703.033095,3,91,7,7,2.58,2,2,0,0,0,2,55,2,5,3,NA +67470,7,2,2,37,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,22326.231285,22166.696692,1,99,6,6,0.6,7,7,2,1,1,2,69,1,3,2,NA +67471,7,2,2,45,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,4,NA,1,2,2,1,2,2,1,2,2,1,155208.037885,157114.920604,2,102,8,8,4.32,1,1,0,0,0,2,45,1,3,4,NA +67472,7,2,1,2,NA,3,3,2,2,28,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,40111.361732,45255.148434,1,98,15,15,3.7,5,5,2,1,0,1,34,1,5,1,5 +67473,7,2,2,79,NA,2,2,1,NA,NA,2,NA,2,1,9,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,29145.675285,31446.34406,3,92,7,7,2.31,2,2,0,0,2,1,77,1,4,1,4 +67474,7,2,1,38,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,18423.855809,18161.238545,1,96,12,12,NA,5,5,1,2,0,2,35,1,5,1,4 +67475,7,2,1,52,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,16287.780872,16793.056025,2,100,10,10,5,1,1,0,0,0,1,52,1,3,3,NA +67476,7,2,1,6,NA,3,3,2,6,78,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,57218.802967,58901.688698,1,95,9,9,2.13,6,6,0,4,0,2,44,1,1,1,1 +67477,7,2,2,57,NA,4,4,2,NA,NA,2,NA,2,1,7,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,12449.932013,12109.206963,3,90,15,15,4.89,5,5,0,0,0,2,57,2,3,1,3 +67478,7,2,1,2,NA,3,3,2,3,36,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,37959.146468,40828.920669,1,94,99,99,NA,3,3,1,0,0,1,31,1,4,6,NA +67479,7,2,2,5,NA,4,4,2,5,64,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10771.85499,11250.180007,2,97,2,2,0.38,3,3,1,1,0,2,27,1,2,5,NA +67480,7,2,2,62,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,6503.357568,6816.933235,2,95,15,15,3.85,7,7,0,3,1,2,62,1,4,2,NA +67481,7,2,2,69,NA,2,2,1,NA,NA,2,NA,2,1,7,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,10235.0654,10662.230581,2,93,3,3,0.66,2,2,0,0,2,2,69,2,4,3,NA +67482,7,2,2,14,NA,2,2,1,14,173,NA,NA,1,1,NA,11,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,18515.058419,19360.671834,2,96,2,2,0.27,6,6,1,3,0,1,34,NA,NA,1,NA +67483,7,2,2,64,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,1,3,NA,2,2,2,2,2,2,2,2,2,2,9570.416297,10355.226074,1,92,2,2,0.66,1,1,0,0,1,2,64,1,1,3,NA +67484,7,2,2,23,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,2,1,2,2,1,2,2,NA,NA,NA,NA,14289.513581,13586.634632,2,99,2,2,0.19,7,7,3,1,0,2,43,1,2,4,NA +67485,7,2,1,1,22,3,3,1,NA,23,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,22261.258803,25115.990281,1,94,7,7,1.21,6,6,2,2,0,1,31,1,2,6,NA +67486,7,2,2,41,NA,1,1,1,NA,NA,2,NA,2,1,7,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,36924.381422,38054.088192,2,102,14,14,3.8,4,4,2,0,0,2,41,2,4,1,5 +67487,7,2,2,75,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,16494.288293,17728.004854,2,101,3,3,0.92,1,1,0,0,1,2,75,1,2,2,NA +67488,7,2,1,29,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,5,NA,1,2,2,1,2,2,1,2,2,3,12241.196357,12961.680012,2,96,15,7,3.21,3,1,0,0,0,1,31,2,5,1,NA +67489,7,2,2,80,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,24158.28574,25084.308361,1,92,14,9,3.97,3,2,0,0,2,1,51,1,4,5,NA +67490,7,2,1,34,NA,2,2,1,NA,NA,2,NA,2,2,4,NA,3,1,NA,2,2,2,1,2,2,2,2,2,2,41241.224595,41716.316195,2,102,4,4,0.61,5,5,0,3,0,1,34,2,3,1,3 +67491,7,2,1,2,NA,1,1,1,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,13968.423539,13738.28453,2,102,3,3,0.54,4,4,1,1,0,1,28,2,2,6,NA +67492,7,2,2,32,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,85444.349063,87754.040572,1,94,14,14,5,2,2,0,0,0,1,50,1,3,1,5 +67493,7,2,1,76,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,8517.336599,8684.171961,2,100,9,9,4.35,2,2,0,0,2,2,79,1,5,1,3 +67494,7,2,1,34,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,19384.896286,21265.137164,1,94,4,4,0.56,5,5,1,2,0,1,34,1,2,3,NA +67495,7,2,1,11,NA,2,2,1,11,142,NA,NA,1,1,NA,3,NA,NA,NA,2,1,2,2,2,2,1,2,2,2,13898.598114,14013.214919,2,102,8,8,1.09,7,7,1,3,0,2,33,2,1,6,NA +67496,7,2,1,2,NA,1,1,1,2,30,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,13305.770449,13463.073191,3,92,4,4,0.59,5,5,2,1,0,1,20,2,1,1,3 +67497,7,2,2,6,NA,5,6,1,6,74,NA,NA,2,2,2,0,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,5064.232234,5712.276567,2,92,99,77,NA,7,4,3,3,1,1,61,2,1,1,3 +67498,7,2,2,16,NA,4,4,1,16,200,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,14166.687432,14745.171396,1,100,1,1,0.04,4,4,1,1,0,2,51,1,3,3,NA +67499,7,2,1,73,NA,2,2,2,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,13345.06742,13314.236759,1,99,15,15,5,2,2,0,0,2,1,73,1,4,1,5 +67500,7,2,2,9,NA,5,7,2,9,111,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,18348.624469,20109.577944,2,90,77,77,NA,6,6,0,4,0,2,41,NA,NA,4,NA +67501,7,2,2,62,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,164066.603708,163511.57474,1,95,10,10,4.76,2,2,0,0,2,1,65,1,4,1,4 +67502,7,2,1,56,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,10976.758665,11141.51106,2,103,15,15,5,3,3,0,0,0,2,52,2,4,1,5 +67503,7,2,2,45,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,154825.466557,154977.498295,1,94,12,7,3.67,2,1,0,0,0,2,45,1,5,5,NA +67504,7,2,2,37,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,1,1,2,2,1,2,2,1,2,2,1,27532.825087,28471.490951,1,101,6,6,1.3,4,4,0,2,0,1,43,2,1,1,3 +67505,7,2,2,61,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,163604.158578,166277.181905,1,101,10,10,4.63,2,2,0,0,2,1,62,1,5,1,5 +67506,7,2,2,6,NA,3,3,2,6,76,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,21658.223225,22668.915202,1,90,7,7,1.55,5,5,0,3,0,1,51,2,3,1,2 +67507,7,2,1,28,NA,4,4,1,NA,NA,2,NA,2,2,4,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,17840.217575,17960.016751,2,93,6,6,1.13,4,4,0,0,2,1,60,2,3,1,3 +67508,7,2,1,18,NA,5,7,2,19,228,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13547.769361,13874.542578,1,91,9,9,4.35,2,2,0,0,0,2,40,1,4,3,NA +67509,7,2,1,79,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,NA,68266.732554,70856.701199,1,95,7,7,3.67,1,1,0,0,1,1,79,1,5,5,NA +67510,7,2,1,4,NA,4,4,1,4,50,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7311.663111,7613.781996,2,93,6,6,1.15,5,5,3,1,0,1,29,1,3,5,NA +67511,7,1,2,21,NA,2,2,NA,NA,NA,2,NA,1,1,NA,NA,3,6,3,1,2,2,1,2,2,NA,NA,NA,NA,44119.608456,0,1,92,6,6,1.51,3,3,0,0,0,1,46,1,3,3,NA +67512,7,2,1,3,NA,4,4,2,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9304.437652,10259.663981,2,97,13,13,NA,4,4,1,0,1,2,45,1,2,5,NA +67513,7,2,1,53,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,20286.317046,20915.633712,2,99,2,2,0.5,2,2,0,0,0,1,53,1,3,1,NA +67514,7,2,1,6,NA,1,1,1,6,81,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11036.458246,10936.228943,1,102,13,13,NA,7,7,3,1,2,2,62,2,1,1,2 +67515,7,2,2,56,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,15521.115746,18174.62037,2,97,NA,99,NA,7,6,2,1,1,2,56,1,3,5,NA +67516,7,2,2,47,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,20773.573942,20827.234538,2,93,6,6,1.47,3,3,0,0,0,2,47,1,4,5,NA +67517,7,2,2,36,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,23660.610934,25318.185975,3,91,5,5,1.07,4,4,0,2,0,2,36,1,5,1,4 +67518,7,2,2,5,NA,1,1,2,5,61,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,11009.851855,11478.955249,1,93,13,3,0.54,6,3,2,1,0,1,23,NA,NA,5,NA +67519,7,2,1,63,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,1,6612.194774,6921.511029,2,99,6,6,1.98,2,2,0,0,1,1,63,1,2,2,NA +67520,7,2,1,79,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,11245.778093,11855.469704,1,98,4,4,1.19,2,2,0,0,2,1,79,1,3,1,3 +67521,7,2,2,76,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,NA,81062.798322,86779.337922,1,101,4,4,1.48,1,1,0,0,1,2,76,1,2,3,NA +67522,7,2,2,26,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,63207.045171,63513.398112,2,102,15,15,5,2,2,0,0,0,1,41,2,4,6,NA +67523,7,1,1,54,NA,3,3,NA,NA,NA,1,2,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,31699.998102,0,1,98,5,5,2.15,1,1,0,0,0,1,54,1,3,3,NA +67524,7,2,1,6,NA,2,2,2,6,76,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9807.589376,10786.008845,2,90,5,5,0.76,5,5,0,4,0,2,32,1,2,3,NA +67525,7,2,1,67,NA,5,6,2,NA,NA,2,NA,2,2,2,NA,5,1,NA,1,2,1,1,2,2,1,2,1,3,10497.261485,11239.197739,1,90,2,2,0.33,2,2,0,0,2,2,65,2,3,1,5 +67526,7,2,1,33,NA,1,1,2,NA,NA,2,NA,2,2,4,NA,1,6,NA,2,2,2,2,2,2,NA,NA,NA,NA,34887.439952,36924.956604,2,94,7,7,1.23,6,6,2,1,0,1,33,2,1,6,NA +67527,7,2,2,29,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,17399.722435,17053.300185,2,99,6,3,1.27,3,1,0,0,0,1,41,1,3,6,NA +67528,7,2,1,2,NA,3,3,1,3,36,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,38457.282261,42554.855377,1,100,6,6,1.18,5,5,2,2,0,2,40,1,5,3,NA +67529,7,2,2,11,NA,3,3,2,11,142,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,80369.555824,80552.420473,1,97,15,15,4.07,5,5,0,3,0,1,36,1,5,1,5 +67530,7,2,1,52,NA,1,1,2,NA,NA,2,NA,2,2,7,NA,5,4,NA,2,2,2,2,2,2,1,2,2,2,22446.308035,22508.005013,2,94,4,4,1.38,1,1,0,0,0,1,52,2,5,4,NA +67531,7,2,2,1,15,4,4,2,NA,15,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6880.068407,7403.030352,2,97,3,3,0.33,6,6,2,0,0,2,32,1,2,1,3 +67532,7,2,2,71,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,88916.414931,94489.544183,1,101,6,6,1.65,2,2,0,0,2,1,70,1,3,1,1 +67533,7,2,1,0,4,1,1,2,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6298.658963,6298.775059,2,94,7,7,1.57,4,4,2,0,0,2,27,1,4,1,2 +67534,7,2,2,56,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,31070.966983,31355.213599,1,102,2,2,0.66,1,1,0,0,0,2,56,1,4,2,NA +67535,7,2,2,63,NA,4,4,2,NA,NA,2,NA,2,1,8,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,9113.905743,9695.883475,3,90,9,9,3.14,3,3,0,1,1,2,63,2,4,3,NA +67536,7,2,2,14,NA,3,3,2,14,172,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,91797.787708,92992.465808,1,95,15,15,5,4,4,0,2,0,2,42,1,5,1,5 +67537,7,2,1,33,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,19638.748956,20390.674215,2,99,15,15,5,2,1,0,0,0,2,31,1,5,1,NA +67538,7,2,1,25,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,1,25645.251384,25368.119207,1,92,6,6,1.3,4,4,0,1,1,1,25,1,1,1,3 +67539,7,2,2,27,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,1,2,1,2,2,1,2,2,1,2,2,1,102855.726146,103775.32646,1,101,5,5,0.89,5,5,1,2,0,1,31,1,2,1,1 +67540,7,2,2,12,NA,1,1,2,12,155,NA,NA,2,2,4,7,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,13824.001771,14945.739837,2,90,3,3,0.58,4,4,0,2,0,2,36,2,3,1,3 +67541,7,2,1,11,NA,5,6,2,11,143,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10810.913614,11522.32071,1,97,15,15,4.07,5,5,0,3,0,1,42,2,5,1,5 +67542,7,2,2,30,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,3,1,2,1,2,1,1,2,1,NA,NA,NA,NA,11032.714892,11055.242776,2,92,5,5,0.64,7,7,1,2,1,1,66,2,1,1,3 +67543,7,2,2,16,NA,2,2,2,16,194,NA,NA,1,1,NA,9,NA,NA,NA,2,2,2,2,2,2,1,2,2,1,12680.621719,13709.581084,2,90,7,7,1.34,5,5,0,1,2,1,61,2,1,4,NA +67544,7,2,2,55,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,4,NA,1,2,2,1,2,2,1,2,2,1,17521.481386,17363.561951,2,101,1,1,0.2,2,2,0,0,1,2,55,1,4,4,NA +67545,7,2,2,22,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,6,2,1,2,2,1,2,2,1,2,2,1,124604.441853,125718.490512,1,92,9,4,1,7,3,2,1,0,1,45,1,4,2,NA +67546,7,2,2,30,NA,2,2,1,NA,NA,2,NA,2,1,3,NA,4,1,2,2,2,2,1,2,2,NA,NA,NA,NA,40476.413979,40301.503085,2,93,7,7,1.83,3,3,1,0,0,1,40,2,5,1,4 +67547,7,2,1,8,NA,3,3,2,8,101,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,16549.21669,17579.802509,1,91,12,8,2.15,6,4,1,1,0,2,29,1,4,6,NA +67548,7,2,2,68,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,12532.471503,12837.991566,2,97,4,4,0.84,3,3,1,0,1,2,68,1,4,2,NA +67549,7,2,1,25,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,36391.614555,41134.650764,1,103,5,5,1.02,4,4,2,0,0,1,25,1,2,1,4 +67550,7,2,2,13,NA,4,4,1,13,159,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15483.914568,16116.18632,1,100,4,4,1.23,2,2,0,1,0,2,47,1,2,4,NA +67551,7,2,2,28,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,17427.779559,17328.063231,2,93,12,12,NA,4,4,0,0,2,1,72,1,2,1,4 +67552,7,2,2,16,NA,3,3,1,16,194,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,76992.7514,81576.336255,1,100,15,15,4.07,5,5,0,2,0,2,41,1,5,1,4 +67553,7,2,2,9,NA,4,4,2,9,110,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7388.61397,8001.678046,3,90,2,2,0.39,2,2,0,1,0,2,32,1,3,5,NA +67554,7,1,2,61,NA,4,4,NA,NA,NA,2,NA,2,1,99,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,9024.164523,0,2,93,15,15,5,1,1,0,0,1,2,61,2,5,1,NA +67555,7,2,2,56,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,31785.728924,32871.467684,1,95,4,4,1.22,2,2,0,0,1,1,79,1,1,1,3 +67556,7,2,1,14,NA,4,4,2,14,178,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13251.602554,13095.83949,1,96,9,9,3.14,3,3,0,2,0,2,39,NA,NA,3,NA +67557,7,2,2,15,NA,4,4,2,15,187,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9728.028593,10125.263908,2,99,6,6,1.11,5,5,1,2,0,2,41,1,2,5,NA +67558,7,2,2,0,7,4,4,2,NA,8,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4476.23918,4525.114437,1,90,3,3,0.43,4,4,2,0,0,1,46,1,3,1,4 +67559,7,2,1,9,NA,3,3,2,9,118,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,30554.050397,31755.009616,1,97,6,6,1.03,6,6,2,2,0,2,38,1,5,1,4 +67560,7,2,1,68,NA,5,6,1,NA,NA,2,NA,2,2,8,NA,1,5,NA,1,2,2,2,2,2,1,2,2,1,13527.667075,14341.996991,2,98,6,6,0.59,7,7,2,2,1,2,52,2,1,1,1 +67561,7,2,2,12,NA,4,4,1,12,146,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14086.017075,14046.326674,2,96,5,5,1.07,4,4,0,3,0,2,46,1,4,3,NA +67562,7,2,1,2,NA,4,4,2,2,35,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6347.215153,6609.482921,2,95,1,1,0.09,5,5,3,1,0,2,31,1,2,1,NA +67563,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,35434.580514,39416.921733,1,92,2,2,0.64,1,1,0,0,1,2,80,1,3,2,NA +67564,7,2,2,43,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,37512.060155,39042.669235,1,92,15,15,4.99,4,4,0,2,0,2,43,1,4,1,4 +67565,7,2,1,10,NA,3,3,1,10,131,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,58429.74688,62860.392832,1,100,15,15,4.56,4,4,0,2,0,2,42,1,4,1,3 +67566,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,30796.941649,33729.162412,1,98,4,4,1.26,2,2,0,0,1,2,80,1,4,2,NA +67567,7,2,1,69,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,9618.837002,9727.194029,3,91,14,14,3.53,5,5,0,1,1,1,69,1,4,3,NA +67568,7,2,2,7,NA,3,3,2,7,87,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,22933.149195,22757.230737,1,95,6,6,0.81,6,6,2,2,0,1,30,1,3,1,4 +67569,7,2,1,7,NA,3,3,1,7,91,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,23188.935049,25672.571973,3,91,7,7,1.1,7,7,0,4,0,1,40,1,4,1,3 +67570,7,2,2,6,NA,2,2,1,7,84,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13720.541363,13932.536034,2,100,14,14,3.36,4,4,1,1,0,1,45,2,5,1,2 +67571,7,2,2,35,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,28747.860416,30588.052168,1,99,6,6,0.96,5,5,1,2,0,2,35,1,4,1,2 +67572,7,2,2,1,23,3,3,1,NA,24,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,59617.625426,65799.423913,3,92,15,15,5,4,4,2,0,0,1,38,1,5,1,5 +67573,7,2,2,80,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,1,1,NA,2,2,2,2,2,2,2,2,2,NA,25315.905293,28273.512517,2,98,4,4,1.15,2,2,0,0,2,1,80,1,1,1,1 +67574,7,2,2,12,NA,4,4,2,12,147,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11608.900361,11982.991894,1,99,8,8,2.59,3,3,0,2,0,2,46,1,4,2,NA +67575,7,2,2,6,NA,1,1,1,6,77,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,17458.526997,17642.073401,1,94,6,6,1.11,5,5,1,2,0,2,41,2,1,1,1 +67576,7,2,2,8,NA,1,1,2,8,97,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,2,2,2,1,2,2,1,15225.935813,15621.122955,2,94,77,77,NA,6,6,0,3,0,2,58,1,3,1,9 +67577,7,2,2,60,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,118933.861968,118531.514768,1,91,8,8,4.82,1,1,0,0,1,2,60,1,4,3,NA +67578,7,2,2,10,NA,3,3,2,10,131,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,73810.484644,75214.997077,1,94,15,15,5,4,4,0,2,0,2,47,1,5,1,5 +67579,7,2,1,10,NA,1,1,1,10,121,NA,NA,1,1,NA,2,NA,NA,NA,2,1,1,2,2,1,1,2,2,1,14880.007592,14744.872501,3,92,4,4,1.12,2,2,0,1,0,2,38,2,1,5,NA +67580,7,2,2,67,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,1,37934.469637,42910.885175,1,94,3,3,0.95,2,2,0,0,1,2,67,1,2,2,NA +67581,7,2,2,19,NA,2,2,2,19,235,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,14437.97544,15197.369043,2,90,5,5,0.8,5,5,0,3,0,2,40,2,1,5,NA +67582,7,2,2,29,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,1,2,1,2,2,1,2,2,1,2,2,NA,22306.465066,22494.734848,2,98,3,3,0.54,3,3,1,1,0,2,29,1,2,1,NA +67583,7,1,1,6,NA,1,1,NA,NA,NA,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,14456.751936,0,1,90,15,15,5,5,5,1,1,0,1,32,2,1,1,4 +67584,7,2,1,38,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,19008.083201,19380.210545,2,97,7,7,3.67,1,1,0,0,0,1,38,1,3,5,NA +67585,7,2,2,55,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,16181.169973,16286.716901,2,100,10,10,4.42,2,2,0,0,0,2,55,1,2,1,4 +67586,7,2,2,54,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,17622.141982,17728.11858,2,95,2,2,0.75,1,1,0,0,0,2,54,1,2,5,NA +67587,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,33147.414266,37148.276517,2,94,7,7,3.49,1,1,0,0,1,2,80,1,5,2,NA +67588,7,2,1,4,NA,4,4,2,4,56,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7814.415054,8296.803376,1,93,6,6,0.83,6,6,3,1,0,1,37,NA,NA,1,3 +67589,7,2,1,79,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,8517.336599,8684.171961,2,100,6,6,2.11,2,2,0,0,2,1,79,1,3,1,4 +67590,7,2,1,31,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,36150.793885,43021.850084,1,90,3,3,0.43,4,4,2,0,0,1,31,1,3,6,NA +67591,7,2,1,40,NA,5,6,2,NA,NA,2,NA,2,2,4,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,11113.602843,11678.105413,3,90,14,14,3.47,4,4,1,1,0,2,38,2,5,1,5 +67592,7,2,1,47,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,17810.743272,17839.416552,1,99,15,15,5,2,2,0,0,0,2,46,1,5,1,5 +67593,7,2,1,4,NA,4,4,1,5,60,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9016.053035,9035.668246,2,100,8,8,1.1,7,7,3,3,0,2,58,1,3,5,NA +67594,7,2,1,43,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,100867.796959,104079.392539,2,99,15,15,5,3,3,1,0,0,1,43,1,5,1,5 +67595,7,2,1,49,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,25128.435397,25532.311821,2,94,6,5,2.11,3,1,0,0,0,1,26,1,4,5,NA +67596,7,2,1,63,NA,5,7,2,NA,NA,2,NA,2,1,8,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,9314.746352,9205.449493,1,91,15,15,5,3,3,0,0,1,1,63,2,5,1,5 +67597,7,2,2,41,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,21077.085361,20500.255628,2,99,12,12,NA,1,1,0,0,0,2,41,1,5,5,NA +67598,7,2,2,80,NA,2,2,2,NA,NA,2,NA,2,1,7,NA,1,3,NA,2,2,2,2,2,2,2,2,2,NA,16490.79781,18057.97943,3,90,10,10,3.04,4,4,0,0,2,2,80,2,1,3,NA +67599,7,2,2,4,NA,4,4,1,4,57,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13130.790087,13857.266639,2,102,5,5,0.76,5,5,1,3,0,2,30,1,4,4,NA +67600,7,2,2,15,NA,3,3,2,15,181,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,34552.42011,37128.535405,1,90,7,7,1.55,5,5,0,3,0,1,51,2,3,1,2 +67601,7,1,2,8,NA,5,7,NA,NA,NA,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7842.234542,0,1,91,15,15,5,5,5,2,1,0,1,40,1,5,1,5 +67602,7,2,1,43,NA,1,1,1,NA,NA,1,2,2,2,7,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,31740.385214,32919.784432,2,96,7,7,1.79,4,4,0,2,0,1,43,2,3,1,2 +67603,7,2,2,62,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,17243.546687,17909.086027,1,92,14,14,5,2,2,0,0,2,2,62,1,4,1,4 +67604,7,2,2,24,NA,5,6,2,NA,NA,2,NA,2,2,4,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,13820.210756,14410.358083,1,90,8,8,1.43,7,7,2,0,0,1,23,2,4,1,3 +67605,7,2,2,19,NA,1,1,1,19,230,2,NA,2,7,77,10,NA,NA,NA,2,2,2,2,2,2,2,2,2,1,18581.167701,19429.800436,2,96,6,6,0.77,7,7,2,1,0,1,53,2,1,1,1 +67606,7,2,1,48,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,28542.421068,29427.85637,2,101,2,2,0.74,1,1,0,0,0,1,48,1,2,5,NA +67607,7,2,2,63,NA,5,6,2,NA,NA,2,NA,2,1,8,NA,3,1,NA,1,2,1,1,2,1,1,2,1,1,17248.011865,19146.123826,1,97,14,14,4.96,2,2,0,0,1,1,50,1,3,1,3 +67608,7,2,1,4,NA,5,6,1,4,52,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10273.602479,11522.969217,1,92,15,15,5,3,3,1,0,0,1,50,1,4,1,4 +67609,7,2,2,6,NA,4,4,1,6,76,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9399.281543,9563.245188,2,96,6,6,1.35,3,3,1,1,0,2,23,1,2,5,NA +67610,7,2,1,2,NA,4,4,1,2,35,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,NA,NA,NA,NA,NA,NA,NA,5652.403121,6080.146007,1,102,12,12,NA,7,7,3,2,0,2,52,1,4,5,NA +67611,7,2,2,14,NA,3,3,2,14,175,NA,NA,2,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,76360.13568,77793.595093,1,99,15,15,5,3,3,0,1,0,1,50,1,4,1,4 +67612,7,2,1,6,NA,1,1,1,6,73,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,17882.621856,18280.794545,3,92,7,7,2.1,3,3,1,1,0,2,25,1,4,5,NA +67613,7,2,2,21,NA,5,6,2,NA,NA,2,NA,2,1,3,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,11739.283384,12617.501315,1,96,7,7,1.83,3,3,0,0,1,1,66,2,5,1,3 +67614,7,2,1,53,NA,1,1,1,NA,NA,2,NA,2,2,3,NA,1,1,NA,2,2,2,2,2,2,NA,NA,NA,NA,25118.469449,26312.875816,2,98,5,5,1.07,4,4,0,1,0,1,53,2,1,1,1 +67615,7,2,2,17,NA,5,7,2,17,209,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12857.456314,12821.227649,2,100,9,9,2.46,4,4,0,2,0,2,36,2,4,1,3 +67616,7,2,1,63,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,167711.394252,175827.980982,1,101,4,2,0.81,2,1,0,0,1,1,63,1,2,6,NA +67617,7,2,2,13,NA,2,2,1,13,162,NA,NA,2,2,4,6,NA,NA,NA,2,1,2,2,2,2,2,2,2,2,15809.066118,17342.845429,2,93,7,7,1.52,4,4,1,1,0,1,44,2,4,1,NA +67618,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,39565.288792,43332.356399,1,99,14,14,5,2,2,0,0,2,1,80,1,4,1,4 +67619,7,2,1,53,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,120041.937453,120355.294586,1,98,15,15,5,5,5,0,1,0,1,53,1,5,1,5 +67620,7,2,1,54,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,28017.200708,32299.614806,2,102,3,3,0.92,1,1,0,0,0,1,54,1,4,3,NA +67621,7,2,2,27,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,43813.24867,44204.968982,1,98,4,4,0.67,5,5,1,2,0,1,29,1,4,1,3 +67622,7,2,2,29,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,18246.235208,18261.326779,2,99,1,1,0.07,4,4,1,1,0,2,24,1,2,5,NA +67623,7,2,1,8,NA,3,3,2,8,98,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,74331.764009,78960.699825,2,91,14,14,4.19,3,3,0,1,0,2,31,1,4,1,3 +67624,7,2,1,30,NA,3,3,2,NA,NA,2,NA,2,2,3,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,99283.360764,104566.027434,3,91,1,1,0.09,1,1,0,0,0,1,30,2,5,5,NA +67625,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,25359.946386,29418.979823,2,95,2,2,0.88,1,1,0,0,1,2,80,1,1,2,NA +67626,7,2,1,1,15,2,2,1,NA,16,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13305.770449,13726.956753,3,92,9,9,2.22,5,5,1,0,2,1,66,2,1,1,1 +67627,7,2,1,25,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,23064.54207,22591.937434,2,91,15,15,5,4,4,0,0,1,1,61,NA,NA,1,2 +67628,7,2,2,22,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,53634.754806,54437.113731,1,98,99,99,NA,3,2,0,0,0,2,22,1,4,5,NA +67629,7,2,2,70,NA,5,6,2,NA,NA,2,NA,2,2,4,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,18698.205673,19635.336647,1,97,12,12,NA,5,5,0,1,1,2,40,2,9,1,NA +67630,7,2,1,12,NA,3,3,1,12,147,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,26749.020961,27839.957403,1,98,6,6,1.11,5,5,1,2,0,2,32,1,2,1,2 +67631,7,2,1,36,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,18544.003944,22007.065507,1,96,12,12,NA,7,7,1,0,1,2,59,1,3,1,1 +67632,7,2,2,51,NA,1,1,1,NA,NA,2,NA,2,2,5,NA,1,1,NA,2,2,2,2,2,2,NA,NA,NA,NA,24646.971819,25093.941214,1,102,7,7,1.89,3,3,0,0,0,1,53,2,1,1,1 +67633,7,2,2,9,NA,4,4,2,9,111,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7944.571197,8483.470772,2,99,15,15,5,3,3,0,1,0,2,48,1,5,4,NA +67634,7,2,2,8,NA,4,4,2,8,104,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8184.286585,8442.757341,2,97,2,2,0.21,7,7,2,3,0,2,32,1,4,5,NA +67635,7,2,1,65,NA,1,1,1,NA,NA,2,NA,2,2,6,NA,1,1,NA,2,2,2,2,2,2,2,2,2,2,10298.484448,10551.517983,1,94,6,6,1.98,2,2,0,0,2,1,65,2,1,1,1 +67636,7,1,1,7,NA,5,7,NA,NA,NA,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,17227.332856,0,3,91,5,5,0.65,7,7,0,4,0,2,39,1,3,4,NA +67637,7,1,2,9,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7489.549692,0,2,100,10,10,2.33,6,6,0,2,2,2,35,1,2,5,NA +67638,7,2,2,19,NA,4,4,1,19,232,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11437.338051,11296.529267,2,95,2,2,0.41,3,3,2,0,0,2,19,1,2,NA,NA +67639,7,2,1,0,2,4,4,2,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6476.58432,6575.990772,2,97,3,3,0.75,2,2,1,0,0,2,22,1,4,4,NA +67640,7,2,1,58,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,27595.50738,27352.795749,1,98,6,6,1.57,3,3,0,0,0,1,58,1,3,1,3 +67641,7,2,1,5,NA,1,1,2,5,69,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,16074.564008,16583.394837,1,97,4,4,0.72,5,5,2,1,0,2,33,2,1,6,NA +67642,7,2,2,24,NA,1,1,2,NA,NA,2,NA,2,1,4,NA,2,6,2,1,2,2,1,2,2,NA,NA,NA,NA,39426.061521,43773.817687,2,94,8,8,2.33,4,4,2,0,0,1,24,1,2,6,NA +67643,7,2,1,76,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,51472.063256,53424.859661,2,95,15,15,5,2,2,0,0,2,1,76,1,4,1,5 +67644,7,2,1,56,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,23005.210125,23019.76475,1,95,14,14,3.04,6,6,0,4,0,1,56,1,5,1,4 +67645,7,2,1,15,NA,4,4,2,15,187,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11386.695644,11908.648036,2,99,6,6,1.18,5,5,0,3,0,2,38,1,2,5,NA +67646,7,2,1,48,NA,5,6,2,NA,NA,2,NA,2,2,2,NA,4,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,11113.602843,11678.105413,3,90,5,5,0.93,4,4,1,0,0,1,48,2,4,1,NA +67647,7,2,2,70,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,4,NA,1,2,2,1,2,2,1,2,2,NA,16494.288293,17598.146607,2,95,3,3,1.1,1,1,0,0,1,2,70,1,3,4,NA +67648,7,1,2,2,NA,5,6,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6662.138091,0,2,95,14,14,3.58,4,4,1,0,0,1,39,1,3,1,3 +67649,7,2,2,41,NA,5,6,1,NA,NA,2,NA,2,2,1,NA,2,1,2,1,2,1,1,2,2,1,2,1,3,16378.162652,17998.555773,2,96,4,4,0.92,3,3,0,1,1,2,41,2,2,1,2 +67650,7,2,2,11,NA,3,3,1,11,137,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,16950.724686,16899.799988,2,98,2,2,0.34,2,2,0,1,0,2,30,1,4,4,NA +67651,7,2,2,26,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,20430.250572,20111.803159,2,97,5,5,0.76,5,5,0,0,0,2,50,1,4,5,NA +67652,7,2,1,46,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,108408.375382,118202.807654,1,92,6,6,1.51,3,3,0,0,0,1,46,1,3,3,NA +67653,7,2,2,39,NA,3,3,2,NA,NA,2,NA,2,1,7,NA,4,3,2,1,2,2,1,2,2,1,2,2,1,74517.751389,77393.175383,2,94,10,10,3.51,3,3,0,2,0,2,39,2,4,3,NA +67654,7,2,2,16,NA,1,1,1,16,193,NA,NA,1,1,NA,8,NA,NA,NA,2,2,2,1,2,2,1,2,2,1,20460.442471,21235.303768,2,102,7,7,1.04,7,7,1,2,0,2,37,2,1,1,2 +67655,7,2,2,8,NA,4,4,2,8,99,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9326.540969,10100.402919,1,91,8,8,1.76,5,5,0,3,0,2,42,1,3,6,NA +67656,7,2,1,53,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,15599.953109,16217.343339,1,99,14,1,0.23,2,1,0,0,0,2,51,1,5,1,NA +67657,7,2,1,1,20,3,3,1,NA,22,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,32956.344514,37182.588634,2,97,15,15,4.97,5,5,1,0,0,1,48,1,4,1,3 +67658,7,2,1,77,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,52501.717941,55571.910913,2,102,8,8,4.13,1,1,0,0,1,1,77,1,5,2,NA +67659,7,2,2,15,NA,5,6,1,15,188,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8272.446168,8996.728356,1,102,15,15,3.82,5,5,1,1,0,1,29,1,4,1,4 +67660,7,2,1,16,NA,5,7,2,16,194,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,9136.388281,9764.423514,3,91,15,15,4.47,4,4,0,1,0,2,45,2,5,1,5 +67661,7,2,1,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,13408.721263,15005.802731,2,98,4,4,1.22,2,2,0,0,2,1,80,1,1,1,1 +67662,7,2,2,11,NA,5,6,1,11,141,NA,NA,1,1,NA,5,NA,NA,NA,1,1,1,1,2,1,1,2,2,1,5064.232234,5431.552443,2,92,10,8,2.01,7,4,1,1,1,2,27,2,3,1,3 +67663,7,2,1,3,NA,4,4,2,3,39,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9319.143734,9894.41982,2,95,8,8,1.85,5,5,1,2,0,1,55,1,2,1,3 +67664,7,2,1,11,NA,1,1,1,11,143,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11399.23838,11468.323492,2,103,77,77,NA,5,5,1,2,0,2,30,1,2,1,2 +67665,7,2,2,33,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,NA,NA,NA,NA,19498.713386,19633.661812,2,97,5,5,0.84,5,5,0,2,0,2,33,1,4,1,3 +67666,7,2,2,64,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,10816.310126,11253.74147,1,99,14,14,5,2,2,0,0,1,2,64,1,3,3,NA +67667,7,1,1,35,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,79582.971419,0,2,99,15,15,5,1,1,0,0,0,1,35,1,5,5,NA +67668,7,2,2,70,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,26302.518039,27109.453365,1,101,5,3,0.98,2,1,0,0,2,2,70,1,4,2,NA +67669,7,2,2,2,NA,5,6,1,2,26,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8818.200077,8968.551716,2,102,6,6,1.52,4,4,2,0,0,1,30,2,4,1,4 +67670,7,2,2,52,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,15497.844354,15146.281728,1,99,7,7,3.21,1,1,0,0,0,2,52,1,4,1,NA +67671,7,2,2,5,NA,3,3,1,5,70,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,59321.981286,63042.638464,1,94,8,8,1.67,5,5,1,2,0,1,52,1,4,1,4 +67672,7,2,1,12,NA,3,3,2,12,145,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,27702.556686,27838.63939,1,98,7,7,1.03,7,7,0,4,0,2,20,1,3,5,NA +67673,7,2,2,13,NA,4,4,1,14,169,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14166.687432,14623.20249,1,100,15,15,3.87,6,6,1,3,0,2,39,1,4,1,4 +67674,7,2,2,0,4,4,4,2,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4964.196196,5466.923926,1,93,4,4,1.09,2,2,1,0,0,2,39,2,3,4,NA +67675,7,2,1,66,NA,1,1,1,NA,NA,1,2,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,1,11924.931067,12067.158788,1,98,8,8,1.95,4,4,1,1,1,2,59,1,3,1,1 +67676,7,1,1,6,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10651.061092,0,1,90,99,99,NA,2,2,0,1,0,2,26,1,4,5,NA +67677,7,2,1,36,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,17342.255821,20631.425049,1,93,3,3,1.29,1,1,0,0,0,1,36,1,4,5,NA +67678,7,2,2,6,NA,3,3,1,7,85,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,22308.590534,22137.463018,1,95,7,2,0.35,5,4,1,2,0,1,26,1,4,6,NA +67679,7,2,1,9,NA,1,1,1,9,110,NA,NA,1,1,NA,2,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,14820.807433,14905.891142,2,102,7,7,1.53,5,5,0,3,0,1,43,2,2,1,4 +67680,7,2,2,10,NA,3,3,2,10,124,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,63555.637461,64464.244761,1,90,15,15,5,4,4,0,2,0,1,44,1,5,1,5 +67681,7,2,2,33,NA,4,4,2,NA,NA,2,NA,2,1,3,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,28747.860416,29850.909164,1,99,14,14,3.8,4,4,1,1,0,1,48,2,5,1,5 +67682,7,2,2,13,NA,1,1,2,13,157,NA,NA,2,2,3,7,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,19850.979841,20602.760063,1,97,4,4,0.72,5,5,2,1,0,2,33,2,1,6,NA +67683,7,2,2,56,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,31785.728924,32633.084965,1,95,7,7,2.16,3,3,0,0,1,1,45,1,3,1,4 +67684,7,2,1,8,NA,2,2,1,8,98,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,14820.807433,14943.02937,2,102,5,5,0.89,4,4,0,3,0,2,44,2,2,4,NA +67685,7,2,1,9,NA,5,6,2,9,113,NA,NA,2,2,2,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9720.482616,10533.307174,2,91,14,14,3.47,4,4,1,1,0,2,36,2,3,1,5 +67686,7,2,1,12,NA,1,1,1,12,147,NA,NA,2,2,3,5,NA,NA,NA,2,1,1,1,2,2,1,2,2,1,32326.52031,34735.818434,3,92,7,7,1.41,5,5,1,2,0,1,20,2,1,1,1 +67687,7,2,2,8,NA,5,7,1,8,105,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,10422.423011,10751.577119,1,98,5,5,1.26,3,3,1,1,0,2,27,1,5,5,NA +67688,7,2,2,0,10,5,7,1,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8303.503441,8530.807571,1,94,7,7,1.23,6,6,3,1,0,1,32,1,4,1,4 +67689,7,2,2,18,NA,1,1,2,18,219,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,2,2,2,1,2,2,1,19557.287652,21454.715555,2,94,9,9,2.37,5,5,0,1,0,1,48,2,4,1,2 +67690,7,2,2,40,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,20480.890987,19920.377678,2,93,3,3,1.07,1,1,0,0,0,2,40,1,4,5,NA +67691,7,2,1,18,NA,3,3,1,19,228,2,NA,1,1,NA,66,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,34443.919252,35848.685683,2,101,3,3,0.3,7,7,1,2,0,2,50,1,2,4,NA +67692,7,2,2,12,NA,2,2,2,12,153,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,23072.919059,23761.374659,1,97,15,15,4.52,6,6,0,4,0,2,41,1,5,1,5 +67693,7,1,2,2,NA,2,2,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12871.484115,0,2,102,15,15,4.47,4,4,1,1,0,1,32,1,5,1,4 +67694,7,2,1,62,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,1,8890.956373,9238.69917,2,99,12,12,NA,2,1,0,0,1,2,46,1,3,2,NA +67695,7,1,2,55,NA,2,2,NA,NA,NA,2,NA,2,1,5,NA,4,1,NA,2,2,2,1,2,2,NA,NA,NA,NA,23200.373382,0,2,93,3,3,0.63,3,3,0,1,0,1,53,2,2,1,4 +67696,7,2,2,67,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,18695.172864,19350.637044,2,102,7,7,1.68,5,5,0,0,3,1,70,2,4,1,4 +67697,7,2,2,3,NA,5,7,1,4,48,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8818.200077,9596.189182,2,102,15,15,5,3,3,1,0,0,2,34,1,5,1,5 +67698,7,2,2,63,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,129999.035519,129559.2554,1,98,9,9,3.97,2,2,0,0,2,1,63,1,5,1,4 +67699,7,2,1,32,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,18544.003944,20254.971305,2,100,9,9,3.24,3,3,1,0,0,1,32,1,3,1,4 +67700,7,2,1,69,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,9883.238978,10581.776717,1,90,4,4,0.78,4,4,0,0,1,1,69,2,4,1,3 +67701,7,2,1,54,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,17869.988703,18923.921245,3,90,14,14,3.69,4,4,0,2,0,2,49,1,4,1,4 +67702,7,1,1,8,NA,2,2,NA,NA,NA,NA,NA,1,1,NA,2,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,8613.834494,0,2,90,6,6,0.66,7,7,2,2,0,2,24,2,4,6,NA +67703,7,2,1,72,NA,1,1,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,21815.897449,22272.021332,3,92,6,6,1.98,2,2,0,0,2,1,72,1,4,1,1 +67704,7,2,2,10,NA,4,4,2,10,128,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10221.991799,10790.677347,1,98,15,15,3.7,5,5,0,3,0,1,37,1,2,1,2 +67705,7,1,1,78,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,12173.814732,0,2,92,3,3,0.98,1,1,0,0,1,1,78,1,1,2,NA +67706,7,2,1,7,NA,5,6,1,7,87,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9307.245755,9856.522898,1,92,14,14,3.47,4,4,0,2,0,1,37,1,5,1,5 +67707,7,2,1,46,NA,3,3,1,NA,NA,2,NA,2,1,4,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,27340.471576,32700.198254,2,91,2,2,0.44,3,3,0,1,0,1,46,2,3,1,4 +67708,7,2,1,49,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,22685.373982,23047.569967,1,98,6,6,0.97,7,7,1,2,0,1,49,1,2,1,2 +67709,7,2,1,60,NA,2,2,1,NA,NA,2,NA,2,2,7,NA,2,1,NA,2,2,2,2,2,2,2,2,2,2,9235.951997,10444.280286,2,103,12,12,NA,3,3,0,0,1,1,60,2,2,1,2 +67710,7,2,1,50,NA,2,2,2,NA,NA,2,NA,2,2,4,NA,1,1,NA,2,2,2,2,2,2,1,2,2,2,22238.49412,21912.1785,2,90,7,7,1.34,5,5,0,1,2,1,61,2,1,4,NA +67711,7,2,1,17,NA,4,4,2,17,214,2,NA,2,1,5,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11125.932433,11147.929312,1,96,77,77,NA,7,7,0,3,1,2,43,77,5,5,NA +67712,7,2,1,15,NA,4,4,1,15,181,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13653.432599,13680.426553,2,96,5,5,1.07,4,4,0,3,0,2,46,1,4,3,NA +67713,7,2,1,62,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,167711.394252,169284.299948,1,101,10,10,4.63,2,2,0,0,2,1,62,1,5,1,5 +67714,7,2,1,75,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,43188.300631,46554.36669,2,91,15,2,0.86,7,1,0,0,1,1,49,NA,NA,5,NA +67715,7,2,2,3,NA,5,7,2,3,39,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12382.393854,12702.004448,1,97,10,10,2.82,4,4,1,1,0,2,24,1,3,5,NA +67716,7,2,1,60,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,12585.09113,12786.688219,1,92,5,5,1.41,2,2,0,0,2,1,60,1,2,1,4 +67717,7,2,1,66,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,10717.375231,11218.730451,2,101,3,3,1.1,1,1,0,0,1,1,66,1,1,2,NA +67718,7,2,2,49,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,138322.767578,145546.941919,1,101,5,5,1.45,2,2,0,0,0,2,49,1,4,3,NA +67719,7,2,1,35,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,16214.132654,20271.082789,3,90,14,14,5,2,2,0,0,0,1,47,1,2,5,NA +67720,7,2,1,64,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,12279.19827,12375.250021,2,102,14,14,5,2,2,0,0,2,1,64,1,4,1,3 +67721,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,49191.372812,55403.452354,3,91,3,3,1.1,1,1,0,0,1,2,80,1,1,2,NA +67722,7,2,1,20,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,104488.914565,106745.836574,1,98,4,1,0.4,4,1,0,0,0,1,22,1,5,5,NA +67723,7,1,2,19,NA,2,2,NA,NA,NA,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,NA,NA,NA,NA,21850.358234,0,2,93,99,99,NA,3,3,0,0,0,2,54,2,3,4,NA +67724,7,2,1,1,14,4,4,1,NA,15,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9438.902193,9727.203655,2,102,4,4,0.81,3,3,2,0,0,2,23,1,4,5,NA +67725,7,1,2,68,NA,2,2,NA,NA,NA,2,NA,2,1,5,NA,1,1,NA,2,2,2,2,2,2,NA,NA,NA,NA,10561.745159,0,2,90,77,77,NA,2,2,0,0,2,2,68,2,1,1,NA +67726,7,2,2,50,NA,2,2,2,NA,NA,2,NA,2,1,6,NA,2,1,NA,1,2,2,1,2,2,2,2,2,2,22466.936477,23282.464675,1,90,6,6,1.57,3,3,0,0,0,1,50,2,2,1,2 +67727,7,2,2,32,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,29733.812317,31414.972893,1,101,5,5,1.45,2,2,0,0,0,1,41,NA,NA,1,4 +67728,7,2,1,66,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,NA,74792.980299,75494.43714,2,101,99,2,0.67,7,1,0,0,1,1,55,NA,NA,77,NA +67729,7,2,2,2,NA,2,2,2,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11412.410776,11898.666241,1,97,3,3,0.44,5,5,2,2,0,2,26,1,4,4,NA +67730,7,2,1,14,NA,3,3,1,14,178,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,102027.743122,101259.182802,1,101,8,8,1.85,5,5,0,3,0,1,41,1,3,1,4 +67731,7,2,1,0,11,3,3,2,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13392.309303,13030.480476,1,99,15,15,3.45,7,7,1,4,0,1,42,1,5,1,5 +67732,7,2,1,62,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,1,6910.118936,7233.371983,2,95,1,1,0,1,1,0,0,1,1,62,1,2,2,NA +67733,7,2,2,18,NA,2,2,1,18,217,2,NA,1,1,NA,11,NA,NA,NA,2,2,2,2,2,2,1,2,2,1,15809.066118,16348.490248,2,93,6,6,1.39,4,4,0,0,0,1,53,2,3,1,3 +67734,7,2,2,19,NA,4,4,2,19,237,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,18163.985724,18905.695776,2,101,2,2,0.48,2,2,1,0,0,2,19,1,3,NA,NA +67735,7,2,1,16,NA,5,6,2,16,195,NA,NA,2,2,3,9,NA,NA,NA,1,2,2,1,2,1,1,2,2,1,7350.524832,8448.96413,2,90,3,3,0.54,4,4,0,1,0,2,52,NA,1,1,2 +67736,7,2,2,5,NA,1,1,2,5,70,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,13366.393396,13935.903375,2,94,5,5,0.67,6,6,1,3,0,1,37,2,3,1,4 +67737,7,2,2,25,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,10800.351372,11406.289115,2,92,15,15,5,3,1,0,0,0,2,25,1,5,5,NA +67738,7,2,1,6,NA,2,2,1,6,81,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10738.959181,10632.988891,2,93,9,9,3.14,3,3,0,2,0,2,34,2,5,3,NA +67739,7,2,2,17,NA,5,6,2,17,214,2,NA,2,1,5,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11975.458482,12226.374363,1,97,15,15,5,3,3,0,1,2,2,63,1,5,1,NA +67740,7,2,1,52,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,3,4,NA,2,2,2,1,2,2,NA,NA,NA,NA,21084.369131,21009.599098,2,95,4,4,1.12,2,2,0,1,0,1,52,2,3,4,NA +67741,7,2,2,28,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,1,1,2,2,1,2,2,NA,NA,NA,NA,105039.256649,105978.379214,1,90,8,8,1.67,5,5,2,1,0,2,28,1,4,1,5 +67742,7,2,1,5,NA,1,1,1,5,68,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,17865.135763,18430.646082,3,92,3,3,0.52,5,5,2,1,0,2,29,2,1,1,3 +67743,7,2,1,51,NA,4,4,2,NA,NA,2,NA,2,2,3,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,16117.991297,16911.733026,1,96,3,3,0.43,4,4,1,1,0,2,39,2,4,1,3 +67744,7,2,1,11,NA,1,1,1,11,143,NA,NA,2,2,3,4,NA,NA,NA,2,1,2,2,2,2,1,2,2,NA,13822.148996,14860.201344,3,92,4,4,0.55,6,6,0,4,0,1,36,2,1,1,3 +67745,7,2,2,72,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,NA,29534.722322,30544.805853,3,91,2,2,0.83,1,1,0,0,1,2,72,1,4,3,NA +67746,7,2,1,10,NA,3,3,2,10,128,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,39772.343364,41554.529575,2,100,15,15,4.5,6,6,0,4,0,1,45,1,5,1,5 +67747,7,2,2,2,NA,1,1,1,2,29,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8141.317022,8654.572344,1,103,14,14,2.96,5,5,1,2,0,1,34,1,4,1,5 +67748,7,2,2,4,NA,3,3,2,4,51,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,26966.264969,27815.81123,1,98,6,6,1.31,3,3,2,0,0,2,22,1,3,5,NA +67749,7,2,1,1,19,5,6,1,NA,19,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6389.003009,6767.308805,3,91,14,14,3.06,5,5,3,0,0,1,34,2,5,1,5 +67750,7,2,2,2,NA,4,4,2,2,33,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7016.981922,7550.350821,2,99,3,3,0.42,6,6,1,2,0,2,43,1,4,6,NA +67751,7,2,2,20,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,43813.24867,47373.102231,1,98,7,7,1.03,7,7,0,4,0,2,20,1,3,5,NA +67752,7,2,1,14,NA,5,7,2,14,172,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11506.937395,12095.740214,1,97,15,15,5,6,6,0,3,0,1,47,1,5,1,5 +67753,7,1,2,6,NA,1,1,NA,NA,NA,NA,NA,1,1,NA,0,NA,NA,NA,2,1,1,1,2,1,NA,NA,NA,NA,12789.411811,0,1,102,99,99,NA,5,5,0,2,1,1,52,2,1,1,1 +67754,7,2,2,36,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,14010.52688,14536.170828,2,103,15,15,5,3,3,1,0,0,1,35,1,9,1,5 +67755,7,2,1,11,NA,3,3,1,11,138,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,74331.764009,78594.005469,2,91,9,9,2.6,4,4,0,2,0,1,53,1,2,1,5 +67756,7,2,1,28,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,17583.693727,17958.024135,2,95,15,7,3.13,5,1,0,0,0,1,47,1,5,1,3 +67757,7,2,1,0,4,1,1,1,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,6910.953528,6911.08091,2,96,4,4,0.97,3,3,1,0,0,2,37,2,2,1,1 +67758,7,2,2,7,NA,4,4,2,7,91,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5758.0032,6529.524105,2,90,6,6,0.84,6,6,1,3,1,2,43,1,2,5,NA +67759,7,2,1,4,NA,1,1,1,4,52,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,17341.8035,17546.820808,2,102,7,7,1.53,5,5,1,2,0,1,36,1,2,1,3 +67760,7,2,1,17,NA,5,6,2,18,216,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,7057.977053,7861.480262,2,92,12,12,NA,7,7,2,4,0,1,54,2,2,1,5 +67761,7,2,1,20,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,27271.751091,29115.882263,2,101,6,6,1.67,3,3,0,0,0,2,22,1,4,5,NA +67762,7,2,1,53,NA,4,4,2,NA,NA,2,NA,2,1,4,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,21016.438271,22051.40744,1,93,12,12,NA,3,3,0,1,0,2,49,2,3,1,3 +67763,7,2,2,37,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,1,1,2,2,1,2,2,1,2,2,1,97803.500399,99700.910854,1,95,14,14,3.8,4,4,0,2,0,2,37,1,5,1,5 +67764,7,2,1,76,NA,2,2,2,NA,NA,2,NA,2,1,7,NA,1,2,NA,2,2,2,2,2,2,1,2,2,NA,12962.876803,16930.790311,2,90,6,5,1.84,2,1,0,0,2,1,76,2,1,2,NA +67765,7,2,1,2,NA,2,2,2,2,26,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10803.555682,10931.27688,2,94,6,6,1.43,5,4,2,1,0,2,23,2,3,6,NA +67766,7,2,2,62,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,37934.469637,38685.959862,1,94,4,4,1.26,2,2,0,0,1,2,41,1,4,5,NA +67767,7,2,2,56,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,29167.119125,34820.124106,1,101,1,1,0.08,6,6,0,1,0,1,51,1,2,5,NA +67768,7,2,2,14,NA,3,3,2,14,174,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,103298.858809,112630.333619,1,101,8,8,2.24,4,4,0,1,0,1,45,1,4,1,NA +67769,7,2,2,54,NA,1,1,1,NA,NA,2,NA,2,2,7,NA,1,1,NA,1,2,1,1,2,2,2,2,2,2,18295.488967,18390.898385,1,103,7,7,0.51,7,7,3,4,0,1,54,2,1,1,1 +67770,7,2,2,0,10,4,4,2,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4418.651245,4685.491283,2,95,6,6,0.97,6,6,2,1,0,1,54,1,3,6,NA +67771,7,2,1,13,NA,4,4,2,13,158,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17606.165994,17558.40257,2,101,6,6,1.51,3,3,0,1,1,1,65,1,2,1,4 +67772,7,2,2,73,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,53541.401974,54113.194007,1,99,9,9,3.74,2,2,0,0,2,2,73,1,3,1,4 +67773,7,2,2,60,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,17243.546687,17909.086027,1,92,8,8,3.44,2,2,0,0,2,1,71,1,3,1,5 +67774,7,2,1,34,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,16905.961576,17390.157008,2,94,8,8,1.6,6,6,3,1,0,2,32,1,4,1,4 +67775,7,2,2,29,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,93589.96496,99393.853006,1,93,15,15,5,3,3,1,0,0,1,33,1,5,1,3 +67776,7,2,1,54,NA,1,1,1,NA,NA,2,NA,2,2,7,NA,1,1,NA,1,2,1,1,2,2,2,2,2,2,21139.303536,20829.116843,1,103,7,7,0.51,7,7,3,4,0,1,54,2,1,1,1 +67777,7,1,1,2,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5547.430651,0,1,96,9,9,2.18,5,5,1,1,0,1,26,1,4,1,4 +67778,7,2,1,31,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,17802.31438,18749.539496,1,102,3,3,0.82,2,2,0,0,0,1,31,1,4,1,4 +67779,7,2,2,56,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,207644.101324,209788.639452,1,97,10,10,4.3,2,2,0,0,1,2,56,1,5,1,5 +67780,7,2,2,7,NA,1,1,1,7,93,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15962.145468,16061.826248,2,98,4,4,0.75,4,4,0,2,0,2,33,1,2,5,NA +67781,7,2,2,41,NA,2,2,1,NA,NA,2,NA,2,2,1,NA,5,1,2,2,2,2,2,2,2,2,2,1,2,32606.880052,32776.922157,2,93,9,9,1.49,7,7,0,3,0,2,41,2,5,1,5 +67782,7,2,1,44,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,19440.793325,19514.660132,2,95,10,10,2.32,6,6,1,2,0,1,44,1,4,1,4 +67783,7,2,2,13,NA,5,6,2,13,162,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11975.458482,12226.374363,1,97,15,15,2.33,7,7,2,4,0,2,40,2,5,1,4 +67784,7,2,2,18,NA,1,1,1,18,216,2,NA,1,1,NA,12,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,15690.47168,16249.379042,1,102,5,5,0.86,5,5,2,0,0,2,21,2,2,5,NA +67785,7,2,2,38,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,2,1,2,2,1,2,2,1,2,2,1,27156.758177,27240.256208,1,95,4,4,1.21,2,2,0,0,0,1,46,1,2,1,2 +67786,7,2,1,45,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,152858.509804,153199.936938,1,95,3,3,1.33,1,1,0,0,0,1,45,1,2,5,NA +67787,7,2,1,44,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,24881.621161,24802.260383,2,94,15,15,5,1,1,0,0,0,1,44,1,5,3,NA +67788,7,2,1,62,NA,1,1,2,NA,NA,2,NA,2,1,7,NA,4,1,NA,2,2,2,2,2,2,1,2,2,2,9871.376767,9834.888389,2,97,4,4,1.29,2,2,0,0,2,2,70,1,3,1,4 +67789,7,2,2,20,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,1,1,2,2,1,2,2,1,2,2,1,18723.98095,18882.01405,2,101,2,2,0.22,4,4,1,1,0,2,41,1,2,4,NA +67790,7,2,1,14,NA,4,4,2,14,172,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10065.83895,10440.165744,2,99,14,14,4.09,3,3,0,2,0,2,37,1,5,5,NA +67791,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,32489.451884,36954.118364,2,91,3,3,1.16,1,1,0,0,1,2,80,1,4,2,NA +67792,7,1,1,10,NA,5,6,NA,NA,NA,NA,NA,1,1,NA,3,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,8943.919305,0,1,92,5,5,0.63,7,7,0,4,1,1,60,NA,NA,1,NA +67793,7,2,1,39,NA,1,1,1,NA,NA,2,NA,2,2,6,NA,3,1,NA,2,2,2,2,2,2,1,2,2,2,37658.482129,41412.915504,1,100,7,7,1.74,4,4,0,2,0,2,39,2,1,1,3 +67794,7,2,1,51,NA,2,2,2,NA,NA,2,NA,2,1,7,NA,1,1,NA,2,2,2,2,2,2,NA,NA,NA,NA,25139.75955,26335.178282,2,99,77,77,NA,3,3,0,0,0,2,57,2,2,1,1 +67795,7,2,1,41,NA,5,6,2,NA,NA,2,NA,2,2,99,NA,3,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,11113.602843,11073.454175,3,90,77,77,NA,7,7,1,2,0,1,41,2,3,6,NA +67796,7,2,2,1,20,4,4,2,NA,21,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7108.64371,7648.979929,1,90,14,14,2.96,5,5,1,2,0,1,31,1,5,1,4 +67797,7,2,1,45,NA,2,2,2,NA,NA,2,NA,2,1,77,NA,3,3,NA,2,2,2,2,2,2,2,2,2,2,28428.303115,29087.004066,3,90,77,77,NA,4,3,0,0,0,1,45,2,3,3,NA +67798,7,2,1,51,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,24923.937021,24558.216666,2,93,7,7,2.58,2,2,0,0,0,1,51,1,4,1,4 +67799,7,2,2,38,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,27945.726298,28031.650144,1,94,6,6,1.26,5,5,0,2,0,2,38,1,4,1,NA +67800,7,2,1,0,8,2,2,1,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5863.789973,5970.184293,2,93,8,8,2.17,4,4,2,0,0,2,30,1,4,1,4 +67801,7,2,2,11,NA,3,3,1,11,142,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17482.620882,17502.587262,1,94,7,7,1.29,6,6,1,3,0,1,38,1,3,1,2 +67802,7,2,1,4,NA,5,7,1,4,56,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8890.779467,9258.147648,3,91,10,10,2.48,5,5,2,1,0,2,27,1,2,1,4 +67803,7,2,1,6,NA,5,7,1,6,81,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,18834.739821,19876.018883,1,94,2,2,0.3,5,5,1,2,0,1,23,1,1,6,NA +67804,7,2,2,4,NA,5,6,1,4,52,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4437.828549,4650.082829,1,102,5,5,0.92,5,5,1,2,0,2,44,2,1,1,2 +67805,7,2,1,6,NA,4,4,2,6,82,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7687.032802,8119.723568,2,99,4,4,0.78,4,4,0,2,0,2,45,1,3,5,NA +67806,7,2,2,16,NA,2,2,2,16,198,NA,NA,1,1,NA,11,NA,NA,NA,1,2,2,2,2,2,1,2,2,1,20937.26435,23702.551829,1,90,5,5,1,4,4,0,2,0,1,40,2,2,1,1 +67807,7,2,2,3,NA,3,3,2,3,38,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,76623.952798,84569.150751,2,91,15,15,5,3,3,1,0,0,1,37,1,5,1,5 +67808,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,1,2,NA,40827.983435,45600.111014,1,98,8,8,2.62,3,3,0,0,3,1,68,1,4,1,4 +67809,7,2,1,13,NA,1,1,1,13,164,NA,NA,2,2,3,7,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,32326.52031,34735.818434,2,94,5,5,0.65,6,6,0,3,0,1,44,2,1,1,1 +67810,7,2,1,0,6,2,2,2,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5420.429995,5420.529903,3,90,6,6,1.3,4,4,2,0,0,1,20,2,5,6,NA +67811,7,2,1,2,NA,4,4,1,3,36,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6376.965739,6454.74783,2,100,15,15,5,3,3,1,0,0,2,35,1,5,1,2 +67812,7,2,1,66,NA,2,2,2,NA,NA,2,NA,2,2,2,NA,1,5,NA,2,2,2,1,2,2,2,2,2,2,12118.033999,12538.522644,2,91,99,99,NA,3,3,0,0,1,2,31,2,5,5,NA +67813,7,2,1,67,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,8561.661692,8628.633702,2,99,15,14,5,2,1,0,0,2,2,65,NA,NA,6,NA +67814,7,2,2,19,NA,4,4,1,19,232,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,18163.985724,18749.311901,2,101,1,1,0.06,1,1,0,0,0,2,19,1,4,NA,NA +67815,7,2,2,0,4,3,3,1,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,20786.668002,20803.881706,1,101,8,8,1.85,5,5,3,0,0,2,31,1,2,1,2 +67816,7,2,1,14,NA,4,4,2,14,170,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13969.457688,14306.402061,1,90,3,3,0.63,3,3,1,1,0,2,32,1,4,5,NA +67817,7,2,1,55,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,35958.875702,36129.285962,1,98,8,1,0,4,1,0,0,0,1,53,1,2,1,3 +67818,7,2,2,21,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,16007.367503,15264.693262,2,90,15,15,5,4,4,0,0,0,1,57,2,5,1,5 +67819,7,2,2,79,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,44856.466004,46390.551109,2,94,3,3,1.16,1,1,0,0,1,2,79,1,4,2,NA +67820,7,2,2,47,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,4,NA,1,2,2,1,2,2,1,2,2,1,19130.246369,19040.031855,2,95,7,7,1.74,4,4,0,2,0,2,47,1,5,4,NA +67821,7,2,1,7,NA,4,4,1,8,96,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12399.014378,12375.702699,2,96,2,2,0.31,4,4,0,2,0,2,30,NA,NA,6,NA +67822,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,38369.898602,44511.264162,2,95,3,3,0.95,2,2,0,0,2,2,80,1,1,1,2 +67823,7,2,2,15,NA,3,3,1,15,189,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,92934.523767,97199.343719,1,92,8,8,2.17,4,4,0,1,2,2,80,1,3,2,NA +67824,7,2,1,40,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,15851.563418,15794.298537,2,95,15,15,5,1,1,0,0,0,1,40,2,5,5,NA +67825,7,2,2,11,NA,4,4,1,11,139,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11116.391625,11531.852198,1,92,77,77,NA,5,5,1,2,0,2,41,1,3,5,NA +67826,7,2,1,51,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,122833.610417,128308.021903,1,98,15,15,4.34,4,4,0,2,0,1,51,1,5,1,5 +67827,7,2,1,53,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,27609.8026,27737.039026,2,101,8,8,2.7,3,3,0,1,0,1,53,1,4,1,2 +67828,7,2,1,67,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,1,10717.375231,11136.552864,2,101,4,4,1.22,2,2,0,0,2,1,67,1,1,1,2 +67829,7,2,1,19,NA,3,3,1,19,229,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,73465.215193,72911.812289,1,100,15,15,4.63,5,5,0,0,0,1,51,1,5,1,3 +67830,7,2,1,0,5,2,2,2,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,2,2,2,NA,NA,NA,NA,5733.655482,6014.350383,1,90,10,10,2.44,5,5,1,0,0,2,56,2,1,1,1 +67831,7,2,2,0,1,3,3,2,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16608.743852,16157.613485,1,94,15,15,5,4,4,2,0,0,1,37,1,5,1,4 +67832,7,2,2,71,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,17836.372654,18457.016952,2,96,5,5,0.67,6,6,1,2,1,1,34,1,4,1,4 +67833,7,2,1,80,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,12526.25131,13442.161918,2,95,5,5,1.32,2,2,0,0,2,2,78,1,2,1,2 +67834,7,2,2,33,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,92613.517882,94092.287712,3,91,8,6,2.75,3,1,0,0,0,1,23,1,4,1,4 +67835,7,2,2,9,NA,4,4,2,9,114,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7405.320425,7603.433563,2,99,6,6,1.13,4,4,1,1,0,1,33,1,3,6,NA +67836,7,2,1,24,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,108410.783716,112153.23206,1,91,8,8,2.17,4,4,0,0,0,1,59,1,4,1,5 +67837,7,2,1,8,NA,3,3,2,8,99,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,49922.147265,52289.098209,1,98,9,9,2.6,4,4,1,1,0,2,35,1,2,1,NA +67838,7,2,1,52,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,11650.457723,11613.298191,2,99,NA,77,NA,7,7,1,0,1,2,51,1,2,1,3 +67839,7,2,1,61,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,9313.036488,9824.696739,1,103,15,15,5,2,2,0,0,1,2,56,2,5,1,5 +67840,7,2,1,28,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,115954.75973,120569.27907,1,92,5,5,1.97,1,1,0,0,0,1,28,1,4,3,NA +67841,7,2,1,58,NA,5,6,2,NA,NA,2,NA,2,1,5,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,11498.794569,11546.882913,1,96,15,15,5,5,5,0,0,0,1,58,2,5,1,5 +67842,7,2,2,63,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,4,NA,1,2,2,1,2,2,1,2,2,1,16420.864787,17686.616768,2,102,1,1,0.16,3,3,1,0,1,2,63,1,2,4,NA +67843,7,2,1,3,NA,3,3,1,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,24655.003412,27816.70307,1,98,2,2,0.36,5,5,3,0,0,1,25,1,3,1,3 +67844,7,2,1,23,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,111284.977736,114467.051739,3,91,8,5,1.5,3,2,0,0,0,1,23,1,4,1,4 +67845,7,2,1,49,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,18116.816149,22904.074887,2,90,8,7,3.21,2,1,0,0,0,1,51,1,2,5,NA +67846,7,2,1,15,NA,5,7,2,15,183,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,60818.973858,62775.825513,1,99,15,15,5,4,4,0,2,0,2,44,1,5,1,5 +67847,7,2,2,43,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,NA,NA,NA,NA,16186.470589,15743.485359,2,99,3,3,0.42,6,6,1,2,0,2,43,1,4,6,NA +67848,7,2,1,66,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,1,12585.09113,13280.957381,2,98,4,4,1.34,2,2,0,0,2,1,66,1,1,1,1 +67849,7,2,2,0,11,5,7,2,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5882.73073,5843.204067,3,90,15,15,5,3,3,1,0,0,2,32,2,5,1,5 +67850,7,2,2,64,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,10192.188896,10440.656902,1,99,10,10,5,1,1,0,0,1,2,64,1,5,3,NA +67851,7,2,2,5,NA,3,3,2,5,62,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,51483.624552,53105.566664,1,94,15,15,5,4,4,2,0,0,1,51,2,5,1,5 +67852,7,2,1,15,NA,5,6,1,15,183,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12412.721558,13262.259083,1,92,10,10,2.82,4,4,0,2,0,2,48,2,5,1,5 +67853,7,2,1,37,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,19923.530941,23644.216851,2,95,6,6,0.97,6,6,2,2,0,1,37,1,3,1,4 +67854,7,2,1,80,NA,5,6,2,NA,NA,2,NA,2,2,2,NA,3,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,12101.489198,13370.144062,1,93,3,3,0.65,3,3,0,0,3,2,74,2,1,2,NA +67855,7,2,1,58,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,11498.794569,11546.882913,2,100,15,15,5,3,3,0,1,0,1,58,2,5,1,5 +67856,7,2,2,0,8,4,4,2,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4523.857227,4573.252417,2,95,6,6,1.57,3,3,1,0,0,1,29,1,3,1,4 +67857,7,2,2,25,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,16021.911789,17471.931528,1,94,7,7,1.79,4,4,0,1,0,1,59,2,4,1,4 +67858,7,2,2,68,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,NA,10049.7347,10691.470743,2,90,5,5,1.98,1,1,0,0,1,2,68,1,4,5,NA +67859,7,2,1,18,NA,4,4,1,18,219,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12792.875152,12871.476461,2,93,99,99,NA,7,6,1,0,0,1,19,1,3,NA,NA +67860,7,2,2,14,NA,3,3,2,14,174,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,23708.623398,24267.27809,2,97,5,5,1.08,3,3,0,1,0,2,45,1,4,6,NA +67861,7,2,1,60,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,85786.890667,86591.455494,2,96,9,9,5,1,1,0,0,1,1,60,1,5,5,NA +67862,7,2,1,1,20,3,3,2,NA,20,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,23524.870375,27564.905667,1,90,7,7,2.1,3,3,1,0,0,2,40,2,5,1,4 +67863,7,2,2,50,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,196995.351093,202246.928022,1,91,15,15,5,3,3,0,0,0,2,50,1,4,1,4 +67864,7,2,2,22,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,15735.580263,16455.708445,1,97,15,15,5,4,4,0,0,0,1,51,2,5,1,5 +67865,7,2,1,59,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,17121.370948,17378.349074,1,92,14,14,3.9,4,4,0,0,0,2,55,2,5,1,5 +67866,7,2,2,60,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,13101.965339,13686.954077,1,100,6,6,2.24,1,1,0,0,1,2,60,1,5,3,NA +67867,7,2,2,11,NA,2,2,1,11,138,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,13720.541363,14610.824098,2,100,4,4,0.81,4,4,0,2,0,2,37,1,2,1,2 +67868,7,2,2,13,NA,1,1,1,14,168,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,23979.296993,25562.604106,1,101,3,3,0.41,5,5,0,2,1,2,36,2,4,4,NA +67869,7,2,2,4,NA,2,2,2,4,50,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,1,2,2,1,NA,NA,NA,NA,12675.140707,13078.439708,1,96,5,5,0.94,4,4,2,0,0,1,32,2,3,1,4 +67870,7,2,2,20,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,1,1,2,2,1,10345.80475,11593.940235,3,90,15,15,3.23,6,6,0,2,0,1,50,2,2,1,2 +67871,7,2,2,6,NA,2,2,2,6,77,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15148.721588,15796.67129,2,91,10,10,3.04,4,4,1,1,0,2,31,2,5,1,5 +67872,7,2,2,78,NA,2,2,2,NA,NA,2,NA,2,1,9,NA,1,1,NA,2,2,2,1,2,2,2,2,2,NA,20441.922878,23572.887355,1,90,4,4,0.94,3,3,0,0,2,2,78,2,1,1,2 +67873,7,2,2,50,NA,1,1,1,NA,NA,2,NA,2,2,7,NA,1,1,NA,2,2,2,2,2,2,1,2,2,2,20388.95294,20876.134898,2,96,6,6,0.77,7,7,2,1,0,1,53,2,1,1,1 +67874,7,2,1,69,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,138075.879417,141933.339512,2,94,10,10,4.3,2,2,0,0,2,1,69,1,4,1,5 +67875,7,2,2,9,NA,4,4,1,9,110,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11195.065587,11548.620784,2,96,15,9,3.74,3,2,0,1,0,2,38,1,5,6,NA +67876,7,2,2,5,NA,4,4,2,5,63,NA,NA,2,1,2,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11353.600279,12216.600549,1,98,15,15,5,6,6,3,0,0,1,37,2,5,1,4 +67877,7,2,2,79,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,33602.625,34751.830256,2,103,15,15,3.44,7,7,0,1,2,2,79,1,3,2,NA +67878,7,2,1,9,NA,4,4,1,9,116,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8714.559478,8887.823591,2,96,7,7,1.04,7,7,0,4,0,2,37,1,3,3,NA +67879,7,2,2,45,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,139800.409559,142430.529735,1,100,15,15,5,4,4,0,1,0,1,50,1,4,1,4 +67880,7,2,1,13,NA,5,6,1,13,160,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9737.713978,10134.40846,2,100,14,14,4.03,4,4,0,2,0,1,48,2,5,1,5 +67881,7,2,2,17,NA,3,3,1,17,205,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,31282.308091,32019.424199,2,98,3,3,0.38,5,5,0,4,0,2,39,1,4,5,NA +67882,7,2,1,4,NA,3,3,2,4,51,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,86817.367332,101726.917198,2,91,15,15,5,4,4,2,0,0,1,35,1,5,1,5 +67883,7,2,1,5,NA,5,7,2,5,62,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12996.965152,13393.943951,1,101,2,2,0.33,4,4,2,1,0,2,26,1,4,5,NA +67884,7,2,2,10,NA,2,2,1,10,120,NA,NA,1,1,NA,3,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,16986.005478,17464.743129,2,102,5,5,0.89,4,4,0,3,0,2,44,2,2,4,NA +67885,7,2,2,80,NA,4,4,2,NA,NA,2,NA,2,2,4,NA,3,2,NA,1,2,1,1,2,1,1,2,1,NA,12344.929687,13171.097693,1,93,1,1,0.28,1,1,0,0,1,2,80,2,3,2,NA +67886,7,2,2,3,NA,1,1,1,4,48,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12714.663639,13516.237728,1,102,5,5,0.86,5,5,2,0,0,2,21,2,2,5,NA +67887,7,2,2,67,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,17243.546687,17909.086027,1,92,14,14,5,2,2,0,0,2,1,62,1,4,1,4 +67888,7,2,1,8,NA,3,3,1,8,105,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,27154.222487,28089.451048,2,101,4,4,0.73,5,5,1,2,0,1,40,1,5,1,5 +67889,7,2,2,42,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,30863.871606,31440.435679,1,101,4,4,1.43,1,1,0,0,0,2,42,1,5,5,NA +67890,7,2,2,7,NA,1,1,2,7,88,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,14300.71869,14814.284705,2,94,13,13,NA,5,5,0,3,0,1,32,2,2,1,1 +67891,7,2,2,29,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,17204.739153,20747.6165,1,93,9,9,5,1,1,0,0,0,2,29,1,5,5,NA +67892,7,2,2,10,NA,3,3,1,10,123,NA,NA,2,2,3,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,13450.606713,14078.286101,3,91,4,4,0.65,5,5,2,2,0,2,27,2,2,3,NA +67893,7,2,1,34,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,83819.702285,99717.125794,1,99,14,14,5,1,1,0,0,0,1,34,1,5,5,NA +67894,7,2,1,80,NA,5,7,1,NA,NA,1,1,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,38080.409655,40864.822189,2,95,6,6,1.95,2,2,0,0,2,1,80,1,1,1,3 +67895,7,2,1,8,NA,4,4,1,8,104,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9261.557132,9782.87535,2,100,7,7,1.79,4,4,0,1,0,2,51,1,3,3,NA +67896,7,2,1,17,NA,4,4,2,17,205,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,15381.581315,15476.088016,1,93,12,12,NA,5,4,0,2,0,1,32,1,2,5,NA +67897,7,2,2,71,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,60257.408263,62318.203523,1,103,15,15,5,2,2,0,0,2,1,74,1,5,1,5 +67898,7,2,2,60,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,4,NA,1,2,2,1,2,2,1,2,2,1,11696.973403,12170.020379,2,97,6,6,1,6,6,1,2,2,2,60,1,2,2,NA +67899,7,2,1,80,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,4,NA,1,2,2,1,2,2,1,2,2,NA,7663.797586,8115.960731,1,96,3,3,1.25,1,1,0,0,1,1,80,1,2,4,NA +67900,7,1,1,24,NA,5,6,NA,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,13859.220514,0,1,98,12,2,0.54,3,1,0,0,0,1,24,1,4,5,NA +67901,7,2,2,73,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,12222.312509,13136.499838,2,95,12,12,NA,3,3,0,0,3,2,73,1,2,1,1 +67902,7,2,1,21,NA,1,1,1,NA,NA,2,NA,2,2,3,NA,3,4,NA,2,2,2,2,2,2,2,2,2,2,39915.513053,44831.646235,2,98,5,5,1.07,4,4,0,1,0,1,53,2,1,1,1 +67903,7,2,2,3,NA,4,4,2,3,45,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10771.85499,11049.894844,2,97,1,1,0.2,2,2,1,0,0,2,26,1,4,5,NA +67904,7,2,1,1,21,2,2,1,NA,22,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12373.634774,12852.001067,1,92,10,10,2.63,5,5,2,1,0,2,26,1,4,1,4 +67905,7,2,2,10,NA,5,7,1,10,124,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,5836.229473,6119.1334,2,103,14,14,3.48,5,5,0,2,1,1,43,1,4,1,5 +67906,7,2,2,8,NA,3,3,2,8,105,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,24070.467912,25563.654853,1,95,15,15,3.62,7,7,2,4,0,1,59,1,5,1,2 +67907,7,2,2,37,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,74517.751389,89988.433696,2,94,12,12,NA,5,5,1,1,0,1,37,1,4,1,3 +67908,7,2,1,28,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,23235.97926,24675.846787,2,95,6,6,1.36,3,3,0,0,2,2,60,1,5,1,4 +67909,7,2,1,0,6,1,1,1,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,2,2,2,NA,NA,NA,NA,6218.697738,6608.80804,2,96,6,6,0.77,7,7,2,1,0,1,53,2,1,1,1 +67910,7,2,1,80,NA,2,2,1,NA,NA,1,1,99,NA,NA,NA,9,1,NA,1,1,2,1,1,2,1,1,2,NA,13906.496347,14197.251523,2,103,99,99,NA,6,1,0,0,3,1,80,NA,NA,2,NA +67911,7,2,1,15,NA,3,3,1,15,186,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,81936.967747,80860.127913,1,94,14,14,2.96,5,5,0,3,0,2,39,1,4,1,3 +67912,7,2,1,65,NA,2,2,1,NA,NA,1,2,2,1,7,NA,5,1,NA,2,2,2,1,2,2,1,2,2,1,14067.170863,14292.508976,2,102,15,15,5,3,3,0,0,2,1,36,2,5,5,NA +67913,7,2,1,11,NA,1,1,1,11,133,NA,NA,1,1,NA,4,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,13665.416457,13541.311863,1,94,2,2,0.27,5,5,0,4,0,2,47,2,1,4,NA +67914,7,2,1,8,NA,3,3,1,9,108,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,23188.935049,25672.571973,3,91,7,7,1.1,7,7,0,4,0,1,40,1,4,1,3 +67915,7,2,1,24,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,15976.466658,17286.192057,2,96,8,5,2.2,2,1,0,0,0,2,25,2,5,5,NA +67916,7,2,2,39,NA,2,2,1,NA,NA,2,NA,2,1,6,NA,4,1,2,2,2,2,2,2,2,NA,NA,NA,NA,38184.257672,39931.153329,2,91,8,8,1.85,5,5,0,2,1,1,39,2,3,1,4 +67917,7,2,1,27,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,22634.531479,23281.741513,1,103,9,6,2.6,3,1,0,0,0,1,27,1,5,5,NA +67918,7,2,2,19,NA,4,4,2,19,232,2,NA,2,2,3,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,10694.834447,10900.381844,1,90,4,4,0.58,6,6,0,3,0,2,21,2,5,5,NA +67919,7,2,2,59,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,186864.831109,211461.930376,1,97,3,3,1.3,1,1,0,0,0,2,59,1,4,3,NA +67920,7,2,2,1,19,2,2,2,NA,20,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13464.808163,13893.232889,1,101,15,15,4.99,4,4,2,0,0,1,31,1,4,1,4 +67921,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,NA,51644.110977,57877.507418,1,102,14,14,5,2,2,0,0,1,2,59,1,5,3,NA +67922,7,2,2,3,NA,5,6,1,3,47,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7483.230909,7475.326886,2,96,15,15,5,3,3,1,0,0,1,34,2,5,1,5 +67923,7,2,2,11,NA,4,4,2,11,134,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8115.309776,8917.717263,2,95,6,6,0.97,6,6,2,2,0,1,37,1,3,1,4 +67924,7,2,2,45,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,19150.604366,19611.675453,3,91,15,15,4.47,4,4,0,1,0,2,45,2,5,1,5 +67925,7,2,2,51,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,12449.932013,12144.773422,3,90,7,7,2.23,3,3,0,0,0,2,51,1,4,3,NA +67926,7,2,2,40,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,15819.48188,17091.862943,1,90,15,15,5,3,3,1,0,0,1,42,1,5,1,5 +67927,7,2,1,32,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,15137.053737,17738.779486,2,99,15,15,5,1,1,0,0,0,1,32,1,5,5,NA +67928,7,2,2,34,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,64581.191728,64779.757488,2,94,15,15,5,2,2,0,0,0,1,36,1,2,1,4 +67929,7,1,2,20,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,4,5,3,1,2,2,1,2,2,NA,NA,NA,NA,18723.98095,0,2,95,9,9,1.81,6,6,1,1,0,2,56,1,4,3,NA +67930,7,2,1,59,NA,1,1,2,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,27595.50738,28151.492876,1,98,10,10,3.51,3,3,0,0,0,1,59,2,5,1,4 +67931,7,2,1,0,10,1,1,1,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5991.543696,6284.863687,1,102,5,5,0.86,5,5,2,0,0,2,21,2,2,5,NA +67932,7,2,1,9,NA,3,3,1,9,110,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,48147.167375,49984.220445,3,92,14,14,2.74,6,6,2,2,0,1,35,1,5,1,4 +67933,7,2,1,12,NA,3,3,1,12,146,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,124064.997098,122531.713298,1,95,7,7,2.54,2,2,0,1,0,2,37,1,1,5,NA +67934,7,2,2,16,NA,3,3,1,16,194,NA,NA,1,1,NA,8,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,113907.203714,124196.980527,1,94,7,7,1.52,4,4,0,2,2,1,61,2,1,1,5 +67935,7,2,1,35,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,74265.831326,76685.765974,3,92,14,14,2.74,6,6,2,2,0,1,35,1,5,1,4 +67936,7,2,1,13,NA,5,6,2,14,168,NA,NA,1,1,NA,7,NA,NA,NA,1,1,1,1,2,1,1,2,2,1,10346.302718,11357.395963,2,91,12,12,NA,7,6,0,4,2,2,72,2,1,2,NA +67937,7,1,2,74,NA,1,1,NA,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,15730.58404,0,2,98,77,77,NA,4,4,0,0,2,1,71,NA,NA,1,1 +67938,7,2,2,27,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,16026.268721,19326.470131,1,93,14,14,5,1,1,0,0,0,2,27,1,5,5,NA +67939,7,2,1,72,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,49653.587757,54188.961403,2,98,15,15,5,2,2,0,0,2,2,66,1,3,1,1 +67940,7,2,1,66,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,22184.040999,22468.589781,2,94,8,8,3.06,2,2,0,0,2,1,66,1,4,1,4 +67941,7,2,2,26,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,4,2,1,2,2,1,2,2,1,2,2,1,35313.648114,35629.376203,2,95,6,6,0.9,6,6,1,1,0,1,49,1,1,1,1 +67942,7,2,1,1,12,2,2,2,NA,13,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,8331.647763,8595.381151,2,90,99,99,NA,5,5,1,1,0,2,40,2,3,1,1 +67943,7,2,1,5,NA,5,7,2,5,71,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6176.631821,6670.596558,1,93,15,15,5,5,5,1,2,0,2,40,1,5,1,5 +67944,7,2,2,10,NA,4,4,2,10,131,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11467.793741,13004.375485,2,91,6,6,0.78,7,7,1,4,0,2,38,2,2,77,NA +67945,7,2,1,6,NA,3,3,1,6,81,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,38712.032122,41122.784973,3,91,15,15,5,6,6,1,3,0,2,40,1,5,1,5 +67946,7,2,1,3,NA,1,1,1,3,39,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,18754.85406,18780.196288,2,102,5,5,0.89,4,4,2,0,0,1,33,2,9,1,2 +67947,7,2,1,79,NA,4,4,1,NA,NA,2,NA,2,2,4,NA,3,1,NA,1,2,2,1,2,1,1,2,2,NA,8074.739647,8488.510868,2,93,13,13,NA,3,3,0,0,2,2,63,2,2,1,3 +67948,7,2,1,27,NA,2,2,1,NA,NA,2,NA,2,1,4,NA,4,5,NA,2,2,2,NA,NA,NA,1,2,2,1,44549.73661,46547.524849,2,93,4,4,0.69,4,4,0,1,1,2,66,2,3,2,NA +67949,7,2,2,10,NA,2,2,2,10,129,NA,NA,2,2,1,5,NA,NA,NA,2,1,2,1,2,2,1,2,2,2,10762.400563,12070.126078,2,90,3,3,0.46,5,5,1,3,0,2,35,2,1,4,NA +67950,7,2,2,4,NA,4,4,1,4,53,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11914.048896,13313.886049,1,100,14,14,3.6,4,4,1,1,0,1,41,1,4,1,5 +67951,7,2,2,59,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,15521.115746,18174.62037,1,96,12,12,NA,7,7,1,0,1,2,59,1,3,1,1 +67952,7,2,2,65,NA,2,2,2,NA,NA,2,NA,2,1,9,NA,1,5,NA,1,2,2,1,2,2,1,2,2,1,9716.805546,12994.252166,2,90,2,2,0.55,1,1,0,0,1,2,65,2,1,5,NA +67953,7,2,1,0,9,4,4,2,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5081.270665,5448.486113,2,99,77,77,NA,6,6,1,1,0,2,42,1,3,1,3 +67954,7,2,1,15,NA,2,2,2,15,181,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,21399.234084,21768.65302,1,91,15,15,5,4,4,0,2,0,1,49,1,5,1,5 +67955,7,2,2,12,NA,3,3,2,12,147,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,71303.309206,77744.474592,2,94,15,15,5,5,5,0,3,0,1,44,1,5,1,4 +67956,7,2,2,3,NA,5,6,2,3,37,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4369.011217,4638.097632,2,100,4,4,0.44,7,7,1,2,2,1,71,2,1,1,1 +67957,7,2,1,50,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,2,3,NA,1,2,2,NA,NA,NA,1,2,2,1,27609.8026,27521.740194,2,101,99,99,NA,3,3,0,1,1,2,78,1,1,2,NA +67958,7,2,2,43,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,3,1,3,1,2,2,1,2,2,NA,NA,NA,NA,9131.449129,11051.567129,1,103,77,77,NA,6,6,0,2,2,1,70,NA,NA,1,1 +67959,7,2,1,13,NA,4,4,1,13,162,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,16147.713323,16532.569027,1,92,5,5,0.95,4,4,0,2,0,2,33,1,4,5,NA +67960,7,2,2,40,NA,2,2,1,NA,NA,2,NA,2,2,4,NA,5,1,2,2,2,2,2,2,2,2,2,2,2,31334.47528,32058.983464,2,96,7,7,1.57,4,4,0,2,0,1,40,2,2,1,5 +67961,7,2,1,6,NA,2,2,2,6,80,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15882.795076,15889.831109,1,97,3,3,0.44,5,5,2,2,0,2,26,1,4,4,NA +67962,7,2,2,40,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,2,2,1,2,2,1,2,2,1,2,2,1,16339.124275,15891.961277,2,95,15,15,3.85,7,7,0,3,1,2,62,1,4,2,NA +67963,7,2,2,11,NA,4,4,1,11,141,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8146.767632,8771.942314,2,100,6,6,0.99,5,5,0,3,0,2,40,1,3,1,3 +67964,7,2,2,31,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,3,2,1,2,2,1,2,2,NA,NA,NA,NA,31335.13799,33684.15133,1,95,6,3,0.45,6,4,1,2,0,1,28,1,2,1,2 +67965,7,2,1,74,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,52448.388619,54438.22579,1,99,8,8,3.4,2,2,0,0,2,1,74,1,5,1,4 +67966,7,2,1,20,NA,3,3,1,NA,NA,2,NA,2,1,6,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,101419.325386,103801.228657,1,100,15,15,4.63,5,5,0,0,0,1,51,1,5,1,3 +67967,7,2,1,52,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,158509.005274,159425.752864,1,100,15,15,4.07,5,5,0,2,0,2,41,1,5,1,4 +67968,7,2,2,7,NA,5,6,2,7,88,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6878.565723,7345.278289,3,90,14,14,4.71,3,3,0,1,0,1,43,1,5,1,5 +67969,7,2,2,40,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,2,1,2,2,1,2,2,1,2,2,1,118269.59683,119479.91378,2,98,10,10,4.55,2,2,0,0,1,2,66,1,5,2,NA +67970,7,2,1,72,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,48254.793439,51076.634961,2,100,99,99,NA,2,2,0,0,2,1,72,1,4,1,4 +67971,7,2,2,11,NA,1,1,1,11,140,NA,NA,1,1,NA,4,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,12215.503444,12532.555214,1,102,5,5,0.92,5,5,0,3,0,2,39,2,3,1,3 +67972,7,2,1,30,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,84910.063417,90031.493834,2,96,14,4,1.38,3,1,0,0,0,1,30,2,5,5,NA +67973,7,2,1,6,NA,5,6,2,6,82,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10810.913614,11522.32071,1,97,15,15,4.07,5,5,0,3,0,1,42,2,5,1,5 +67974,7,2,1,27,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,37814.382501,44413.458724,1,98,3,3,1.03,1,1,0,0,0,1,27,1,4,5,NA +67975,7,2,2,76,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,33731.056243,36109.766611,2,98,4,4,1.22,2,2,0,0,2,1,80,1,1,1,1 +67976,7,1,1,34,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,99134.771466,0,2,99,15,15,5,2,2,0,0,0,2,34,NA,NA,1,5 +67977,7,2,2,56,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,4,4,NA,1,2,2,1,2,2,1,2,2,1,17152.714252,16747.256128,1,102,7,1,0.33,5,1,1,0,2,1,47,1,3,5,NA +67978,7,2,2,60,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,49428.481088,50236.061312,1,101,1,1,0.13,1,1,0,0,1,2,60,1,4,3,NA +67979,7,2,1,65,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,8232.241159,8296.636338,2,98,7,7,2.72,2,2,0,0,1,1,65,1,4,3,NA +67980,7,2,2,8,NA,4,4,1,8,105,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8362.256577,8929.488766,2,100,7,7,1.34,5,5,0,2,0,2,53,1,4,4,NA +67981,7,2,1,19,NA,1,1,2,19,238,2,NA,2,1,4,15,NA,NA,NA,1,2,2,2,2,2,1,2,2,1,20174.283097,21488.447069,2,94,7,7,1.33,6,6,0,1,0,1,55,2,2,1,1 +67982,7,1,1,42,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,148374.146816,0,2,96,10,6,2.66,2,1,0,0,0,1,35,1,5,5,NA +67983,7,2,2,47,NA,5,6,2,NA,NA,2,NA,2,1,5,NA,5,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,13568.706187,17300.043727,3,90,6,6,1.98,2,2,0,0,0,2,47,2,5,2,NA +67984,7,2,1,20,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,85040.351078,89341.219459,1,93,7,7,2.16,3,3,0,1,0,2,50,1,5,3,NA +67985,7,2,1,13,NA,3,3,2,13,157,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,58479.782556,60361.370686,1,99,15,15,5,5,5,0,3,0,2,43,1,5,1,5 +67986,7,2,2,63,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,1,8411.959333,8787.544319,1,96,9,9,3.97,2,2,0,0,1,1,28,1,5,5,NA +67987,7,2,2,6,NA,4,4,2,6,82,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7446.876055,7952.015759,2,99,6,6,1.15,5,5,1,2,0,2,34,1,4,77,NA +67988,7,2,1,14,NA,3,3,2,14,176,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,58479.782556,60361.370686,1,99,15,15,5,5,5,0,3,0,2,43,1,5,1,5 +67989,7,2,2,22,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,3,5,3,1,2,2,1,2,2,NA,NA,NA,NA,55392.206282,57222.234271,3,91,3,3,1.29,1,1,0,0,0,2,22,1,3,5,NA +67990,7,2,2,12,NA,5,6,2,12,148,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6937.463063,7205.726089,3,90,10,10,2.41,5,5,1,2,0,1,44,2,4,1,5 +67991,7,2,1,57,NA,5,6,2,NA,NA,2,NA,2,2,2,NA,2,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,11690.444016,12095.591726,3,90,4,4,0.92,3,3,0,0,1,2,56,2,2,1,2 +67992,7,2,1,41,NA,2,2,1,NA,NA,2,NA,2,2,6,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,52941.648658,52646.945429,2,102,15,15,5,2,2,0,0,0,1,41,2,4,6,NA +67993,7,2,1,60,NA,2,2,2,NA,NA,2,NA,2,1,8,NA,1,5,NA,2,2,2,2,2,2,1,2,2,NA,8609.250304,11228.904188,2,90,4,4,0.57,5,5,1,0,2,2,80,2,1,2,NA +67994,7,2,1,12,NA,3,3,2,13,156,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,71458.892941,71654.216305,2,94,3,3,0.54,4,4,0,1,0,2,48,1,3,1,3 +67995,7,2,1,70,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,58072.588922,61468.555023,1,101,14,14,5,2,2,0,0,2,2,70,1,5,1,2 +67996,7,2,1,9,NA,1,1,1,9,110,NA,NA,1,1,NA,2,NA,NA,NA,2,1,2,1,2,2,2,2,2,2,11367.678664,11547.566042,2,96,5,5,0.78,5,5,0,2,0,1,37,2,1,5,NA +67997,7,1,2,25,NA,5,6,NA,NA,NA,2,NA,1,1,NA,NA,5,5,3,1,2,2,1,2,2,NA,NA,NA,NA,11934.941038,0,3,90,8,8,1.85,5,5,0,0,1,2,25,1,5,5,NA +67998,7,2,2,52,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,5,2,NA,1,2,2,1,2,2,1,2,2,1,17991.883465,18228.515837,2,102,10,10,3.62,3,3,0,0,0,1,51,2,5,1,5 +67999,7,2,2,52,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,24004.6026,25447.359355,2,91,14,14,4.19,3,3,0,1,0,1,55,2,3,1,5 +68000,7,2,1,65,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,21941.544332,21717.573526,1,99,10,10,2.58,5,5,0,1,2,1,65,1,5,1,3 +68001,7,2,1,79,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,2,4,NA,1,2,2,1,2,2,1,2,2,NA,8992.410435,11769.853451,2,90,4,4,1.43,1,1,0,0,1,1,79,1,2,4,NA +68002,7,2,2,11,NA,3,3,1,11,135,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,55469.656717,57246.428971,1,98,9,9,2.15,5,5,0,3,0,2,32,1,3,1,4 +68003,7,2,1,72,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,15262.668516,16210.38509,1,102,7,7,1.41,5,5,0,2,2,1,72,1,4,1,3 +68004,7,2,2,33,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,36002.138941,36147.943555,1,103,15,15,5,2,2,0,0,0,1,36,2,5,1,5 +68005,7,2,1,21,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,25815.880139,26556.735732,2,101,99,2,0.55,2,1,0,0,0,1,21,NA,NA,5,NA +68006,7,2,1,13,NA,4,4,2,13,167,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15970.206483,16374.875978,2,97,3,3,0.46,5,5,0,3,0,1,40,1,2,1,3 +68007,7,2,2,33,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,23038.68441,23821.989403,1,92,6,6,1.92,2,2,0,0,0,2,33,2,4,5,NA +68008,7,2,1,80,NA,2,2,1,NA,NA,2,NA,2,1,8,NA,3,2,NA,2,2,2,2,2,2,NA,NA,NA,NA,9710.399795,10186.406299,2,93,99,99,NA,1,1,0,0,1,1,80,2,3,2,NA +68009,7,2,2,14,NA,4,4,1,14,175,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13697.127402,13594.601175,2,100,10,7,2.05,4,3,0,2,0,1,20,1,4,6,NA +68010,7,2,1,63,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,1,10717.375231,11218.730451,2,97,3,3,1.29,1,1,0,0,1,1,63,1,2,2,NA +68011,7,2,2,27,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,47973.37979,48741.666001,1,95,6,6,0.81,6,6,2,2,0,1,30,1,3,1,4 +68012,7,2,2,70,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,12537.004291,13376.026635,2,98,77,77,NA,2,2,0,0,2,2,70,1,3,1,2 +68013,7,2,2,60,NA,2,2,1,NA,NA,2,NA,2,1,7,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,14067.755128,14924.32642,2,91,8,8,4.3,1,1,0,0,1,2,60,2,5,5,NA +68014,7,2,1,16,NA,3,3,2,16,197,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,30100.326038,29873.584609,1,101,6,6,1.17,4,4,0,1,0,1,41,1,3,6,NA +68015,7,2,2,9,NA,3,3,2,9,109,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,19824.800404,20630.46787,1,101,4,4,0.78,4,4,1,2,0,2,32,1,3,3,NA +68016,7,2,2,56,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,159097.269198,158226.612798,1,97,15,15,4.77,4,4,0,0,0,1,56,1,4,1,4 +68017,7,2,2,68,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,16352.915834,18960.412859,3,92,10,10,4.3,5,2,2,1,1,2,68,1,3,1,1 +68018,7,2,1,1,22,5,6,2,NA,24,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5891.941477,6363.138629,1,90,6,6,0.92,6,6,2,0,2,2,30,2,5,1,5 +68019,7,2,1,12,NA,3,3,1,12,149,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,71934.689876,71392.8162,1,100,15,15,5,5,5,0,3,0,1,47,1,5,1,5 +68020,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,35334.703093,40990.264786,1,101,3,3,1.25,1,1,0,0,1,2,80,1,2,2,NA +68021,7,2,1,34,NA,4,4,2,NA,NA,2,NA,2,2,2,NA,2,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,20803.970543,21211.256549,1,93,5,5,1.84,1,1,0,0,0,1,34,2,2,5,NA +68022,7,2,1,58,NA,1,1,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,37426.314738,36877.141263,3,92,15,15,5,2,2,0,0,0,1,58,1,4,1,4 +68023,7,2,1,25,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,5,5,NA,1,2,2,NA,NA,NA,1,2,2,1,9177.295801,9548.31812,2,92,77,77,NA,4,4,0,0,0,1,27,2,2,5,NA +68024,7,2,2,26,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,3,5,2,2,2,2,1,2,2,NA,NA,NA,NA,30253.427014,34374.819903,2,90,6,6,2.01,2,2,0,1,0,2,26,1,3,5,NA +68025,7,2,2,19,NA,2,2,1,19,238,2,NA,2,2,3,15,NA,NA,NA,2,2,2,1,2,2,1,2,2,1,18556.092615,19088.608674,1,103,6,6,0.93,5,5,0,1,0,1,39,2,3,1,3 +68026,7,2,2,1,19,5,7,2,NA,19,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6683.092466,7272.710878,3,91,8,8,2.7,3,3,1,0,0,1,31,1,5,1,5 +68027,7,2,2,41,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,18490.479848,18604.849683,2,100,8,8,2.7,3,3,1,0,0,2,41,1,4,1,3 +68028,7,2,2,66,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,14994.337564,16150.13007,1,100,9,9,3.97,2,2,0,0,2,1,70,NA,NA,1,3 +68029,7,2,1,60,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,7973.883342,8285.757609,1,100,3,3,0.9,1,1,0,0,1,1,60,1,3,5,NA +68030,7,2,1,20,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,89234.06428,94763.645369,1,93,15,15,5,4,3,0,0,3,1,80,1,5,2,NA +68031,7,2,1,2,NA,1,1,1,2,32,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10276.786905,10398.280565,1,102,4,4,0.5,6,6,2,2,0,1,25,1,2,1,3 +68032,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,36401.782557,40656.559204,2,100,6,6,2.01,2,2,0,0,2,1,80,1,5,1,5 +68033,7,2,1,2,NA,3,3,1,3,36,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,49276.9767,53002.397569,2,98,8,8,2.42,4,4,2,0,0,2,31,1,4,1,2 +68034,7,2,2,68,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,1,11190.39853,11690.037855,2,99,99,99,NA,2,2,0,0,2,2,62,1,5,3,NA +68035,7,2,2,78,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,55793.89654,57702.040299,2,103,12,12,NA,1,1,0,0,1,2,78,1,4,2,NA +68036,7,2,1,3,NA,1,1,2,3,41,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,14505.510202,14266.522334,2,94,5,5,1.3,3,3,1,0,0,2,38,2,1,1,4 +68037,7,2,1,13,NA,5,6,2,13,167,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6666.045669,7124.269577,3,90,15,15,5,4,4,0,2,0,2,41,2,5,1,5 +68038,7,2,1,68,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,7238.674935,7295.298127,1,96,15,15,5,3,3,0,0,2,2,44,1,5,5,NA +68039,7,2,2,0,1,1,1,1,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7849.042868,8059.930457,2,98,14,14,3.25,5,5,2,1,0,1,37,1,5,1,5 +68040,7,2,1,25,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,29738.952706,30201.133298,2,94,8,8,3.4,2,2,0,0,0,1,22,1,3,5,NA +68041,7,2,1,63,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,6441.264127,6693.19464,1,96,15,15,5,2,2,0,0,2,1,63,1,3,1,3 +68042,7,2,1,23,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,32375.321924,34954.784356,1,98,2,2,0.31,3,3,1,0,0,1,45,NA,NA,1,NA +68043,7,2,2,32,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,79351.077678,83837.616505,2,98,9,9,4.01,2,2,0,0,0,1,27,1,5,1,4 +68044,7,2,2,58,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,187291.098551,189225.431861,2,91,7,7,2.31,2,2,0,0,0,2,58,1,5,3,NA +68045,7,2,2,13,NA,4,4,2,13,162,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10671.280357,10591.403308,1,99,10,10,3.13,4,4,0,2,0,1,35,1,4,1,5 +68046,7,2,2,65,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,149575.283913,151406.873597,1,95,5,5,1.84,1,1,0,0,1,2,65,1,3,3,NA +68047,7,2,1,7,NA,5,6,2,7,93,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10810.913614,11461.625841,1,97,15,15,5,3,3,0,1,0,2,36,2,5,1,5 +68048,7,2,1,10,NA,4,4,2,10,131,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9699.683862,9815.96792,2,100,1,1,0.06,3,3,1,1,0,2,30,1,4,5,NA +68049,7,2,2,6,NA,5,6,2,6,79,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9227.090107,9736.375878,2,100,15,15,5,4,4,1,1,0,1,41,2,5,1,5 +68050,7,2,2,80,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,21143.97379,22281.995197,1,97,77,77,NA,3,3,0,0,3,2,62,1,5,1,NA +68051,7,1,1,51,NA,2,2,NA,NA,NA,2,NA,1,1,NA,NA,5,1,NA,2,2,2,1,2,2,NA,NA,NA,NA,24595.31055,0,1,97,15,15,5,4,4,0,2,0,1,51,1,5,1,NA +68052,7,2,1,39,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,18404.681357,22792.166915,1,101,4,4,0.58,6,6,0,4,0,2,41,1,3,5,NA +68053,7,2,1,4,NA,1,1,1,4,52,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,18754.85406,20094.472571,2,102,10,10,3.04,4,4,2,0,0,2,31,2,2,1,NA +68054,7,2,2,8,NA,3,3,2,8,98,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,43531.157975,44359.496292,1,91,7,7,1.88,4,4,1,2,0,2,43,1,5,4,NA +68055,7,2,1,0,1,5,6,2,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5300.922196,5735.896742,3,90,7,7,1.82,4,4,1,0,0,2,54,2,1,3,NA +68056,7,2,2,6,NA,4,4,2,6,83,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7136.421849,7489.546444,1,90,9,9,1.65,7,7,0,4,0,1,36,1,4,1,4 +68057,7,1,1,6,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,66000.998272,0,1,90,15,15,5,4,4,1,1,0,2,39,1,5,1,4 +68058,7,2,1,50,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,123771.419917,129271.862102,2,98,8,8,2.7,3,3,0,0,1,2,71,NA,NA,2,NA +68059,7,1,1,29,NA,1,1,NA,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,35782.041084,0,2,96,3,3,0.54,4,4,1,1,0,1,29,1,2,1,2 +68060,7,2,1,18,NA,3,3,1,18,217,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,69211.537407,74163.290023,1,92,14,14,3.16,6,6,1,1,0,1,49,1,1,1,3 +68061,7,2,2,35,NA,5,6,1,NA,NA,2,NA,2,1,3,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,21619.283038,21815.3204,2,102,15,15,3.92,5,5,1,2,0,1,34,2,5,1,5 +68062,7,2,1,28,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,59682.963348,63721.06052,2,102,10,7,3.67,2,1,0,0,0,2,27,1,4,6,NA +68063,7,2,1,51,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,27227.937106,28128.07977,1,101,1,1,0.27,1,1,0,0,0,1,51,1,3,3,NA +68064,7,2,2,80,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,17057.278872,18910.504828,2,98,2,2,0.82,1,1,0,0,1,2,80,1,3,2,NA +68065,7,2,2,20,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,114993.808573,116714.079488,1,98,7,3,0.9,4,1,0,0,0,2,20,1,4,5,NA +68066,7,2,2,63,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,9518.80186,9943.806181,2,100,14,14,5,2,2,0,0,2,2,63,1,5,1,4 +68067,7,2,2,2,NA,5,6,1,2,30,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8818.200077,9596.189182,2,102,9,9,2.68,4,4,1,1,0,2,38,2,5,1,2 +68068,7,2,2,79,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,74947.363106,78666.944453,2,91,15,15,5,2,2,0,0,2,2,79,1,5,1,5 +68069,7,2,2,66,NA,2,2,2,NA,NA,2,NA,2,2,7,NA,3,5,NA,2,2,2,2,2,2,NA,NA,NA,NA,10136.963678,11753.317783,2,94,2,2,0.41,2,2,0,1,1,2,66,2,3,5,NA +68070,7,2,1,47,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,19692.655418,21458.476044,2,99,13,13,NA,3,3,0,0,1,1,80,1,2,2,NA +68071,7,1,1,27,NA,5,6,NA,NA,NA,2,NA,2,1,6,NA,5,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,11977.649578,0,2,92,15,10,5,3,1,0,0,0,1,29,1,5,5,NA +68072,7,2,1,14,NA,3,3,1,14,173,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,75412.415858,75196.316989,2,98,15,15,5,4,4,0,2,0,2,46,1,4,1,NA +68073,7,2,1,58,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,26124.541799,26375.922323,1,94,4,4,1.34,4,1,0,0,0,1,58,1,4,6,NA +68074,7,2,1,1,16,5,7,2,NA,17,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8361.302835,9219.703624,1,101,13,13,NA,3,3,1,0,0,2,19,1,2,NA,NA +68075,7,2,1,59,NA,5,6,2,NA,NA,1,1,2,1,7,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,15693.68983,16353.841376,1,94,7,7,1.79,4,4,0,1,0,1,59,2,4,1,4 +68076,7,2,1,30,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,101896.080785,107317.764998,3,91,6,6,2.3,1,1,0,0,0,1,30,1,4,3,NA +68077,7,2,2,72,NA,3,3,2,NA,NA,2,NA,2,1,9,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,54256.870337,56112.448006,2,91,12,12,NA,2,2,0,0,2,1,76,1,5,1,2 +68078,7,2,2,38,NA,5,6,2,NA,NA,2,NA,2,2,99,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,13392.164122,13834.479479,3,90,15,15,5,3,3,0,0,0,1,46,2,3,1,3 +68079,7,2,2,49,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,37307.740846,37344.375392,1,91,5,5,1.36,2,2,0,1,0,2,49,1,5,3,NA +68080,7,2,2,39,NA,5,6,1,NA,NA,2,NA,2,1,3,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,19741.154437,19920.161476,1,100,5,5,0.74,6,6,0,3,0,1,40,2,3,1,4 +68081,7,2,2,1,21,4,4,1,NA,22,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7382.686927,7573.246603,2,100,8,8,2.33,4,4,1,0,0,2,50,1,4,3,NA +68082,7,2,1,0,0,3,3,2,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,22570.662508,23423.888442,1,95,12,12,NA,5,5,1,1,0,2,46,1,4,1,4 +68083,7,2,1,10,NA,2,2,1,10,128,NA,NA,1,1,NA,4,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,12577.115885,12649.318947,2,96,7,7,1.57,4,4,0,2,0,1,40,2,2,1,5 +68084,7,2,1,20,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,25815.880139,26556.735732,2,101,1,1,0.14,2,1,0,0,0,1,20,1,4,5,NA +68085,7,2,2,16,NA,1,1,2,16,194,NA,NA,2,2,4,9,NA,NA,NA,2,2,2,2,2,2,1,2,2,1,18368.872199,19023.186366,2,94,4,4,0.63,6,6,1,2,0,2,36,2,3,1,1 +68086,7,2,2,27,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,3,1,2,2,2,2,2,2,2,1,2,2,2,50915.06085,50693.303376,3,92,4,4,0.55,6,6,0,4,0,1,36,2,1,1,3 +68087,7,2,1,12,NA,4,4,2,12,154,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13742.402649,13769.572504,1,96,15,15,5,2,2,0,1,0,2,39,1,4,5,NA +68088,7,2,2,10,NA,5,7,1,10,123,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,5139.061504,5511.809249,2,103,15,15,5,3,3,0,1,0,2,37,2,5,1,5 +68089,7,2,1,46,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,18335.522037,18907.54446,1,96,15,15,5,4,4,0,2,0,1,46,1,5,1,5 +68090,7,2,1,13,NA,3,3,1,13,167,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,19381.771783,19434.749274,1,102,4,4,0.97,3,3,0,1,0,2,19,1,2,NA,NA +68091,7,2,2,74,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,2,2,2,NA,17057.278872,19050.04708,2,98,13,13,NA,1,1,0,0,1,2,74,1,1,2,NA +68092,7,2,2,11,NA,5,7,1,11,141,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6137.256046,6434.751859,1,103,15,15,3.7,5,5,0,2,1,1,55,1,5,1,5 +68093,7,2,1,47,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,18186.25816,18751.952628,2,101,9,9,3.74,2,2,0,0,0,2,40,2,4,1,2 +68094,7,2,1,3,NA,2,2,1,3,46,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,14716.463544,15182.304505,2,96,1,1,0.06,5,5,2,1,0,1,27,2,3,1,4 +68095,7,2,2,41,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,NA,NA,NA,NA,35126.205635,35295.519265,1,92,4,4,0.5,6,6,0,3,0,2,41,1,4,1,NA +68096,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,28280.669788,29879.976389,1,99,77,77,NA,2,2,0,0,2,2,80,1,4,1,4 +68097,7,2,2,8,NA,4,4,1,8,105,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9399.281543,9696.12347,2,96,3,3,0.54,4,4,2,1,0,2,25,1,4,2,NA +68098,7,2,2,9,NA,3,3,2,9,112,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12892.545573,15136.637829,1,99,6,6,1.12,4,4,0,2,0,1,39,1,3,1,3 +68099,7,2,2,35,NA,1,1,1,NA,NA,2,NA,2,2,2,NA,1,1,2,2,2,2,2,2,2,1,2,2,2,34898.504426,33956.869463,1,100,99,99,NA,7,7,2,3,0,2,35,2,1,1,NA +68100,7,2,2,65,NA,4,4,2,NA,NA,2,NA,2,2,4,NA,1,1,NA,1,2,1,1,2,2,1,2,1,NA,11313.630983,11818.772505,1,93,2,2,0.54,2,2,0,0,2,1,76,2,4,1,1 +68101,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,11740.600601,12693.223305,3,91,4,4,1.16,2,2,0,0,2,1,80,1,5,1,5 +68102,7,2,1,75,NA,2,2,2,NA,NA,2,NA,2,2,4,NA,1,1,NA,2,2,2,2,2,2,1,2,2,NA,12962.876803,16930.790311,2,90,3,3,0.46,5,5,0,2,2,1,75,2,1,1,2 +68103,7,2,2,0,3,4,4,2,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4099.350341,4514.494508,2,99,6,6,1.39,4,4,1,0,1,2,63,1,3,3,NA +68104,7,2,1,18,NA,5,7,1,19,228,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,14831.338089,14976.576871,1,98,3,3,0.43,4,4,0,1,0,2,39,1,2,5,NA +68105,7,2,2,58,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,16675.763807,16960.86402,2,95,12,12,NA,3,3,0,0,2,1,65,1,4,1,4 +68106,7,2,2,72,NA,3,3,1,NA,NA,2,NA,2,1,9,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,69886.968852,72277.093789,1,102,7,7,2.86,2,2,0,0,2,1,73,1,5,1,3 +68107,7,2,2,8,NA,3,3,1,8,105,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,64166.795496,75335.746424,1,101,5,5,0.89,5,5,1,2,0,1,31,1,2,1,1 +68108,7,2,1,2,NA,4,4,2,2,28,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6314.243514,6704.025386,2,97,5,5,0.76,5,5,1,1,0,2,47,1,4,5,NA +68109,7,2,1,45,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,18790.641284,20754.743742,2,100,8,8,2.7,3,3,1,0,0,2,41,1,4,1,3 +68110,7,2,1,60,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,121588.761604,120347.630506,1,91,10,10,4.49,2,2,0,0,2,1,60,1,5,1,4 +68111,7,2,2,12,NA,1,1,1,12,150,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17490.464019,17826.708822,1,102,15,15,4.47,4,4,0,2,0,2,30,1,4,1,4 +68112,7,2,1,52,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,17950.706927,18011.264999,2,94,15,15,4.44,5,5,0,1,1,2,74,1,5,2,NA +68113,7,2,2,0,6,1,1,1,NA,7,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,7565.515117,7406.345541,1,100,1,1,0.09,4,4,2,0,0,2,28,2,2,1,2 +68114,7,2,2,16,NA,3,3,2,17,204,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,71303.309206,77744.474592,2,94,15,15,5,3,3,0,1,1,1,63,1,5,1,3 +68115,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,44066.377955,48262.000685,2,97,5,5,2.11,1,1,0,0,1,2,80,1,4,2,NA +68116,7,2,1,8,NA,1,1,1,8,105,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13927.458372,14042.313177,2,98,3,3,0.54,3,3,0,2,0,2,35,1,3,5,NA +68117,7,2,1,28,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,23022.732862,27069.827485,2,102,14,14,3.25,5,5,1,1,0,2,32,1,4,1,3 +68118,7,2,2,18,NA,4,4,2,18,221,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,NA,NA,NA,NA,10154.02528,10568.655787,2,99,2,2,0.19,7,7,3,1,0,2,43,1,2,4,NA +68119,7,2,1,30,NA,4,4,1,NA,NA,2,NA,2,2,3,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,30195.362375,34424.306144,2,102,8,8,4.59,1,1,0,0,0,1,30,2,4,5,NA +68120,7,2,2,25,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,NA,NA,NA,NA,26388.213487,26374.704746,2,96,6,3,1.01,2,1,0,0,0,1,25,NA,NA,6,NA +68121,7,2,1,70,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,62513.129282,66168.769092,2,95,15,15,5,2,2,0,0,2,1,70,1,5,1,5 +68122,7,2,1,70,NA,3,3,2,NA,NA,1,9,1,1,NA,NA,4,1,NA,1,1,2,1,2,2,NA,NA,NA,NA,68074.313029,72055.159478,1,101,9,9,4.13,2,2,0,0,2,1,70,1,4,1,3 +68123,7,2,1,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,5,NA,1,1,2,1,1,2,1,2,2,NA,15437.181938,16772.913227,2,98,3,3,0.97,1,1,0,0,1,1,80,1,1,5,NA +68124,7,2,1,22,NA,5,6,1,NA,NA,2,NA,2,2,1,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,14385.653726,15564.966804,2,101,14,6,2.3,2,1,0,0,0,1,22,2,4,5,NA +68125,7,2,1,15,NA,4,4,2,15,190,NA,NA,2,1,2,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13969.457688,14694.403205,1,90,14,14,3.25,4,4,0,2,0,2,33,2,3,1,3 +68126,7,2,1,6,NA,3,3,2,6,74,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,22394.780012,23678.914206,1,91,4,4,0.81,4,4,1,1,0,1,32,1,4,6,NA +68127,7,2,2,50,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,3,1,NA,1,2,1,1,2,2,NA,NA,NA,NA,11446.604914,11862.967437,2,92,8,8,2.01,4,4,0,0,0,1,53,2,3,1,3 +68128,7,2,1,58,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,25786.235831,27127.570278,1,93,3,3,0.75,2,2,0,0,1,2,80,1,1,2,NA +68129,7,2,2,78,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,16494.288293,17728.004854,2,97,2,2,0.84,1,1,0,0,1,2,78,1,2,2,NA +68130,7,2,1,7,NA,3,3,1,7,92,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,57057.523607,61384.115788,1,98,9,9,2.15,5,5,0,3,0,2,32,1,3,1,4 +68131,7,2,2,39,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,34898.504426,34194.957212,1,100,9,9,2.02,6,6,0,3,1,2,39,1,4,1,5 +68132,7,2,1,5,NA,1,1,2,5,63,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,14505.510202,14964.673559,2,94,4,4,0.63,6,6,1,2,0,2,36,2,3,1,1 +68133,7,2,1,44,NA,2,2,1,NA,NA,2,NA,2,2,6,NA,4,1,NA,2,2,2,2,2,2,2,2,2,2,33029.272844,33302.556931,2,93,7,7,1.52,4,4,1,1,0,1,44,2,4,1,NA +68134,7,2,1,32,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,4,6,NA,2,2,2,2,2,2,1,2,2,2,41155.167164,40844.556107,1,102,13,13,NA,6,6,1,2,0,2,36,2,4,6,NA +68135,7,2,1,50,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,16590.074977,17115.36835,1,92,15,15,5,3,3,1,0,0,1,50,1,4,1,4 +68136,7,2,1,15,NA,2,2,1,15,188,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,19570.996814,20425.923806,2,100,4,4,0.81,4,4,0,2,0,2,37,1,2,1,2 +68137,7,2,2,68,NA,5,6,2,NA,NA,2,NA,2,2,4,NA,2,4,NA,1,2,1,1,2,1,1,2,1,NA,9991.888445,10532.363744,3,90,8,4,1.72,3,1,0,0,1,2,68,2,2,4,NA +68138,7,2,2,5,NA,3,3,2,5,69,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,78165.891242,86270.974005,1,101,14,14,4.21,4,4,1,1,0,2,37,1,5,1,5 +68139,7,2,2,52,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,19210.136544,19335.440888,1,96,15,15,5,2,2,0,0,0,1,48,1,2,1,3 +68140,7,2,1,30,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,19008.083201,18737.138245,2,97,1,1,0,2,2,0,0,1,2,63,1,4,5,NA +68141,7,2,2,4,NA,4,4,2,4,49,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10544.002566,11345.464378,1,91,6,6,0.99,5,5,3,0,0,2,33,2,3,1,4 +68142,7,2,1,36,NA,5,6,1,NA,NA,2,NA,2,2,4,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,15732.465299,16321.860662,2,92,14,6,2.75,2,1,0,0,0,1,48,NA,NA,5,NA +68143,7,2,2,80,NA,2,2,1,NA,NA,2,NA,2,1,8,NA,4,4,NA,2,2,2,1,2,2,2,2,1,NA,16623.349489,17874.484754,2,93,6,6,1.41,3,3,0,1,1,2,80,2,4,4,NA +68144,7,2,2,29,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,1,1,2,2,1,2,2,1,2,2,1,15083.375446,14341.447668,2,99,5,5,0.65,6,6,2,1,0,2,53,1,4,3,NA +68145,7,2,1,62,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,1,9221.19173,9581.850682,2,95,6,6,1.65,2,2,0,0,2,1,62,1,1,1,3 +68146,7,2,2,6,NA,5,7,2,7,84,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,22371.648216,22397.198208,1,92,3,3,0.46,5,5,2,1,0,1,30,1,3,1,2 +68147,7,2,1,75,NA,4,4,1,NA,NA,2,NA,2,1,8,NA,4,3,NA,1,2,2,1,2,2,1,2,2,NA,9662.124837,9885.036833,2,92,3,3,1.1,1,1,0,0,1,1,75,2,4,3,NA +68148,7,2,1,9,NA,1,1,1,9,111,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13927.458372,14258.502552,2,98,6,6,0.63,7,7,2,2,1,1,60,1,3,1,2 +68149,7,2,1,8,NA,1,1,1,8,99,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11399.23838,11468.323492,2,103,77,77,NA,5,5,1,2,0,2,30,1,2,1,2 +68150,7,2,1,13,NA,2,2,1,13,167,NA,NA,1,1,NA,7,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,19820.949231,20163.121943,2,91,8,8,1.85,5,5,0,2,1,1,39,2,3,1,4 +68151,7,2,1,29,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,16088.355002,15889.986896,2,100,3,3,0.92,1,1,0,0,0,1,29,1,2,5,NA +68152,7,2,1,56,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,16287.780872,16737.888813,2,100,14,14,4.86,3,3,0,0,0,2,52,1,5,1,3 +68153,7,2,1,14,NA,5,6,1,14,170,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6015.001712,6229.601178,1,102,5,5,0.92,5,5,1,2,0,2,44,2,1,1,2 +68154,7,2,1,56,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,15599.953109,15843.647059,1,99,15,15,5,2,2,0,0,0,1,56,1,4,1,4 +68155,7,2,2,40,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,25189.042335,24499.678113,1,100,10,10,2.59,5,5,0,1,0,2,40,1,5,1,NA +68156,7,2,2,61,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,13934.943848,14557.124186,2,96,12,10,5,2,1,0,0,1,1,53,1,4,3,NA +68157,7,2,2,24,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,14756.436992,15386.562828,2,95,14,8,4.59,2,1,0,0,0,2,24,1,4,6,NA +68158,7,2,1,7,NA,1,1,1,7,88,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,8828.580268,9491.612368,2,103,77,77,NA,7,7,0,4,0,1,38,2,1,6,NA +68159,7,2,1,66,NA,5,6,1,NA,NA,2,NA,2,2,6,NA,5,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,12579.986433,13271.133625,1,92,6,6,2.15,2,2,0,0,2,2,61,2,4,1,5 +68160,7,2,1,11,NA,3,3,2,11,143,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,24713.905595,26080.214484,1,98,6,6,0.97,7,7,1,2,0,1,49,1,2,1,2 +68161,7,2,1,10,NA,4,4,1,10,131,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8894.789377,9317.745565,2,97,NA,99,NA,7,6,2,1,1,2,56,1,3,5,NA +68162,7,2,1,0,9,3,3,2,NA,10,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,17196.879565,17846.963436,2,94,99,99,NA,6,6,2,0,0,2,26,1,4,1,NA +68163,7,2,2,0,9,3,3,2,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,20729.303307,20166.249394,1,90,14,14,4.98,3,3,1,0,0,2,33,2,5,1,5 +68164,7,2,2,14,NA,1,1,1,14,169,NA,NA,2,2,3,8,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,26325.414456,26852.811114,3,92,4,4,0.67,4,4,0,3,0,2,36,2,1,5,NA +68165,7,2,2,0,5,2,2,2,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6850.346072,7305.598313,1,90,3,3,0.43,4,4,2,0,0,1,31,1,3,6,NA +68166,7,2,1,6,NA,5,6,2,6,77,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6631.058951,7488.793181,2,92,12,12,NA,7,7,2,4,0,1,54,2,2,1,5 +68167,7,1,1,5,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,27873.065855,0,1,91,6,6,1.13,6,6,1,3,0,1,40,1,4,6,NA +68168,7,2,2,2,NA,5,7,2,2,32,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6247.52442,6810.692829,1,99,6,6,0.6,7,7,2,1,1,2,69,1,3,2,NA +68169,7,2,2,23,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,55695.737629,59946.103917,1,92,5,5,1.15,3,3,1,0,0,1,23,1,4,1,4 +68170,7,2,1,37,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,22856.432972,22931.992355,2,98,14,14,3.36,4,4,0,2,0,1,37,1,4,1,4 +68171,7,2,2,58,NA,1,1,1,NA,NA,2,NA,2,2,8,NA,1,4,NA,2,2,2,2,2,2,NA,NA,NA,NA,28349.668436,29490.478086,1,102,1,1,0.33,2,2,0,0,0,1,37,1,2,4,NA +68172,7,2,2,9,NA,3,3,2,9,111,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,50928.148447,51656.230004,3,91,14,14,3.4,4,4,0,2,0,1,40,1,4,1,4 +68173,7,2,1,38,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,22188.836739,22824.336433,1,95,4,4,0.65,6,6,2,2,0,2,36,1,4,6,NA +68174,7,2,1,5,NA,3,3,2,5,62,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,30883.231636,34843.624635,1,95,6,3,0.45,6,4,1,2,0,1,28,1,2,1,2 +68175,7,2,1,4,NA,2,2,1,4,51,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16169.123686,17324.04909,1,100,10,10,2.91,4,4,1,1,0,1,32,1,5,1,5 +68176,7,2,2,58,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,17164.211773,17267.434455,2,99,6,6,2.24,1,1,0,0,0,2,58,1,2,5,NA +68177,7,2,1,62,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,32476.100686,32780.682518,1,100,4,4,1.19,2,2,0,0,1,1,62,1,5,1,5 +68178,7,2,1,18,NA,5,6,2,18,223,2,NA,2,1,3,15,NA,NA,NA,1,2,2,1,2,2,NA,NA,NA,NA,9923.450213,10376.279545,2,100,5,5,0.89,4,4,0,1,0,2,40,2,3,1,3 +68179,7,2,1,17,NA,4,4,2,17,213,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,NA,9178.515376,10829.980579,2,99,2,2,0.19,6,6,0,1,0,1,59,1,2,5,NA +68180,7,2,1,31,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,19799.565045,19517.338151,1,90,14,14,2.96,5,5,1,2,0,1,31,1,5,1,4 +68181,7,2,1,74,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,15498.463997,16338.715638,1,98,5,5,1.39,2,2,0,0,2,2,71,1,3,1,3 +68182,7,2,1,47,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,138834.18124,153441.395439,1,100,15,15,4.56,4,4,0,2,0,2,42,1,4,1,3 +68183,7,2,2,28,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,NA,NA,NA,NA,23293.719218,24697.897932,1,92,7,7,1.83,3,3,1,1,0,2,28,1,3,5,NA +68184,7,2,1,7,NA,4,4,1,7,87,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12267.215138,12414.279886,2,102,5,5,0.76,5,5,1,3,0,2,30,1,4,4,NA +68185,7,2,1,29,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,26847.643051,27369.434392,1,98,4,4,0.67,5,5,1,2,0,1,29,1,4,1,3 +68186,7,2,2,17,NA,1,1,1,17,206,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,20370.629189,20955.218165,1,95,15,15,5,3,3,0,1,0,1,50,1,3,1,4 +68187,7,2,1,3,NA,4,4,2,3,41,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7431.820906,7890.591472,1,99,10,10,2.71,5,5,1,1,2,1,75,1,1,1,3 +68188,7,2,2,70,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,64463.340883,66173.435468,1,91,14,14,5,2,2,0,0,2,2,70,1,2,1,NA +68189,7,2,2,10,NA,4,4,2,10,129,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9326.540969,10100.402919,1,91,8,8,1.76,5,5,0,3,0,2,42,1,3,6,NA +68190,7,2,2,1,12,1,1,1,NA,12,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11438.839305,12628.78556,1,102,14,14,4.32,3,3,1,0,0,1,25,1,4,1,4 +68191,7,2,2,56,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,29167.119125,34820.124106,1,98,3,3,0.5,5,5,0,3,0,2,56,1,3,3,NA +68192,7,2,2,5,NA,1,1,1,5,62,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14852.990935,14903.708855,2,94,6,6,0.8,7,7,1,3,0,2,36,2,3,1,1 +68193,7,2,1,17,NA,3,3,2,17,208,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,NA,NA,NA,NA,71458.892941,70519.759062,2,94,10,10,3.51,3,3,0,2,0,2,39,2,4,3,NA +68194,7,2,1,15,NA,4,4,2,15,180,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10745.098568,10766.342508,1,96,12,12,NA,5,5,1,2,0,2,35,1,5,1,4 +68195,7,2,1,74,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,17306.956173,18319.031536,1,100,4,4,1.16,2,2,0,0,2,1,74,1,3,1,5 +68196,7,2,2,45,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,125040.051934,125530.45672,1,97,15,15,5,4,4,0,0,1,1,67,NA,NA,2,NA +68197,7,2,1,59,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,196252.38045,199712.076327,1,98,14,14,5,2,2,0,0,0,1,59,1,3,1,4 +68198,7,2,1,32,NA,4,4,2,NA,NA,2,NA,2,2,3,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,17371.064048,17243.514155,1,96,12,12,NA,5,5,2,0,1,2,63,2,5,3,NA +68199,7,2,2,30,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,5,4,2,1,2,2,1,2,2,1,2,2,1,29148.354549,29365.982413,2,92,14,14,4.03,4,4,1,1,1,2,30,1,5,4,NA +68200,7,2,1,51,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,31155.769617,31636.819209,1,92,14,9,3.97,3,2,0,0,2,1,51,1,4,5,NA +68201,7,2,2,12,NA,1,1,1,12,153,NA,NA,1,1,NA,5,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,19719.98657,20781.904006,2,102,6,6,1.03,5,5,1,1,0,1,37,1,2,1,2 +68202,7,2,1,9,NA,3,3,2,9,115,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,75923.373594,80651.425295,1,94,15,15,5,4,4,0,2,0,2,47,1,5,1,5 +68203,7,2,2,78,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,72551.269339,73326.076054,1,95,4,4,1.12,2,2,0,0,2,2,78,1,4,1,2 +68204,7,2,2,18,NA,3,3,2,18,226,2,NA,1,1,NA,12,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,24820.424867,25966.716212,1,91,3,3,0.62,3,3,0,1,0,2,55,1,4,4,NA +68205,7,2,1,51,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,15601.50288,15850.523572,2,99,2,2,0.2,7,7,1,2,1,1,63,1,1,2,NA +68206,7,2,2,35,NA,5,6,2,NA,NA,2,NA,2,2,2,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,17978.142628,18308.053591,1,91,10,10,3.22,4,4,1,1,0,1,38,2,5,1,5 +68207,7,2,1,36,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,22013.270774,22643.742168,1,101,3,3,0.66,2,2,0,0,1,2,65,1,2,3,NA +68208,7,2,1,16,NA,5,7,2,16,195,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,5388.361335,5758.757236,3,91,15,15,4.47,4,4,0,3,0,2,44,2,5,1,NA +68209,7,2,1,15,NA,2,2,1,15,189,NA,NA,1,1,NA,9,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,20798.348063,20598.526957,2,93,12,12,NA,3,1,1,1,0,2,43,1,5,3,NA +68210,7,2,1,27,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,9177.295801,9548.31812,2,92,15,8,4.59,3,1,0,0,0,2,25,1,5,5,NA +68211,7,2,1,2,NA,3,3,2,2,35,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,37959.146468,40828.920669,1,91,6,6,1.62,3,3,1,0,0,1,30,1,4,1,4 +68212,7,2,2,80,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,1,2,1,2,2,1,1,2,NA,16321.652472,17542.456462,2,97,4,4,1.02,2,2,0,0,2,2,80,1,1,2,NA +68213,7,2,2,41,NA,1,1,2,NA,NA,2,NA,2,2,4,NA,1,4,2,2,2,2,1,2,2,NA,NA,NA,NA,40880.818805,41857.641766,1,101,5,5,0.51,7,7,0,3,2,1,75,2,1,1,1 +68214,7,2,2,3,NA,5,6,2,3,38,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6858.963321,7464.098007,3,91,15,15,5,3,3,1,0,0,1,40,2,5,1,5 +68215,7,2,2,14,NA,4,4,1,14,178,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13895.342981,13964.270792,2,102,5,5,0.67,6,6,0,4,0,2,33,1,2,6,NA +68216,7,1,1,60,NA,5,6,NA,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,11992.891463,0,1,100,15,15,5,2,2,0,0,1,1,60,2,5,1,NA +68217,7,2,2,19,NA,4,4,2,19,234,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13841.239638,13875.328502,1,96,15,15,4.9,4,4,0,1,0,1,47,1,3,1,5 +68218,7,2,1,1,14,1,1,1,NA,14,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13968.423539,13738.28453,2,102,6,6,1.62,3,3,1,0,0,1,20,2,4,1,4 +68219,7,2,1,20,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,25270.027986,25977.972711,1,100,9,6,2.24,3,1,0,0,0,1,25,NA,NA,5,NA +68220,7,2,1,14,NA,4,4,2,14,169,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11834.781205,13035.394237,2,90,2,2,0.31,5,5,0,2,1,2,71,1,2,2,NA +68221,7,2,1,3,NA,4,4,1,3,46,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8385.172131,8641.288503,2,93,6,2,0.46,3,2,1,1,0,2,31,2,3,3,NA +68222,7,2,1,36,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,39040.678458,38746.026117,2,98,14,14,2.87,5,5,0,3,0,2,34,1,2,1,2 +68223,7,2,2,9,NA,3,3,1,9,109,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,25527.806244,26565.240294,2,101,3,3,0.3,7,7,1,2,0,2,50,1,2,4,NA +68224,7,2,2,11,NA,2,2,2,11,134,NA,NA,1,1,NA,4,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,15166.167659,15710.813593,2,94,1,1,0.01,7,7,1,3,0,1,41,2,1,1,1 +68225,7,2,1,2,NA,5,6,2,2,33,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6389.003009,6946.807658,3,91,6,6,1.15,5,5,1,0,0,1,55,2,5,1,5 +68226,7,2,2,38,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,20039.469886,21581.359058,1,97,15,15,5,4,4,1,1,0,1,44,2,5,1,5 +68227,7,2,2,56,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,25638.18991,26248.270338,2,101,2,2,0.38,3,3,0,2,0,2,56,1,3,2,NA +68228,7,2,1,11,NA,4,4,2,11,140,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6377.235034,7094.374704,2,90,6,6,0.84,6,6,1,3,1,2,43,1,2,5,NA +68229,7,2,2,36,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,97803.500399,102601.600974,1,101,14,14,5,3,3,0,1,0,2,36,1,5,1,5 +68230,7,2,2,22,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,59001.303336,68847.35366,2,101,2,2,0.46,1,1,0,0,0,2,22,1,4,5,NA +68231,7,2,1,13,NA,5,6,2,13,157,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10592.643259,11320.781443,2,91,77,77,NA,3,3,0,1,0,2,43,2,5,1,5 +68232,7,2,2,9,NA,1,1,1,10,121,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13064.573334,13403.6626,2,103,2,2,0.22,7,7,0,3,0,2,39,2,1,5,NA +68233,7,2,2,5,NA,3,3,2,5,64,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,51483.624552,53105.566664,1,91,15,15,5,4,4,1,1,0,1,38,1,5,1,5 +68234,7,2,1,68,NA,1,1,1,NA,NA,2,NA,2,1,8,NA,4,5,NA,1,2,2,1,2,2,2,2,2,2,12845.115724,13050.878075,1,100,9,9,2.02,6,6,0,3,1,2,39,1,4,1,5 +68235,7,2,1,79,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,19473.412374,20529.16646,1,95,4,4,1.22,2,2,0,0,1,1,79,1,1,1,3 +68236,7,2,2,41,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,26595.398371,26621.513872,1,94,4,4,1.26,2,2,0,0,1,2,41,1,4,5,NA +68237,7,2,1,63,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,120735.071461,122283.708051,1,94,8,8,2.41,3,3,0,0,3,1,63,1,4,1,5 +68238,7,2,2,4,NA,4,4,2,4,53,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10771.85499,11250.180007,2,97,5,5,1.08,3,3,1,1,0,2,27,1,3,5,NA +68239,7,2,2,7,NA,1,1,2,7,93,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,20753.369981,21285.255435,1,97,10,10,2.32,6,6,0,4,0,1,42,1,4,1,4 +68240,7,2,1,19,NA,1,1,2,19,239,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,25099.482648,25097.275151,1,97,4,4,0.65,4,4,0,1,0,2,45,2,2,3,NA +68241,7,2,1,9,NA,1,1,1,9,114,NA,NA,2,2,3,3,NA,NA,NA,2,1,1,1,2,2,1,2,2,1,19774.151841,21259.203461,3,92,7,7,1.41,5,5,1,2,0,1,20,2,1,1,1 +68242,7,2,1,7,NA,1,1,2,7,85,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,9390.522479,9862.720437,2,90,3,3,0.58,4,4,0,2,0,2,36,2,3,1,3 +68243,7,2,1,13,NA,1,1,1,13,158,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,22621.505951,23112.921348,1,92,14,14,5,2,2,0,1,0,2,41,1,5,3,NA +68244,7,2,1,49,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,1,28813.038041,29108.403608,1,94,2,2,0.42,3,3,0,0,0,2,52,1,4,1,1 +68245,7,2,2,24,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,2,1,2,2,1,2,2,1,2,2,1,18246.235208,18400.236064,2,99,1,1,0.07,4,4,1,1,0,2,24,1,2,5,NA +68246,7,2,1,9,NA,5,6,2,9,116,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,5377.477719,5731.340117,2,100,4,4,0.5,6,6,2,1,0,1,30,2,4,1,3 +68247,7,2,2,80,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,12833.793728,13278.897744,2,92,77,77,NA,2,2,0,0,2,2,80,1,3,1,4 +68248,7,2,1,15,NA,4,4,1,15,190,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12147.046136,12703.852077,2,100,8,8,1.8,5,5,0,3,0,2,43,1,3,1,3 +68249,7,2,1,60,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,117075.881463,118577.582598,1,94,9,9,3.97,2,2,0,0,1,1,60,1,4,1,4 +68250,7,2,2,50,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,207644.101324,214736.820497,1,97,15,15,5,2,2,0,0,0,1,50,1,3,6,NA +68251,7,2,2,34,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,1,2,1,2,2,1,2,2,1,2,2,1,39561.667842,39233.767064,2,98,14,14,2.87,5,5,0,3,0,2,34,1,2,1,2 +68252,7,2,2,45,NA,4,4,2,NA,NA,2,NA,2,1,7,NA,5,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,15206.604563,15895.992431,2,90,14,14,4.25,4,4,0,2,1,2,45,2,5,5,NA +68253,7,2,2,8,NA,3,3,2,8,102,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,63165.080986,62975.31549,1,98,15,15,5,3,3,0,1,0,2,43,1,5,1,5 +68254,7,2,2,55,NA,4,4,2,NA,NA,2,NA,2,2,4,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,15499.383981,15426.291906,2,99,5,5,1.26,3,3,1,0,0,2,50,2,3,5,NA +68255,7,2,1,60,NA,5,6,2,NA,NA,2,NA,2,1,3,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,6800.602543,7011.068263,1,99,6,6,1.62,3,3,0,0,1,1,60,2,5,1,3 +68256,7,2,2,46,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,22790.461787,22849.332243,2,98,10,10,3.78,3,3,0,0,0,2,46,1,4,1,4 +68257,7,2,1,12,NA,5,6,1,12,155,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10346.302718,11892.421636,2,91,6,6,1.26,5,5,0,2,0,2,47,2,1,1,1 +68258,7,2,1,3,NA,2,2,2,3,42,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,12403.412256,13289.361067,2,90,10,10,3.13,4,4,1,2,0,2,39,1,5,4,NA +68259,7,2,2,4,NA,5,7,2,4,59,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,27257.164734,28966.726071,1,95,10,6,1.34,5,4,1,2,0,1,32,1,3,6,NA +68260,7,2,1,61,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,10717.375231,11218.730451,2,95,3,3,1.29,1,1,0,0,1,1,61,1,2,3,NA +68261,7,2,2,80,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,14971.827573,15192.169136,2,97,15,15,5,3,3,0,0,3,2,80,1,3,2,NA +68262,7,2,2,64,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,10576.529742,11391.789088,2,99,2,2,0.72,1,1,0,0,1,2,64,1,3,5,NA +68263,7,2,2,63,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,118611.064701,118209.809508,1,91,10,10,3.78,3,3,0,0,2,1,62,1,5,1,5 +68264,7,2,1,9,NA,1,1,2,9,111,NA,NA,2,2,3,3,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,11917.887108,12700.965428,2,94,7,7,1.34,5,5,2,1,0,1,32,2,1,1,NA +68265,7,2,1,11,NA,1,1,1,11,143,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11881.117946,11953.12349,1,102,6,6,1.18,5,5,0,2,1,2,42,2,2,2,NA +68266,7,2,2,11,NA,4,4,2,12,144,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8757.841043,9104.895674,2,97,7,7,2.16,3,3,0,1,0,2,31,1,3,6,NA +68267,7,2,1,3,NA,5,6,1,3,38,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6389.003009,6899.95174,3,91,6,6,1.22,5,5,1,2,0,2,37,1,4,1,2 +68268,7,1,2,6,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10332.067017,0,1,100,3,3,0.73,3,3,1,1,0,2,32,1,3,5,NA +68269,7,2,2,2,NA,1,1,2,2,26,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13065.99844,14425.21291,1,95,8,8,2.24,4,4,2,0,0,2,29,1,3,1,4 +68270,7,2,2,48,NA,2,2,2,NA,NA,2,NA,2,2,6,NA,2,6,NA,2,2,2,2,2,2,2,2,2,2,31235.666551,31802.121006,2,94,9,9,4.21,3,2,0,0,0,2,48,2,2,6,NA +68271,7,2,1,43,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,127198.447143,126871.700524,1,101,8,8,4.25,1,1,0,0,0,1,43,1,4,5,NA +68272,7,2,1,1,18,5,7,1,NA,19,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,26337.322319,30860.353051,1,94,6,6,1.33,4,4,2,0,0,2,29,1,2,1,4 +68273,7,2,1,31,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,59510.728426,64021.429591,1,99,5,5,0.89,4,4,2,0,0,2,31,1,4,1,5 +68274,7,2,1,12,NA,5,6,1,12,147,NA,NA,2,2,3,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8530.740143,8910.137481,3,92,8,8,0.91,7,7,3,3,1,1,61,NA,NA,1,4 +68275,7,2,1,71,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,7608.031426,7606.53553,1,99,14,14,5,2,2,0,0,2,1,71,1,4,1,3 +68276,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,31909.283101,36294.223393,2,91,6,6,1.26,5,5,0,1,2,2,80,1,4,2,NA +68277,7,2,1,61,NA,1,1,1,NA,NA,2,NA,2,2,7,NA,4,1,NA,2,2,2,1,2,2,1,2,2,2,11568.876339,11794.347884,1,102,6,6,1.48,3,3,0,0,1,2,57,2,1,1,4 +68278,7,2,2,0,0,1,1,1,NA,0,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7896.364456,7653.697165,2,102,15,15,2.43,7,7,3,2,0,1,28,2,5,1,4 +68279,7,2,1,20,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,14424.961621,15273.975784,2,102,8,8,2.01,4,4,0,0,0,1,59,2,4,1,4 +68280,7,2,2,15,NA,3,3,2,15,184,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,91539.042546,96988.607103,1,101,9,9,2.6,4,4,0,2,0,2,38,1,4,1,4 +68281,7,2,1,27,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,17420.978407,17115.540769,2,97,12,6,2.75,3,1,0,0,0,1,21,NA,NA,77,NA +68282,7,2,2,54,NA,4,4,2,NA,NA,2,NA,2,1,6,NA,1,1,NA,1,2,2,1,2,2,1,2,2,1,13728.308948,13865.439464,2,90,6,6,1.12,4,4,0,1,1,1,63,2,1,1,1 +68283,7,2,2,54,NA,5,6,2,NA,NA,2,NA,2,1,3,NA,3,1,NA,1,2,2,1,2,2,1,2,2,3,13155.047649,13224.610785,3,90,15,15,3.7,5,5,0,0,0,1,56,2,3,1,3 +68284,7,2,1,8,NA,1,1,1,8,106,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13927.458372,14007.413517,2,98,15,15,4.97,5,5,0,3,0,1,39,1,5,1,5 +68285,7,2,2,49,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,110369.721342,114327.60352,1,94,9,9,3.97,2,2,0,0,0,1,49,1,3,1,3 +68286,7,2,2,16,NA,3,3,2,17,205,NA,NA,1,1,NA,11,NA,NA,NA,1,2,2,NA,NA,NA,1,2,2,1,111142.989658,114400.666347,1,95,NA,NA,NA,5,5,0,2,0,2,37,1,3,1,NA +68287,7,2,1,12,NA,1,1,1,12,145,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,22768.423624,22944.003607,1,92,5,5,1.24,3,3,0,1,0,2,29,2,3,6,NA +68288,7,2,1,28,NA,1,1,2,NA,NA,2,NA,2,2,4,NA,2,1,NA,2,2,2,2,2,2,2,2,2,2,34708.958385,37032.750996,2,97,13,13,NA,3,3,0,1,0,1,28,2,2,1,1 +68289,7,2,1,9,NA,4,4,1,9,115,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10199.928366,10774.065998,1,100,5,5,0.85,5,5,0,2,0,2,54,1,2,2,NA +68290,7,2,2,74,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,81416.374938,89993.518978,1,97,9,9,3.97,2,2,0,0,2,1,79,1,3,1,3 +68291,7,2,1,69,NA,2,2,1,NA,NA,2,NA,2,1,7,NA,3,1,NA,2,2,2,2,2,2,2,2,1,2,6687.985443,7006.085081,2,93,4,4,0.99,2,2,0,0,2,1,69,2,3,1,1 +68292,7,2,1,2,NA,1,1,1,2,26,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12005.116852,11690.420322,3,92,14,14,2.29,7,7,2,0,0,2,50,2,1,1,9 +68293,7,2,1,54,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,191792.099076,199776.618579,1,98,6,6,1.98,2,2,0,0,0,1,54,1,4,1,3 +68294,7,2,2,11,NA,3,3,2,12,144,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,55469.656717,57246.428971,1,101,14,14,3.3,4,4,0,2,0,2,42,1,4,1,3 +68295,7,1,2,20,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,2,6,3,1,2,2,1,2,2,NA,NA,NA,NA,60324.348827,0,1,101,13,13,NA,3,3,1,0,0,2,20,1,2,6,NA +68296,7,2,2,69,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,46357.185832,48577.343045,2,98,3,3,0.68,2,2,0,0,2,1,80,1,1,1,3 +68297,7,2,1,5,NA,5,6,1,5,63,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10273.602479,11522.969217,1,92,14,14,3.3,4,4,2,0,0,1,28,1,4,1,4 +68298,7,2,1,1,23,2,2,2,NA,24,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12567.081957,12360.030976,1,97,15,15,5,4,4,1,1,0,1,42,1,5,1,5 +68299,7,2,2,12,NA,4,4,2,12,148,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,19113.842115,19208.656277,1,97,1,1,0.09,4,4,0,1,0,2,44,2,2,1,3 +68300,7,2,1,16,NA,4,4,2,16,193,NA,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11023.237662,11433.168046,1,99,14,14,4.05,3,3,0,1,0,2,52,1,4,4,NA +68301,7,2,1,59,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,166897.201244,169896.236244,2,91,15,2,0.63,7,1,0,0,1,1,49,NA,NA,5,NA +68302,7,2,1,17,NA,4,4,2,17,209,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11023.237662,11433.168046,1,99,15,15,5,4,4,0,2,0,2,46,1,5,1,5 +68303,7,2,2,16,NA,1,1,2,16,198,NA,NA,2,2,1,10,NA,NA,NA,1,2,2,1,2,2,2,2,2,2,16896.101801,17220.920308,1,93,15,1,0,3,1,0,1,0,2,46,2,5,5,NA +68304,7,2,1,19,NA,1,1,1,19,232,2,NA,2,2,3,11,NA,NA,NA,2,2,2,2,2,2,1,2,2,2,25268.119938,26371.916437,1,100,99,99,NA,6,6,0,1,0,2,22,2,3,1,3 +68305,7,2,2,17,NA,5,6,1,17,205,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,1,1,2,2,1,10081.858636,10347.605805,2,102,15,15,3.82,5,5,0,1,2,1,60,2,2,1,1 +68306,7,2,1,17,NA,3,3,2,17,212,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,88448.252445,87285.839384,1,95,8,1,0.09,4,1,0,1,0,2,57,1,5,5,NA +68307,7,2,1,2,NA,4,4,2,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6347.215153,6424.634366,2,95,7,7,1.83,3,3,1,0,0,1,33,1,3,6,NA +68308,7,2,1,0,2,3,3,1,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8361.170561,8618.715512,1,94,4,4,0.56,5,5,1,2,0,1,34,1,2,3,NA +68309,7,2,1,57,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,16499.662173,16747.308945,3,91,7,7,1.33,6,6,0,0,2,2,51,2,5,1,5 +68310,7,2,2,47,NA,5,6,2,NA,NA,2,NA,2,1,4,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,20303.639991,21936.687597,1,97,10,10,3.67,3,3,0,1,0,1,47,1,5,1,5 +68311,7,2,2,33,NA,5,6,2,NA,NA,2,NA,2,1,4,NA,3,1,1,1,2,2,1,2,2,1,2,2,1,18018.210636,18055.00232,2,91,15,15,4.63,7,7,1,2,0,1,36,2,4,1,3 +68312,7,2,2,35,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,62471.259637,62663.338056,1,92,8,8,1.45,6,6,1,3,0,1,36,1,3,1,4 +68313,7,2,1,5,NA,3,3,2,5,70,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,67064.292398,74209.90502,2,91,15,15,5,5,5,2,1,0,2,40,1,5,1,5 +68314,7,2,1,31,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,16995.30979,18681.886374,2,103,6,6,1.3,4,4,1,1,0,2,26,1,4,1,3 +68315,7,2,2,10,NA,1,1,1,10,121,NA,NA,1,1,NA,5,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,15510.382876,18634.445505,1,100,6,6,1.11,5,5,0,2,1,1,38,2,2,1,1 +68316,7,2,2,70,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,13204.205822,14198.003586,1,98,9,9,2.49,4,4,0,1,2,2,70,1,4,2,NA +68317,7,2,2,19,NA,3,3,1,19,237,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,36241.268921,38398.808798,2,101,2,1,0.28,2,1,0,0,0,2,21,1,4,5,NA +68318,7,2,2,80,NA,5,6,1,NA,NA,2,NA,2,2,6,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,18693.365067,19341.691824,1,92,12,12,NA,7,7,1,2,1,2,45,2,3,1,3 +68319,7,2,2,43,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,90708.718111,91145.947869,2,100,15,15,4.5,6,6,0,4,0,1,45,1,5,1,5 +68320,7,2,1,0,1,5,7,2,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6420.539566,6377.399312,2,99,15,15,5,3,3,1,0,0,1,35,2,5,1,5 +68321,7,2,1,80,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,28658.58153,30983.915333,2,94,8,8,3.4,2,2,0,0,2,1,80,1,3,1,5 +68322,7,2,1,32,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,30626.581617,32055.135325,2,90,6,6,1.62,3,3,1,0,0,2,28,1,5,1,4 +68323,7,2,2,16,NA,5,7,1,16,202,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,23414.779924,23738.339087,1,102,5,5,1.27,3,3,0,2,0,2,38,1,2,3,NA +68324,7,2,2,27,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,90179.087212,91826.282843,2,95,14,14,5,2,2,0,0,0,1,39,1,4,1,5 +68325,7,2,1,2,NA,4,4,2,2,27,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5662.231921,6243.536586,1,99,2,2,0.31,4,4,1,0,1,2,67,1,3,3,NA +68326,7,2,1,12,NA,4,4,2,12,152,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,NA,NA,NA,1,2,2,1,10366.393886,10567.129261,1,90,9,9,1.65,7,7,0,4,0,1,36,1,4,1,4 +68327,7,2,1,80,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,26019.443397,28034.871168,2,100,6,6,2.01,2,2,0,0,2,1,80,1,5,1,5 +68328,7,2,1,5,NA,3,3,2,5,68,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,56162.95725,63365.162813,2,95,15,15,4.63,5,5,1,2,0,2,36,1,5,1,3 +68329,7,2,2,15,NA,1,1,1,15,188,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18515.058419,19512.090709,2,96,7,7,1.79,4,4,0,2,0,1,43,2,3,1,2 +68330,7,2,2,69,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,133492.667054,133041.068157,1,95,6,6,1.94,2,2,0,0,2,2,69,1,2,1,4 +68331,7,2,1,66,NA,1,1,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,14488.953694,14771.336069,3,92,14,14,5,2,2,0,0,2,1,66,1,4,1,4 +68332,7,2,2,17,NA,3,3,2,17,205,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,123622.182994,127245.633335,2,94,7,7,2.72,2,2,0,1,0,2,43,1,3,3,NA +68333,7,2,1,2,NA,3,3,2,2,33,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,43818.485,49773.383799,2,91,10,10,2.5,5,5,1,0,0,1,57,1,9,1,3 +68334,7,2,2,38,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,26682.998353,27885.908424,2,99,3,3,0.56,4,4,1,0,0,2,38,1,3,5,NA +68335,7,1,2,14,NA,5,6,NA,NA,NA,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7969.467397,0,2,103,15,15,4.34,4,4,0,2,0,1,48,2,5,1,5 +68336,7,2,2,1,22,1,1,1,NA,22,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,8832.868731,8863.029978,1,102,6,6,0.8,7,7,3,3,0,2,34,2,3,1,1 +68337,7,2,1,36,NA,1,1,1,NA,NA,2,NA,2,2,5,NA,4,1,NA,2,2,2,2,2,2,1,2,2,2,41241.224595,42341.927552,2,102,10,10,3.04,4,4,2,0,0,2,31,2,2,1,NA +68338,7,2,1,51,NA,2,2,1,NA,NA,2,NA,2,2,2,NA,3,1,NA,2,2,2,2,2,2,2,2,1,2,25108.558777,27044.812277,2,93,4,4,0.82,4,4,0,0,0,1,51,2,3,1,3 +68339,7,2,1,46,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,18790.641284,20754.743742,2,100,4,4,0.85,4,4,0,2,0,2,39,1,3,6,NA +68340,7,2,1,10,NA,3,3,2,10,125,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,21087.869274,22876.159598,1,101,4,4,0.78,4,4,1,2,0,2,32,1,3,3,NA +68341,7,2,2,64,NA,2,2,1,NA,NA,2,NA,2,1,6,NA,2,1,NA,1,2,2,1,2,2,2,2,2,1,10235.0654,10993.258671,2,93,10,10,3.04,4,4,0,0,2,1,72,2,3,1,2 +68342,7,2,1,59,NA,5,6,2,NA,NA,2,NA,2,2,7,NA,1,6,NA,1,2,1,1,2,1,NA,NA,NA,NA,16499.662173,16440.055989,3,91,6,4,1.38,3,1,0,0,0,1,59,2,1,6,NA +68343,7,2,1,52,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,17206.320427,17285.613667,1,96,2,2,0.4,3,3,0,0,0,2,56,1,3,3,NA +68344,7,2,1,40,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,152858.509804,152465.847768,1,95,14,7,3.67,2,1,0,0,0,1,47,1,4,3,NA +68345,7,2,2,18,NA,4,4,1,18,223,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,18163.985724,18749.311901,2,101,2,1,0.09,4,1,0,0,0,2,19,1,4,NA,NA +68346,7,2,1,0,4,4,4,2,NA,4,NA,NA,2,2,99,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6327.979262,6425.104835,1,90,13,13,NA,3,3,2,0,0,2,21,2,4,5,NA +68347,7,2,2,0,2,3,3,1,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,20899.681083,21326.972731,1,92,14,14,3.16,6,6,1,1,0,1,49,1,1,1,3 +68348,7,2,1,32,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,51543.062078,54569.929737,3,92,14,14,3.25,4,4,2,0,0,2,33,1,5,1,5 +68349,7,1,2,12,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,24869.937631,0,2,93,6,6,1.48,4,4,0,1,0,1,53,2,2,1,3 +68350,7,2,2,12,NA,3,3,1,12,151,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,93740.540203,99321.165816,1,100,15,15,4.56,4,4,0,2,0,2,42,1,4,1,3 +68351,7,2,1,27,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,90303.174138,92885.29608,2,92,15,15,5,4,1,0,0,0,1,27,NA,NA,5,NA +68352,7,2,2,75,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,30548.472436,32702.747345,1,95,1,1,0.21,4,4,1,0,1,2,75,1,1,2,NA +68353,7,2,1,36,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,94698.084211,100770.654731,1,101,14,14,4.21,4,4,1,1,0,2,37,1,5,1,5 +68354,7,2,1,45,NA,5,6,2,NA,NA,2,NA,2,2,2,NA,4,1,NA,1,2,1,1,2,2,1,2,1,NA,14879.667962,14825.914121,3,91,4,4,0.69,5,5,0,2,0,1,45,2,4,1,1 +68355,7,2,2,19,NA,4,4,2,19,236,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,18163.985724,18749.311901,2,101,1,1,0.05,1,1,0,0,0,2,19,1,4,NA,NA +68356,7,2,2,73,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,NA,15616.794261,15846.627851,2,97,7,7,3.49,1,1,0,0,1,2,73,1,4,3,NA +68357,7,2,1,1,12,3,3,1,NA,12,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,26337.322319,28328.46741,1,94,3,3,0.93,2,2,1,0,0,2,25,1,5,3,NA +68358,7,2,2,0,5,1,1,2,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,6787.112205,6644.319314,2,94,3,3,0.54,3,3,1,0,0,2,21,1,4,1,3 +68359,7,1,2,11,NA,2,2,NA,NA,NA,NA,NA,2,1,4,4,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15821.530831,0,2,91,6,6,0.93,5,5,1,2,0,2,50,2,1,5,NA +68360,7,2,1,13,NA,5,6,1,13,166,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12013.02156,13498.577364,3,92,12,12,NA,5,5,0,2,0,1,47,1,3,1,3 +68361,7,2,1,8,NA,1,1,1,8,101,NA,NA,1,1,NA,2,NA,NA,NA,2,1,2,1,2,2,1,2,2,2,13898.598114,14118.535925,2,102,5,5,0.59,7,7,1,3,0,1,37,2,1,6,NA +68362,7,2,1,2,NA,4,4,1,2,30,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8009.966208,8254.622305,2,96,13,13,NA,4,4,1,1,0,2,40,1,3,77,NA +68363,7,2,1,1,21,5,7,1,NA,23,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6929.441295,7483.610581,2,102,15,15,5,5,5,1,0,2,1,30,1,4,1,5 +68364,7,2,1,63,NA,4,4,2,NA,NA,2,NA,2,2,7,NA,1,1,NA,1,2,2,1,2,2,1,2,2,1,7514.993062,7713.03043,2,90,6,6,1.12,4,4,0,1,1,1,63,2,1,1,1 +68365,7,2,1,64,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,22184.040999,22468.589781,2,94,6,6,2.66,1,1,0,0,1,1,64,1,4,3,NA +68366,7,2,1,3,NA,4,4,1,3,45,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11920.911192,13144.753907,2,96,3,3,0.59,3,3,1,0,0,2,25,1,4,1,NA +68367,7,2,1,78,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,10160.645851,10681.304475,1,96,8,8,3.14,2,2,0,0,2,2,64,1,3,1,2 +68368,7,2,1,17,NA,5,6,2,17,207,2,NA,2,1,3,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,9136.388281,9764.423514,3,91,9,9,4.08,2,2,0,1,0,2,54,2,5,1,NA +68369,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,39565.288792,43332.356399,1,99,77,77,NA,2,2,0,0,2,2,80,1,4,1,4 +68370,7,2,2,10,NA,3,3,2,10,129,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,24070.467912,23750.822126,1,95,7,7,1.17,6,6,1,3,0,2,44,1,4,1,NA +68371,7,2,1,10,NA,3,3,1,10,128,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18216.94614,18737.854061,1,94,3,3,0.39,6,6,2,2,0,2,25,1,4,1,2 +68372,7,2,2,2,NA,5,6,2,2,28,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4962.240532,5199.576603,2,94,77,77,NA,6,6,2,0,0,2,18,1,3,NA,NA +68373,7,2,2,8,NA,4,4,2,8,97,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11467.793741,13004.375485,2,91,6,6,0.78,7,7,1,4,0,2,38,2,2,77,NA +68374,7,2,1,45,NA,5,6,1,NA,NA,2,NA,2,1,8,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,20696.713928,21333.342141,2,102,15,15,5,3,3,1,0,0,2,34,1,5,1,5 +68375,7,2,2,52,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,29167.119125,29596.13582,1,101,1,1,0.1,4,4,1,1,0,2,52,1,4,3,NA +68376,7,2,2,61,NA,1,1,1,NA,NA,2,NA,2,1,7,NA,1,1,NA,2,2,2,1,2,2,2,2,2,2,13057.178942,13648.591881,1,102,77,77,NA,2,2,0,0,2,1,68,2,4,1,1 +68377,7,2,1,74,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,4,4,NA,1,2,2,1,2,2,1,2,2,NA,8386.962371,8877.414759,1,93,3,3,0.93,1,1,0,0,1,1,74,1,4,4,NA +68378,7,2,1,0,3,3,3,1,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9419.940635,10084.452218,2,98,3,3,0.54,3,3,1,0,0,1,23,1,3,1,2 +68379,7,2,1,1,16,4,4,2,NA,17,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6580.937346,6661.20735,2,97,4,4,0.97,3,3,1,0,0,1,38,1,3,6,NA +68380,7,2,2,43,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,17623.300255,17855.084956,1,100,15,15,5,4,4,0,1,0,1,44,2,5,1,5 +68381,7,2,1,9,NA,3,3,1,9,118,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,21087.869274,22876.159598,1,101,4,4,0.99,2,2,0,1,0,2,35,1,3,5,NA +68382,7,2,1,0,11,3,3,2,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9081.731172,9425.042696,1,95,8,8,1.45,6,6,1,1,2,1,69,1,1,1,3 +68383,7,2,2,0,9,3,3,2,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,21905.560663,22505.214105,1,95,5,5,0.76,5,5,2,1,0,2,27,1,4,6,NA +68384,7,2,2,23,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,61710.107686,62261.838119,1,98,2,2,0.63,1,1,0,0,0,2,23,1,4,5,NA +68385,7,2,2,22,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,22912.222762,29561.458771,2,96,5,5,1.5,2,2,1,0,0,2,22,1,3,5,NA +68386,7,1,1,30,NA,1,1,NA,NA,NA,2,NA,2,2,77,NA,3,5,NA,2,2,2,2,2,2,NA,NA,NA,NA,53303.690379,0,1,100,4,4,0.78,4,4,0,0,1,1,33,2,1,1,1 +68387,7,2,2,70,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,1,1,2,1,1,2,2,NA,12296.397953,12433.512478,1,99,9,9,4.08,2,2,0,0,2,1,73,2,5,1,5 +68388,7,2,2,2,NA,3,3,1,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,47602.397711,49102.065502,1,102,6,6,1.23,4,4,2,0,0,2,25,1,5,1,5 +68389,7,2,2,15,NA,4,4,1,15,191,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15483.914568,16116.18632,1,100,6,6,2.12,2,2,0,1,0,2,44,1,3,3,NA +68390,7,1,2,25,NA,2,2,NA,NA,NA,2,NA,1,1,NA,NA,2,1,3,1,2,2,1,2,2,NA,NA,NA,NA,39550.779175,0,2,96,3,3,0.54,4,4,1,1,0,1,29,1,2,1,2 +68391,7,1,2,80,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,1,5,NA,1,1,2,1,2,2,NA,NA,NA,NA,60163.952904,0,1,97,12,99,NA,2,1,0,0,2,2,65,1,2,2,NA +68392,7,1,2,61,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,14994.337564,0,1,100,10,10,4.63,2,2,0,0,1,1,58,1,5,1,4 +68393,7,2,2,20,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,23845.8146,22808.13483,1,98,2,1,0.11,4,1,0,0,0,2,19,1,4,NA,NA +68394,7,2,2,58,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,139343.551779,138175.157138,2,98,14,14,5,1,1,0,0,0,2,58,1,5,5,NA +68395,7,2,2,0,10,1,1,2,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9179.885292,9149.640857,1,101,5,5,1.23,3,3,2,0,0,2,24,1,2,5,NA +68396,7,2,2,0,6,1,1,1,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,6700.950086,6495.019697,2,96,3,3,0.34,7,7,3,1,0,2,49,2,1,4,NA +68397,7,1,2,55,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,141316.739364,0,2,94,8,8,1.33,7,7,1,2,1,1,34,NA,NA,6,NA +68398,7,2,2,6,NA,4,4,1,6,74,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11116.391625,11531.852198,1,92,7,7,1.83,3,3,1,1,0,2,28,1,3,5,NA +68399,7,2,2,5,NA,5,6,1,5,64,NA,NA,2,2,1,NA,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,6858.963321,7464.098007,3,91,14,14,3.58,4,4,1,1,0,1,39,2,5,1,5 +68400,7,2,1,8,NA,4,4,2,9,108,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7687.032802,8052.55895,2,99,9,9,2.43,4,4,0,2,0,2,49,1,3,3,NA +68401,7,2,1,43,NA,1,1,2,NA,NA,2,NA,2,2,4,NA,1,5,NA,2,2,2,2,2,2,1,2,2,2,31347.36219,35248.66815,2,90,2,2,0.46,1,1,0,0,0,1,43,2,1,5,NA +68402,7,2,2,1,19,5,7,2,NA,19,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,3842.794137,4026.588867,1,93,15,15,5,5,5,1,0,1,1,61,2,4,1,4 +68403,7,2,2,36,NA,1,1,2,NA,NA,2,NA,2,2,4,NA,2,1,2,2,2,2,2,2,2,NA,NA,NA,NA,35425.867861,35132.246023,1,97,8,8,1.45,6,6,2,2,0,2,36,2,2,1,1 +68404,7,2,2,65,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,11879.290971,12409.688606,2,96,3,3,1.1,1,1,0,0,1,2,65,1,4,5,NA +68405,7,2,1,1,20,3,3,1,NA,21,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,22170.765881,25013.89276,1,94,3,3,0.39,6,6,1,0,2,1,80,1,4,1,3 +68406,7,2,2,17,NA,5,6,2,17,215,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12054.065975,12306.62888,1,98,6,6,1.65,2,2,0,1,0,2,52,2,5,1,NA +68407,7,2,2,80,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,2,1,2,2,1,2,NA,NA,NA,NA,16878.750567,18850.661665,2,98,3,3,0.98,2,2,0,0,1,2,80,1,1,2,NA +68408,7,2,2,16,NA,3,3,1,16,194,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,91539.042546,96988.607103,1,101,7,7,2.31,2,2,0,1,0,2,43,1,4,3,NA +68409,7,2,1,3,NA,1,1,1,3,46,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,20874.345556,20902.551716,3,92,5,5,1.05,3,3,1,1,0,2,38,2,3,5,NA +68410,7,2,1,16,NA,4,4,2,16,193,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13863.378072,13964.345562,1,96,15,15,5,4,4,0,1,0,1,56,1,4,1,5 +68411,7,2,2,30,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,6,2,1,2,2,1,2,2,1,2,2,1,89807.047643,92234.66957,3,91,9,7,3.67,2,1,0,0,0,1,41,NA,NA,3,NA +68412,7,2,1,32,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,4,NA,1,2,2,1,2,2,1,2,2,1,22013.270774,24073.71767,1,101,5,5,1.05,3,3,0,0,1,2,55,1,4,1,NA +68413,7,2,2,3,NA,1,1,1,3,37,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15326.318384,16920.666785,1,94,6,6,1.3,4,4,2,0,0,1,24,2,1,1,4 +68414,7,1,1,77,NA,3,3,NA,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,19418.523783,0,1,101,4,4,0.99,2,2,0,0,2,1,77,1,3,1,3 +68415,7,2,2,43,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,4,2,1,2,2,1,2,2,1,2,2,1,49900.868115,50161.096898,3,92,7,7,2.78,2,2,0,0,0,1,24,1,3,5,NA +68416,7,2,1,63,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,3,1,NA,1,2,2,1,2,2,1,2,2,3,8623.181934,10090.425838,2,103,3,3,0.63,3,3,0,0,1,1,63,2,3,1,NA +68417,7,2,1,19,NA,1,1,2,19,230,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,2,2,2,1,2,2,1,14081.782012,14391.713696,2,90,6,6,1.15,5,5,0,2,0,2,47,2,1,1,5 +68418,7,2,2,70,NA,2,2,1,NA,NA,2,NA,2,2,2,NA,2,1,NA,2,2,2,2,2,2,2,2,2,NA,20621.25319,22173.285594,2,93,9,9,3.14,3,3,0,0,2,1,43,NA,NA,5,NA +68419,7,2,2,70,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,81416.374938,85457.008484,1,97,5,5,1.79,1,1,0,0,1,2,70,1,4,2,NA +68420,7,2,1,22,NA,4,4,1,NA,NA,2,NA,2,1,4,NA,4,5,NA,1,2,2,NA,NA,NA,NA,NA,NA,NA,18831.340773,18391.458344,2,93,9,9,2.07,5,5,0,1,0,1,55,NA,NA,5,NA +68421,7,1,2,15,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,10,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12327.773112,0,2,95,12,12,NA,2,2,0,1,0,1,47,1,4,2,NA +68422,7,2,2,60,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,53370.063988,54427.336747,3,92,13,13,NA,2,2,0,0,2,2,60,1,4,1,NA +68423,7,2,2,42,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,154825.466557,157902.106304,1,91,15,15,5,2,2,0,0,0,1,44,NA,NA,1,5 +68424,7,2,1,72,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,1,1,NA,1,1,1,1,2,2,1,2,1,NA,16828.011748,23148.456034,1,97,14,14,2.29,7,7,1,2,2,1,40,2,1,1,1 +68425,7,2,1,56,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,16287.780872,16385.890285,2,100,12,12,NA,2,2,0,0,1,1,56,1,5,1,4 +68426,7,2,2,19,NA,3,3,1,19,236,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,35205.804094,37301.699975,2,101,99,2,0.55,3,1,0,0,0,2,19,1,4,NA,NA +68427,7,2,2,21,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,NA,NA,NA,NA,30275.274308,30259.77569,2,101,3,1,0.18,2,1,0,0,0,2,25,1,4,5,NA +68428,7,2,2,44,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,4,2,1,2,2,1,2,2,1,2,2,1,24842.055317,24866.449113,2,95,3,3,0.63,3,3,0,0,0,2,44,1,2,4,NA +68429,7,2,1,27,NA,3,3,2,NA,NA,2,NA,2,1,4,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,118671.226879,152848.538678,2,91,15,9,5,2,1,0,0,0,2,26,1,5,5,NA +68430,7,2,2,2,NA,5,6,1,2,28,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6365.363193,6669.808387,1,92,14,14,2.42,6,6,1,3,0,1,30,1,4,6,NA +68431,7,2,1,3,NA,4,4,2,3,38,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7076.684446,7163.001252,2,99,2,2,0.22,4,4,1,1,0,1,18,1,2,NA,NA +68432,7,2,1,80,NA,2,2,2,NA,NA,1,2,2,1,9,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,11755.776731,12827.229805,3,90,3,3,0.78,3,3,0,1,2,1,80,2,3,1,2 +68433,7,2,2,6,NA,1,1,1,6,77,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13085.05107,13640.91346,2,92,14,14,4.03,4,4,1,1,1,2,30,1,5,4,NA +68434,7,2,2,67,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,11576.638399,12468.988052,1,101,3,3,1.12,1,1,0,0,1,2,67,1,2,5,NA +68435,7,2,2,8,NA,3,3,1,8,101,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,25826.784831,26196.011011,2,91,2,2,0.44,3,3,0,1,0,1,46,2,3,1,4 +68436,7,2,2,51,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,196995.351093,203724.329642,1,91,15,12,NA,2,1,0,0,0,1,51,1,3,1,NA +68437,7,2,1,4,NA,4,4,2,4,58,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7354.77583,7808.790358,2,90,8,8,1.67,6,6,1,1,0,1,52,1,3,1,5 +68438,7,2,1,43,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,25964.952645,26783.974907,2,96,5,5,1.36,2,2,0,0,0,2,51,1,4,1,3 +68439,7,2,1,14,NA,5,7,2,14,174,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8676.361974,9272.775003,1,90,77,77,NA,4,4,0,2,0,2,51,1,5,1,5 +68440,7,2,1,46,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,116464.874823,116165.700541,2,94,99,99,NA,2,2,0,0,0,2,37,1,2,1,4 +68441,7,2,2,51,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,22631.175755,22215.258702,2,96,5,5,1.36,2,2,0,0,0,2,51,1,4,1,3 +68442,7,2,2,42,NA,1,1,1,NA,NA,2,NA,2,1,7,NA,1,5,2,2,2,2,2,2,2,1,2,2,2,30678.628571,30838.615009,3,91,5,5,1.03,4,4,0,2,0,2,42,2,1,5,NA +68443,7,2,1,73,NA,4,4,2,NA,NA,2,NA,2,2,5,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,6725.306794,6857.040344,2,99,77,77,NA,1,1,0,0,1,1,73,2,5,1,NA +68444,7,2,1,23,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,19537.368697,21142.881814,2,96,3,3,0.47,4,4,1,0,1,2,61,1,4,3,NA +68445,7,2,1,70,NA,2,2,1,NA,NA,2,NA,2,2,3,NA,4,1,NA,2,2,2,2,2,2,1,2,1,NA,9710.399795,9879.67408,2,93,12,12,NA,5,5,1,0,2,1,70,2,4,1,5 +68446,7,2,2,68,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,11838.431472,12295.352662,2,92,7,7,2.72,2,2,0,0,2,2,68,1,5,1,NA +68447,7,2,2,68,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,49568.196121,49400.509437,1,95,2,2,0.78,1,1,0,0,1,2,68,1,4,3,NA +68448,7,2,2,28,NA,5,7,1,NA,NA,2,NA,2,1,3,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,18100.072824,19323.729203,1,92,7,7,3.22,1,1,0,0,0,2,28,2,5,5,NA +68449,7,2,1,12,NA,2,2,2,12,145,NA,NA,2,1,4,6,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,15594.049321,16140.624477,2,99,77,77,NA,4,4,1,1,1,2,38,2,4,1,4 +68450,7,2,2,47,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,21481.050033,21698.613985,2,91,8,7,3.31,2,1,0,0,0,1,55,1,2,6,NA +68451,7,2,1,24,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,16995.648055,16715.026676,2,100,7,7,1.38,5,5,1,0,0,2,45,1,2,3,NA +68452,7,2,2,69,NA,2,2,2,NA,NA,2,NA,2,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,9716.805546,12994.252166,2,90,4,4,1.47,1,1,0,0,1,2,69,2,2,3,NA +68453,7,2,2,79,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,56393.181686,58123.268911,2,93,7,7,2.31,2,2,0,0,2,2,79,1,3,1,5 +68454,7,1,1,28,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,103001.073873,0,2,97,7,7,3.21,1,1,0,0,0,1,28,1,4,5,NA +68455,7,2,1,27,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,39031.957066,39638.562591,1,95,3,2,0.74,2,1,0,0,0,1,27,1,3,5,NA +68456,7,2,1,3,NA,2,2,1,3,37,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,11179.43727,11311.602194,2,93,3,3,0.37,5,5,3,0,0,1,28,2,1,6,NA +68457,7,2,1,0,8,3,3,1,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,28319.415322,27829.834184,1,92,9,9,2.6,4,4,2,0,0,2,32,1,3,1,5 +68458,7,2,1,44,NA,1,1,1,NA,NA,2,NA,2,1,6,NA,1,1,NA,2,2,2,2,2,2,NA,NA,NA,NA,29797.944087,29360.705192,1,103,5,5,0.74,5,5,1,1,0,2,40,99,3,1,1 +68459,7,2,2,16,NA,4,4,2,16,201,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,10460.187371,12283.198438,1,99,7,7,1.53,5,5,0,3,0,1,39,1,3,1,3 +68460,7,2,1,4,NA,2,2,1,4,55,NA,NA,2,1,2,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,11179.43727,11533.315753,2,93,14,14,2.91,6,6,2,0,1,2,74,NA,NA,2,NA +68461,7,2,1,6,NA,3,3,2,7,84,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,63513.013195,68899.034203,2,101,7,7,1.57,4,4,0,2,0,2,28,1,3,6,NA +68462,7,2,1,49,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,29483.108693,29407.372658,1,94,4,4,0.79,3,3,0,1,0,1,49,1,2,3,NA +68463,7,2,2,0,7,3,3,2,NA,7,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,19676.563141,20852.949038,2,99,15,15,5,3,3,1,0,0,1,43,1,5,1,5 +68464,7,2,2,61,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,42101.975168,41959.54633,1,101,5,5,1.24,3,3,0,0,1,2,61,1,4,1,3 +68465,7,2,2,80,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,1,2,NA,1,2,1,1,2,1,1,2,1,NA,13689.379977,14234.742701,2,92,2,2,0.89,1,1,0,0,1,2,80,2,1,2,NA +68466,7,2,1,33,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,25624.148584,27611.905955,2,96,12,12,NA,2,1,0,0,0,1,33,1,3,3,NA +68467,7,2,2,47,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,139800.409559,144765.126463,1,100,15,15,5,4,4,0,2,0,2,47,1,5,1,5 +68468,7,2,1,61,NA,2,2,2,NA,NA,2,NA,2,1,8,NA,1,1,NA,2,2,2,2,2,2,1,2,2,2,9115.676792,11889.427964,2,90,6,6,1.7,2,2,0,0,2,1,61,2,1,1,2 +68469,7,2,1,25,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,29738.952706,30201.133298,2,94,3,3,1.01,1,1,0,0,0,1,25,1,4,5,NA +68470,7,2,1,56,NA,5,6,2,NA,NA,2,NA,2,1,3,NA,3,1,NA,1,2,2,1,2,2,1,2,2,3,12158.061776,12114.139928,3,90,15,15,3.7,5,5,0,0,0,1,56,2,3,1,3 +68471,7,2,2,15,NA,4,4,2,15,185,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11600.051433,12143.645666,3,90,14,14,2.97,5,5,0,2,1,1,73,2,3,2,NA +68472,7,2,1,9,NA,3,3,2,9,110,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18324.386573,20287.008963,2,95,7,7,1.13,6,6,0,3,1,1,52,1,4,1,4 +68473,7,2,1,28,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,17811.496463,19015.919888,2,99,NA,77,NA,3,2,0,0,1,1,63,1,3,5,NA +68474,7,2,1,35,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,108014.727405,114941.235527,2,94,14,14,4.71,3,3,1,0,0,1,35,1,5,1,5 +68475,7,2,2,12,NA,3,3,2,12,146,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,36586.371708,39087.782259,1,98,3,3,0.5,5,5,0,3,0,2,56,1,3,3,NA +68476,7,2,2,9,NA,4,4,1,9,112,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9139.784234,11102.911341,2,100,3,3,0.63,4,4,0,1,0,1,51,1,2,77,NA +68477,7,2,1,21,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,16386.190684,20296.970403,2,90,7,5,1.84,2,1,0,0,0,1,21,1,3,5,NA +68478,7,2,1,41,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,116464.874823,120278.381994,2,94,10,10,2.91,4,4,0,2,0,2,38,1,4,1,4 +68479,7,2,2,3,NA,3,3,2,3,40,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,27257.164734,28966.726071,1,95,4,4,0.65,6,6,2,2,0,2,36,1,4,6,NA +68480,7,2,1,6,NA,1,1,2,6,77,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,12477.812875,12553.43469,2,94,7,7,1.17,6,6,1,2,0,2,30,2,3,6,NA +68481,7,2,2,19,NA,3,3,2,19,239,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,100004.689924,104137.373956,1,90,15,15,5,3,3,0,0,1,1,66,NA,NA,1,4 +68482,7,2,2,77,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,15211.382198,16229.383727,2,101,3,3,0.65,3,3,0,0,1,2,77,1,3,2,NA +68483,7,2,2,14,NA,1,1,1,14,176,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,16427.640886,18021.433684,1,102,7,7,1.41,5,5,0,2,2,1,72,1,4,1,3 +68484,7,2,1,47,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,10846.102759,10858.953375,1,99,7,5,1.84,2,1,0,1,0,1,47,2,4,5,NA +68485,7,2,2,64,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,122483.259869,124909.680309,3,91,6,6,2.3,1,1,0,0,1,2,64,1,5,3,NA +68486,7,2,1,3,NA,4,4,1,3,45,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10690.995725,11500.031681,2,98,5,5,0.59,7,7,3,0,0,2,50,1,5,4,NA +68487,7,2,1,19,NA,4,4,2,19,229,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,NA,NA,NA,1,2,2,1,10817.360862,11219.635132,2,99,6,6,1.15,5,5,1,2,0,2,34,1,4,77,NA +68488,7,2,2,58,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,16741.034883,16282.872546,2,95,4,4,1.61,1,1,0,0,0,2,58,1,5,5,NA +68489,7,2,2,10,NA,4,4,2,10,127,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7746.357421,8271.811673,1,99,7,7,2.52,2,2,0,1,0,2,40,1,4,3,NA +68490,7,2,2,4,NA,5,6,1,4,59,NA,NA,2,2,2,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5601.441711,5595.525293,1,103,5,5,1.26,3,3,1,0,0,1,40,2,5,1,5 +68491,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,35161.248998,42165.766203,3,91,7,7,2.45,2,2,0,0,2,1,80,1,2,1,2 +68492,7,2,1,0,1,1,1,2,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8519.229538,8673.80493,1,101,15,15,4.99,4,4,2,0,0,1,31,1,4,1,4 +68493,7,2,1,29,NA,5,6,2,NA,NA,2,NA,2,2,1,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,11770.082057,12287.307332,3,91,5,5,1.08,3,3,1,0,0,1,29,2,5,1,5 +68494,7,2,2,38,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,2,2,1,2,2,1,2,2,1,2,2,1,20626.479002,22617.279591,2,100,4,1,0,2,1,0,0,0,2,38,1,3,2,NA +68495,7,2,2,78,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,27275.632708,28985.222851,2,96,2,2,0.87,1,1,0,0,1,2,78,1,3,2,NA +68496,7,2,1,56,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,17188.361186,17721.573899,2,95,2,2,0.75,1,1,0,0,0,1,56,1,2,3,NA +68497,7,2,2,34,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,3,2,1,2,2,1,2,2,1,2,2,1,59613.972918,59797.266126,2,100,5,5,2.2,1,1,0,0,0,2,34,1,5,3,NA +68498,7,2,2,63,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,9547.901254,10157.592212,3,90,15,15,5,5,5,1,0,1,1,38,2,3,1,4 +68499,7,2,1,58,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,175544.769665,182852.89468,1,91,15,15,5,2,2,0,0,0,2,56,1,4,1,4 +68500,7,2,2,80,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,12863.404053,13555.744544,2,90,6,6,2.75,1,1,0,0,1,2,80,1,5,2,NA +68501,7,2,1,52,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,152467.08796,152865.087613,1,94,8,8,1.67,5,5,1,2,0,1,52,1,4,1,4 +68502,7,2,1,27,NA,4,4,2,NA,NA,2,NA,2,1,6,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,21873.767586,21362.816924,2,99,77,4,1.43,2,1,0,0,0,1,27,2,5,5,NA +68503,7,2,2,3,NA,5,7,2,3,38,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,27257.164734,28966.726071,1,92,3,3,0.46,5,5,2,1,0,1,30,1,3,1,2 +68504,7,2,2,6,NA,3,3,1,6,75,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,48532.852397,48387.04619,1,98,14,14,4.12,4,4,0,2,0,2,36,1,5,1,3 +68505,7,2,1,57,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,NA,151766.599459,156268.87702,3,91,7,7,1.97,4,4,0,0,1,2,77,1,5,2,NA +68506,7,2,2,77,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,32189.450686,32533.215899,1,101,4,4,1.22,2,2,0,0,2,2,77,1,4,1,3 +68507,7,2,2,49,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,25189.111847,25556.352159,2,102,10,10,4.76,2,2,0,0,1,2,49,2,5,5,NA +68508,7,2,2,31,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,5,1,3,1,2,2,1,2,2,1,2,2,1,15542.93857,15828.161907,3,91,8,8,2.7,3,3,1,0,0,1,31,1,5,1,5 +68509,7,2,2,26,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,14140.449064,14449.882828,3,90,15,15,4.2,6,6,1,0,2,1,60,1,5,1,4 +68510,7,2,1,65,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,8886.717016,8956.231711,2,101,6,6,1.51,3,3,0,1,1,1,65,1,2,1,4 +68511,7,2,2,9,NA,5,7,1,9,114,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8128.755281,8415.30848,1,98,4,4,0.94,3,3,1,1,0,2,28,1,2,77,NA +68512,7,2,2,57,NA,2,2,2,NA,NA,2,NA,2,1,6,NA,2,1,NA,2,2,2,2,2,2,2,2,2,2,20734.495277,22158.856945,2,99,77,77,NA,3,3,0,0,0,2,57,2,2,1,1 +68513,7,2,2,69,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,54370.517487,54186.584794,1,95,6,6,2.04,2,2,0,0,2,1,71,1,3,1,4 +68514,7,2,1,3,NA,5,7,2,3,44,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7629.74403,8207.121237,1,99,6,6,0.6,7,7,2,1,1,2,69,1,3,2,NA +68515,7,2,1,13,NA,5,7,1,13,163,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,63907.082519,63067.196763,1,102,8,8,1.91,5,5,1,2,0,2,38,1,5,1,4 +68516,7,2,1,30,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,28213.419452,32164.786649,1,100,7,7,3.13,1,1,0,0,0,1,30,1,5,5,NA +68517,7,2,1,28,NA,2,2,2,NA,NA,2,NA,2,2,2,NA,1,1,NA,1,2,1,1,2,2,NA,NA,NA,NA,49741.714519,52356.235161,2,91,14,14,4.71,3,3,0,0,0,1,28,2,1,1,2 +68518,7,2,2,25,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,19495.209875,21153.580858,2,90,7,7,3.31,1,1,0,0,0,2,25,1,5,5,NA +68519,7,2,1,5,NA,3,3,2,5,66,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,58332.578536,63879.860857,1,91,7,7,1.88,4,4,1,2,0,2,43,1,5,4,NA +68520,7,2,2,17,NA,3,3,2,17,207,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,29885.567338,31265.78413,1,94,7,7,0.94,7,7,1,4,0,2,46,2,5,1,5 +68521,7,2,2,28,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,4,3,2,1,2,2,1,2,2,1,2,2,1,47348.206546,48810.979214,1,92,10,10,2.93,4,4,1,0,0,2,55,1,4,1,4 +68522,7,2,1,12,NA,4,4,2,12,154,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10817.360862,11219.635132,2,99,6,6,1.15,5,5,1,2,0,2,34,1,4,77,NA +68523,7,2,2,62,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,11879.290971,12889.384857,2,96,2,2,0.83,1,1,0,0,1,2,62,1,2,5,NA +68524,7,2,1,11,NA,4,4,1,11,141,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9184.716222,9199.031651,1,102,7,7,1.57,4,4,0,2,0,2,33,1,4,1,4 +68525,7,2,2,39,NA,1,1,1,NA,NA,2,NA,2,1,5,NA,3,1,2,2,2,2,1,2,2,2,2,2,2,36453.846815,35470.245447,1,102,5,5,0.92,5,5,0,3,0,2,39,2,3,1,3 +68526,7,2,1,31,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,15799.067708,16817.831279,2,95,5,5,1.52,2,2,0,0,0,2,58,1,2,2,NA +68527,7,2,2,8,NA,3,3,1,8,107,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,48532.852397,48387.04619,1,98,15,15,5,5,5,0,3,0,2,41,1,5,6,NA +68528,7,2,2,70,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,NA,90234.245265,93002.542962,2,101,6,6,2.75,1,1,0,0,1,2,70,1,4,3,NA +68529,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,42992.537371,48017.666119,2,95,5,5,1.79,1,1,0,0,1,2,80,1,4,2,NA +68530,7,2,1,13,NA,2,2,2,13,166,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13921.972975,14228.387356,3,90,14,14,3.93,3,3,0,1,0,2,36,2,3,1,4 +68531,7,2,1,60,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,6038.685119,6085.921613,1,96,15,15,5,3,3,0,0,1,1,60,1,4,1,4 +68532,7,2,1,3,NA,1,1,1,3,37,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,17341.8035,17890.748046,2,102,6,6,1,6,6,1,3,0,1,35,2,3,1,3 +68533,7,2,2,9,NA,5,6,2,9,111,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6198.268014,6830.048804,3,90,77,77,NA,5,5,0,2,0,1,46,2,3,1,3 +68534,7,2,2,8,NA,2,2,1,8,99,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,2,2,2,1,2,2,1,15897.166957,16345.216522,2,102,4,4,0.57,6,6,2,3,0,2,26,2,3,1,NA +68535,7,2,2,0,7,1,1,2,NA,8,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,6787.112205,7016.795893,2,94,13,2,0.36,5,4,1,1,0,1,25,2,4,1,4 +68536,7,2,2,60,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,8308.628726,8949.073879,2,95,7,7,3.22,1,1,0,0,1,2,60,1,3,3,NA +68537,7,2,2,34,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,95087.883412,95380.247139,1,100,15,15,5,2,2,0,0,0,1,46,1,4,1,5 +68538,7,2,1,72,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,9472.03363,9657.569347,2,93,12,12,NA,4,4,0,0,2,1,72,1,2,1,4 +68539,7,1,1,72,NA,2,2,NA,NA,NA,2,NA,2,1,9,NA,2,5,NA,2,2,2,1,2,2,NA,NA,NA,NA,12962.876803,0,2,90,3,3,0.92,1,1,0,0,1,1,72,2,2,5,NA +68540,7,2,1,9,NA,3,3,2,9,116,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14307.565788,15198.555052,3,91,5,5,1.07,4,4,0,2,0,2,36,1,5,1,4 +68541,7,2,1,12,NA,4,4,2,12,151,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11125.932433,11147.929312,1,96,77,77,NA,7,7,0,3,1,2,43,77,5,5,NA +68542,7,2,2,4,NA,3,3,1,4,54,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,21341.740728,22680.288414,1,98,4,4,0.67,5,5,1,2,0,1,29,1,4,1,3 +68543,7,2,2,13,NA,1,1,1,13,160,NA,NA,2,2,3,6,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,21819.210646,22256.331163,3,92,6,6,0.86,7,7,1,4,0,2,36,2,1,1,1 +68544,7,2,1,66,NA,5,6,1,NA,NA,1,1,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,8623.181934,9096.941425,2,103,6,6,2.28,1,1,0,0,1,1,66,1,4,5,NA +68545,7,2,1,63,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,8219.195224,8540.664122,2,99,2,2,0.2,7,7,1,2,1,1,63,1,1,2,NA +68546,7,2,2,6,NA,4,4,2,6,79,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10888.493631,13227.224662,1,101,13,13,NA,5,5,0,1,0,1,53,1,3,1,3 +68547,7,2,2,21,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,60914.616471,70137.240791,2,91,2,2,0.58,1,1,0,0,0,2,21,1,5,5,NA +68548,7,2,2,66,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,1,124544.616504,126579.471046,1,100,6,6,2.82,1,1,0,0,1,2,66,1,5,2,NA +68549,7,2,1,67,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,1,1,NA,2,2,2,1,2,2,2,2,2,1,9430.93681,9952.400706,1,92,3,3,0.88,2,2,0,0,2,1,67,1,1,1,1 +68550,7,1,2,80,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,1,2,1,2,2,NA,NA,NA,NA,37019.065541,0,1,96,15,15,5,3,2,0,0,2,2,57,1,5,6,NA +68551,7,2,2,80,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,11532.104822,12394.666968,2,99,4,4,1.61,1,1,0,0,1,2,80,1,1,2,NA +68552,7,2,2,0,2,4,4,1,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4439.36229,4769.277094,1,96,5,5,0.53,7,7,2,2,0,2,38,1,9,6,NA +68553,7,2,2,61,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,129999.035519,131590.908764,1,98,6,6,1.11,5,5,0,2,1,2,37,1,1,1,1 +68554,7,2,2,11,NA,1,1,1,11,132,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17053.854294,17496.484818,2,94,6,6,0.8,7,7,1,3,0,2,36,2,3,1,1 +68555,7,2,2,6,NA,3,3,1,6,79,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,22308.590534,22137.463018,1,101,5,5,0.71,6,6,1,1,1,1,63,1,2,1,5 +68556,7,2,2,50,NA,2,2,2,NA,NA,2,NA,2,1,6,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,24902.414229,28566.820481,1,90,15,15,5,2,2,0,0,0,2,50,2,4,3,NA +68557,7,2,1,71,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,NA,15176.622228,16562.859469,1,101,3,3,0.98,1,1,0,0,1,1,71,1,3,3,NA +68558,7,2,2,62,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,1,1,NA,1,2,1,1,2,1,1,2,1,3,17243.546687,17998.333464,1,92,1,1,0.26,2,2,0,0,2,1,63,2,1,1,1 +68559,7,2,1,80,NA,3,3,2,NA,NA,2,NA,2,1,9,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,34540.440658,39912.090511,1,90,6,6,2.69,1,1,0,0,1,1,80,2,3,2,NA +68560,7,2,2,28,NA,1,1,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,51746.15111,53882.638481,1,95,6,6,1.37,3,3,1,1,0,2,28,1,4,5,NA +68561,7,2,2,65,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,145813.864843,148196.223981,1,100,6,6,1.31,3,3,0,0,2,1,65,1,5,1,5 +68562,7,2,1,3,NA,4,4,1,3,44,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9016.053035,9126.025,2,100,6,6,1.52,4,4,1,2,0,2,39,1,4,3,NA +68563,7,2,2,17,NA,4,4,1,17,208,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13452.957635,13490.376767,2,93,4,4,1.29,2,2,0,1,0,2,56,2,3,4,NA +68564,7,2,2,35,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,4,1,2,1,2,1,1,2,1,NA,NA,NA,NA,20039.469886,21581.359058,1,97,15,15,5,4,4,2,0,0,2,35,2,4,1,4 +68565,7,2,2,65,NA,5,6,2,NA,NA,2,NA,2,1,8,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,14102.354333,14646.654863,3,91,15,15,5,2,2,0,0,2,2,65,2,5,1,5 +68566,7,2,1,13,NA,4,4,1,13,158,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13468.614146,13600.508187,2,102,5,5,0.67,6,6,0,4,0,2,33,1,2,6,NA +68567,7,2,2,54,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,24217.957803,24014.890408,2,94,4,1,0.09,2,1,0,0,0,2,51,1,2,6,NA +68568,7,2,1,27,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,114410.004231,116188.079068,1,97,15,15,3.89,5,5,0,2,0,1,50,1,4,6,NA +68569,7,2,2,56,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,4,NA,1,2,2,1,2,2,1,2,2,1,19977.261965,20728.031273,1,92,NA,1,0.18,4,3,0,2,0,2,56,1,4,4,NA +68570,7,2,1,49,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,23465.604153,23669.640656,2,98,3,3,1.19,1,1,0,0,0,1,49,1,3,3,NA +68571,7,2,1,53,NA,5,6,1,NA,NA,2,NA,2,2,5,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,10562.541357,10524.383438,1,103,5,5,0.65,6,6,0,0,1,2,26,2,4,5,NA +68572,7,2,1,42,NA,3,3,1,NA,NA,2,NA,2,2,2,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,117613.757473,123317.366869,2,93,9,9,3.77,2,2,0,0,0,2,42,2,4,1,5 +68573,7,2,1,64,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,10288.337394,10853.580889,3,91,9,9,3.24,3,3,0,1,1,1,64,2,2,1,5 +68574,7,2,1,20,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,39915.513053,40776.102186,2,98,7,7,1.53,5,5,0,0,0,2,48,1,3,5,NA +68575,7,2,2,42,NA,2,2,1,NA,NA,2,NA,2,1,7,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,33565.905936,33977.52311,2,93,14,14,3.52,5,5,1,2,0,1,44,1,5,1,5 +68576,7,2,2,1,20,1,1,2,NA,20,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,9439.743884,10034.856293,1,90,6,6,1.11,5,5,1,2,0,1,30,2,1,6,NA +68577,7,2,1,19,NA,2,2,2,19,239,2,NA,1,1,NA,14,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,22228.448129,22318.929635,1,93,6,6,1.78,3,3,0,0,0,1,19,1,3,NA,NA +68578,7,2,1,8,NA,2,2,1,8,100,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13665.416457,13530.568366,1,94,5,5,0.74,5,5,1,1,0,2,24,1,3,1,4 +68579,7,2,1,6,NA,1,1,1,6,74,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,11159.151566,11335.739115,1,102,6,6,1.03,6,6,0,4,0,1,34,2,2,1,1 +68580,7,2,2,47,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,46405.063078,46647.061535,2,98,10,10,4.43,2,2,0,0,1,2,47,1,4,3,NA +68581,7,2,1,43,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,18790.641284,18862.037788,2,100,15,15,4.97,5,5,0,2,1,2,42,1,5,1,5 +68582,7,2,2,42,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,19807.824556,20146.472612,1,96,9,9,3.35,3,3,0,0,0,2,42,1,4,5,NA +68583,7,2,1,11,NA,3,3,2,11,135,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,42986.51011,44926.997612,2,94,14,14,2.83,6,6,0,4,0,2,38,1,2,1,2 +68584,7,2,1,18,NA,3,3,2,18,221,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,88198.948426,91036.751291,1,101,9,9,2.6,4,4,0,1,2,2,63,1,4,1,4 +68585,7,2,2,1,17,1,1,1,NA,17,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,11901.705423,12652.027961,2,102,7,7,1.33,6,6,1,3,0,1,34,2,2,1,1 +68586,7,2,2,20,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,29040.300396,28462.118402,2,101,1,1,0.05,4,1,0,0,0,2,21,1,4,5,NA +68587,7,2,2,2,NA,4,4,2,2,35,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6854.479526,6961.787344,2,91,6,6,0.78,7,7,1,4,0,2,38,2,2,77,NA +68588,7,2,2,14,NA,1,1,1,14,174,NA,NA,1,1,NA,8,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,16360.434077,17687.989006,3,91,5,5,1.03,4,4,0,2,0,2,42,2,1,5,NA +68589,7,2,1,54,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,16117.991297,16472.240486,1,96,10,10,3.04,4,4,0,1,0,2,43,1,5,1,4 +68590,7,2,1,1,16,4,4,2,NA,17,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5942.817425,6188.375425,2,97,13,13,NA,6,6,2,2,0,2,24,1,2,6,NA +68591,7,2,1,67,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,8088.223021,7993.317874,1,99,14,14,4.86,3,3,0,1,1,2,56,1,5,1,5 +68592,7,2,1,34,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,24793.720953,26072.340199,1,92,14,14,3.25,4,4,0,2,0,1,34,1,4,6,NA +68593,7,2,2,63,NA,5,6,2,NA,NA,2,NA,2,1,8,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,14745.12656,14965.949752,1,98,10,10,5,1,1,0,0,1,2,63,2,5,5,NA +68594,7,2,1,80,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,12291.154515,13189.875012,1,95,3,3,0.92,1,1,0,0,1,1,80,1,3,2,NA +68595,7,2,2,50,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,4,NA,1,2,2,1,2,2,1,2,2,1,36676.329165,37617.002202,1,95,4,4,1.56,1,1,0,0,0,2,50,1,2,4,NA +68596,7,2,2,6,NA,3,3,1,6,82,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,17958.854782,18534.102526,2,100,2,2,0.38,3,3,0,2,0,2,35,1,4,5,NA +68597,7,2,2,73,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,NA,49260.413155,50771.674072,2,100,14,5,2.2,2,1,0,0,2,1,71,1,2,6,NA +68598,7,2,1,14,NA,4,4,1,15,180,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11429.628358,11512.87076,2,96,3,3,0.47,6,6,0,4,0,1,36,1,4,1,4 +68599,7,2,2,2,NA,1,1,1,2,32,NA,NA,2,1,2,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13322.479814,13501.65138,1,92,5,5,1.15,3,3,1,0,0,2,27,1,3,1,3 +68600,7,2,2,7,NA,3,3,2,7,94,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,24070.467912,24097.958076,1,95,6,3,0.45,6,4,1,2,0,1,28,1,2,1,2 +68601,7,2,1,26,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,9956.598907,10266.888978,1,95,5,5,0.73,6,6,1,0,1,1,62,2,3,1,NA +68602,7,2,1,36,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,2,1,NA,2,2,2,2,2,2,2,2,2,2,34997.800447,35379.102239,2,96,6,6,1.11,5,5,0,3,0,2,32,2,3,1,2 +68603,7,2,1,19,NA,4,4,2,19,234,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12721.673656,12814.326071,2,97,2,2,0.49,2,2,0,0,0,1,24,1,4,6,NA +68604,7,2,2,2,NA,4,4,2,2,27,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5403.773938,5854.006054,3,90,10,10,2.59,5,5,1,2,0,2,32,1,4,1,4 +68605,7,2,2,46,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,1,23003.908463,24458.642976,2,99,12,1,0.12,2,1,0,0,1,2,46,1,3,2,NA +68606,7,2,2,62,NA,2,2,2,NA,NA,2,NA,2,1,7,NA,1,2,NA,2,2,2,2,2,2,1,2,2,2,9330.330573,12477.420452,3,90,6,6,1.04,5,5,0,1,1,2,50,2,1,1,2 +68607,7,2,2,0,4,5,6,2,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5507.575232,5813.640954,1,97,15,15,2.33,7,7,2,4,0,2,40,2,5,1,4 +68608,7,1,2,80,NA,3,3,NA,NA,NA,2,NA,2,1,9,NA,5,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,41252.836432,0,1,100,15,15,5,3,1,0,0,3,2,69,NA,NA,5,NA +68609,7,2,1,4,NA,1,1,2,4,50,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,14505.510202,14676.996441,2,94,7,7,1.17,6,6,1,2,0,2,30,2,3,6,NA +68610,7,2,1,6,NA,4,4,1,7,84,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8439.403196,8726.876152,2,103,6,6,1.11,5,5,1,2,0,2,36,1,4,5,NA +68611,7,2,1,8,NA,5,6,2,8,96,NA,NA,2,2,3,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9928.619925,10708.884665,1,91,12,12,NA,4,4,0,2,0,1,43,2,5,1,5 +68612,7,2,2,55,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,24713.281483,24036.937705,1,92,10,10,4.3,2,2,0,0,0,2,55,1,4,1,5 +68613,7,2,2,61,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,166028.936087,168741.576297,2,101,8,8,4.41,1,1,0,0,1,2,61,1,4,2,NA +68614,7,2,1,73,NA,2,2,2,NA,NA,2,NA,2,1,9,NA,2,1,NA,2,2,2,1,2,2,2,2,2,NA,15301.031416,16695.608527,1,90,4,4,0.94,3,3,0,0,2,2,78,2,1,1,2 +68615,7,2,1,0,0,2,2,1,NA,0,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7530.249163,7898.897498,2,102,14,14,3.25,5,5,2,0,0,1,27,1,5,1,5 +68616,7,2,2,17,NA,4,4,2,17,206,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11956.705842,11923.015236,1,96,15,15,5,5,5,0,3,0,2,47,1,5,1,5 +68617,7,2,2,2,NA,5,6,2,2,26,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4938.043177,5022.237557,1,91,14,14,3.69,4,4,1,1,0,2,29,2,5,1,5 +68618,7,2,2,13,NA,5,6,2,13,158,NA,NA,2,2,2,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7649.811754,7945.620413,2,90,3,1,0,5,1,1,2,0,1,44,2,5,1,5 +68619,7,2,1,30,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,16942.073558,18043.178849,1,99,6,6,1.12,4,4,2,0,0,2,29,1,2,1,4 +68620,7,2,1,36,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,16555.478822,16319.493771,2,96,3,3,0.47,6,6,0,4,0,1,36,1,4,1,4 +68621,7,2,2,14,NA,4,4,1,14,178,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18163.985724,18749.311901,2,101,6,6,1.16,4,4,0,3,0,2,36,1,4,4,NA +68622,7,2,2,70,NA,3,3,2,NA,NA,2,NA,2,1,9,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,64463.340883,65151.773075,1,91,7,7,2.72,2,2,0,0,2,1,70,NA,NA,1,4 +68623,7,2,1,28,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,11279.598253,11667.930056,1,93,15,15,5,5,5,1,0,1,1,61,2,4,1,4 +68624,7,2,1,45,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,34205.013302,34329.398365,2,102,14,14,2.44,7,7,0,2,1,2,71,1,3,3,NA +68625,7,2,1,24,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,2,2,2,1,2,2,1,2,2,1,47487.549895,49034.44781,1,102,77,77,NA,3,3,0,0,1,1,61,2,4,1,1 +68626,7,2,2,70,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,54781.947924,56462.604085,2,93,10,10,3.61,3,3,0,0,2,1,75,1,4,1,4 +68627,7,2,2,70,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,74668.489197,78374.230241,2,91,77,77,NA,2,2,0,0,2,2,70,1,3,1,4 +68628,7,2,2,17,NA,4,4,2,17,206,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11711.384457,11558.024533,2,95,8,8,1.61,6,6,1,3,0,2,48,1,3,5,NA +68629,7,2,2,4,NA,4,4,1,4,57,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10437.988787,11378.89676,1,96,12,12,NA,7,7,1,0,1,2,59,1,3,1,1 +68630,7,2,1,32,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,69063.138927,75761.928286,1,92,10,10,2.1,6,6,1,1,0,2,29,1,4,1,2 +68631,7,2,1,12,NA,5,6,2,12,149,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10618.845283,10988.972369,1,93,14,14,5,2,2,0,1,0,2,46,2,5,3,NA +68632,7,2,2,65,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,134694.414609,139412.076132,2,94,15,15,5,2,2,0,0,2,1,64,1,5,1,5 +68633,7,2,2,38,NA,1,1,2,NA,NA,2,NA,2,2,4,NA,3,1,2,1,2,2,1,2,2,1,2,2,2,46400.322077,46544.459997,1,95,9,9,2.46,4,4,0,0,0,1,42,2,2,1,3 +68634,7,2,2,15,NA,4,4,1,15,181,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17373.928778,17416.718116,2,96,15,15,5,3,3,0,1,0,1,55,1,5,1,4 +68635,7,2,2,58,NA,5,6,1,NA,NA,2,NA,2,2,4,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,19183.115011,19284.554221,1,92,14,14,5,2,2,0,0,0,1,40,1,5,1,4 +68636,7,2,1,1,17,5,6,2,NA,19,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6319.053383,6506.026949,1,91,15,15,5,3,3,1,0,0,1,39,2,5,1,5 +68637,7,2,2,33,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,28059.790487,28146.065043,1,94,7,7,1.21,6,6,2,2,0,1,31,1,2,6,NA +68638,7,2,1,18,NA,4,4,2,18,222,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11538.004005,11560.815583,1,96,9,9,3.35,3,3,0,0,0,2,42,1,4,5,NA +68639,7,2,2,19,NA,3,3,2,19,235,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,123622.182994,134789.559864,2,94,15,15,3.82,5,5,0,0,0,1,50,1,5,1,5 +68640,7,2,2,28,NA,5,6,2,NA,NA,2,NA,2,1,3,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,12412.338679,12980.380959,3,90,15,15,3.7,5,5,0,0,0,1,56,2,3,1,3 +68641,7,2,2,14,NA,1,1,1,14,176,NA,NA,1,1,NA,7,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,20460.442471,21235.303768,2,102,7,7,1.04,7,7,1,2,0,2,37,2,1,1,2 +68642,7,2,1,16,NA,4,4,1,16,197,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,16147.713323,16532.569027,1,92,NA,1,0.18,4,3,0,2,0,2,56,1,4,4,NA +68643,7,2,1,17,NA,1,1,1,17,207,2,NA,1,1,NA,10,NA,NA,NA,2,2,2,2,2,2,1,2,2,1,32326.52031,34735.818434,2,94,5,5,0.65,6,6,0,3,0,1,44,2,1,1,1 +68644,7,2,2,1,13,2,2,2,NA,14,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9889.733317,10584.607254,1,91,5,5,0.8,5,5,2,1,0,2,31,2,3,1,1 +68645,7,2,2,75,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,NA,48731.095364,50226.117333,2,93,6,6,2.51,1,1,0,0,1,2,75,1,5,3,NA +68646,7,2,2,45,NA,1,1,2,NA,NA,2,NA,2,2,6,NA,2,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,34226.159502,34404.646012,1,97,4,4,0.65,4,4,0,1,0,2,45,2,2,3,NA +68647,7,2,1,54,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,16851.334496,17374.092058,2,95,3,3,1.07,1,1,0,0,0,1,54,1,2,5,NA +68648,7,2,2,30,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,85420.170155,86011.35365,1,91,14,14,3.06,5,5,2,0,0,2,30,1,5,1,5 +68649,7,2,2,0,8,1,1,2,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6787.112205,7238.162123,2,94,8,8,2.33,4,4,2,0,0,1,24,1,2,6,NA +68650,7,2,1,3,NA,5,7,1,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6538.646646,7333.807608,2,100,6,6,1.62,3,3,1,0,0,1,32,1,3,1,3 +68651,7,2,2,32,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,87808.984693,88078.968218,1,93,15,15,5,1,1,0,0,0,2,32,1,5,5,NA +68652,7,2,1,34,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,78529.577822,86568.047729,1,98,10,10,2.2,6,6,1,3,0,2,31,1,4,6,NA +68653,7,2,1,9,NA,1,1,1,9,118,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11159.151566,11210.524757,1,102,4,4,0.5,6,6,2,2,0,1,25,1,2,1,3 +68654,7,2,2,2,NA,4,4,2,2,26,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5687.793894,6161.690011,2,90,7,7,1.53,5,5,2,1,0,1,35,2,4,1,4 +68655,7,2,1,19,NA,5,6,1,19,231,2,NA,2,2,1,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,9948.022697,10353.284725,2,101,5,5,1.84,2,1,0,0,0,1,19,2,4,NA,NA +68656,7,2,1,10,NA,4,4,2,10,126,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8183.206265,8693.880504,3,90,3,3,0.78,3,3,0,1,2,1,80,2,3,1,2 +68657,7,2,1,67,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,1,22705.790734,22474.018796,1,95,3,3,0.76,3,3,0,0,1,1,41,1,2,1,4 +68658,7,2,2,17,NA,5,6,2,17,212,2,NA,2,1,99,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,10998.124667,11476.706351,1,91,15,15,5,4,4,0,2,0,2,55,1,5,1,5 +68659,7,2,2,15,NA,3,3,1,15,186,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,85039.920663,86146.650284,1,94,14,14,2.96,5,5,0,3,0,2,39,1,4,1,3 +68660,7,2,1,24,NA,2,2,1,NA,NA,2,NA,2,2,3,NA,1,5,NA,2,2,2,1,2,2,2,2,1,2,38474.772527,38999.213364,2,93,4,4,0.56,5,5,0,0,0,2,49,2,2,5,NA +68661,7,2,2,64,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,10991.458112,11482.21496,2,99,15,15,5,2,2,0,0,2,1,60,1,5,1,5 +68662,7,2,2,37,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,4,1,1,1,2,2,1,2,2,1,2,2,1,16369.916397,16518.354031,1,101,8,8,1.81,5,5,2,0,1,2,37,2,4,1,2 +68663,7,2,2,48,NA,5,6,1,NA,NA,2,NA,2,2,4,NA,3,1,NA,1,2,1,1,2,1,1,2,1,3,14101.070104,15807.720539,2,92,6,6,1.3,4,4,0,1,0,2,48,2,3,1,3 +68664,7,2,1,6,NA,2,2,1,6,79,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13953.558291,13815.866863,2,93,15,15,5,3,3,0,1,0,2,36,2,3,1,5 +68665,7,2,2,51,NA,2,2,1,NA,NA,2,NA,2,1,4,NA,3,3,NA,2,2,2,2,2,2,2,2,1,2,23122.188977,23961.502212,2,93,4,4,0.69,4,4,0,1,1,2,66,2,3,2,NA +68666,7,2,1,15,NA,5,6,1,15,183,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9587.464696,10013.85895,3,92,15,15,5,3,3,0,1,0,1,55,2,5,1,4 +68667,7,2,1,51,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,5,1,NA,1,2,1,1,2,1,1,2,2,3,22345.774392,22681.166648,1,92,7,7,2.1,3,3,0,0,0,1,24,2,4,5,NA +68668,7,2,2,8,NA,1,1,1,8,104,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15841.451259,16252.614023,3,92,15,15,3.15,7,7,0,4,0,2,35,2,3,3,NA +68669,7,2,1,51,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,27140.404673,27611.034752,1,101,1,1,0.08,6,6,0,1,0,1,51,1,2,5,NA +68670,7,2,2,5,NA,5,7,2,6,72,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8173.816615,8894.95474,1,97,15,15,5,4,4,1,0,0,2,39,2,5,1,5 +68671,7,2,1,6,NA,4,4,2,6,81,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7504.213986,7926.614174,2,99,2,2,0.19,7,7,3,1,0,2,43,1,2,4,NA +68672,7,2,1,46,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,133495.735893,134864.21511,3,92,12,3,0.98,3,1,0,0,0,1,45,1,3,1,3 +68673,7,2,1,62,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,4,4,NA,1,2,2,1,2,2,1,2,2,1,10004.038848,10164.290775,2,102,5,5,1.3,3,3,0,0,1,1,56,1,2,5,NA +68674,7,2,2,0,5,5,7,1,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8377.359485,8321.07116,2,96,12,12,NA,4,4,1,0,0,2,20,1,5,1,5 +68675,7,2,2,73,NA,5,6,1,NA,NA,2,NA,2,1,8,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,18481.000773,19056.863071,1,100,10,10,4.63,2,2,0,0,2,1,78,2,5,1,5 +68676,7,2,2,51,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,4,NA,1,2,2,1,2,2,1,2,2,1,19060.786733,19514.352798,2,97,4,4,0.81,4,4,1,1,0,2,51,1,3,4,NA +68677,7,2,2,2,NA,5,7,1,2,25,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8474.492088,9470.199674,1,102,7,7,1.9,4,4,1,1,0,1,29,1,4,1,3 +68678,7,2,1,43,NA,2,2,2,NA,NA,2,NA,2,2,3,NA,1,1,NA,2,2,2,2,2,2,1,2,2,2,27776.016947,27368.446715,2,90,99,99,NA,5,5,1,1,0,2,40,2,3,1,1 +68679,7,2,1,43,NA,5,7,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,168806.614822,176992.791466,2,101,5,5,1.36,2,2,0,0,0,2,47,1,2,1,4 +68680,7,2,2,22,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,6,2,1,2,2,1,2,2,1,2,2,1,53634.754806,54437.113731,1,98,12,2,0.45,3,1,0,0,0,2,22,NA,NA,5,NA +68681,7,2,1,66,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,1,2,NA,7973.883342,8285.757609,1,100,5,5,2.06,1,1,0,0,1,1,66,1,3,3,NA +68682,7,2,2,79,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,98976.420245,105956.226489,2,101,5,5,1.63,2,2,0,0,2,1,80,1,1,1,1 +68683,7,2,2,20,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,2,1,2,2,2,2,1,2,2,1,2,2,2,32537.532358,33640.063825,2,90,8,8,2.01,4,4,0,0,1,2,67,2,4,2,NA +68684,7,2,2,6,NA,3,3,2,6,72,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,23521.178662,23340.749474,1,101,3,3,0.44,5,5,0,3,0,1,35,1,3,1,4 +68685,7,2,2,12,NA,4,4,2,12,154,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11905.948878,13980.928588,2,99,5,5,1.32,2,2,0,1,0,1,46,2,2,5,NA +68686,7,2,2,25,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,5,2,1,2,2,1,2,2,NA,NA,NA,NA,18801.993237,20608.537144,2,96,7,7,2.45,2,2,0,0,0,1,24,2,5,5,NA +68687,7,2,2,45,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,39843.937983,40051.72073,1,102,9,9,3.74,2,2,0,0,0,2,45,1,4,1,2 +68688,7,2,1,35,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,94644.050918,104631.781207,2,91,15,15,5,4,4,2,0,0,1,35,1,5,1,5 +68689,7,2,2,70,NA,2,2,1,NA,NA,2,NA,2,1,7,NA,1,1,NA,2,2,2,1,2,2,1,2,2,NA,18607.968221,20176.873294,2,92,5,5,1.36,2,2,0,0,2,1,75,2,1,1,1 +68690,7,2,2,29,NA,5,7,2,NA,NA,2,NA,2,1,6,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,45549.853584,51248.283427,3,91,7,7,1.57,4,4,2,0,0,2,29,2,3,1,3 +68691,7,2,1,7,NA,3,3,2,7,90,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,66868.503099,69864.859716,1,98,14,14,3.15,5,5,0,3,0,1,34,1,4,1,4 +68692,7,2,2,4,NA,5,6,1,4,50,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5081.860978,5222.553414,3,91,14,14,3.06,5,5,3,0,0,1,34,2,5,1,5 +68693,7,2,1,28,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,124091.929364,126020.47345,1,95,15,15,4.14,7,7,2,2,0,1,28,1,4,5,NA +68694,7,2,1,57,NA,4,4,2,NA,NA,1,1,2,1,8,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,16589.308426,16584.966003,2,90,15,15,5,4,4,0,0,0,1,57,2,5,1,5 +68695,7,2,1,20,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,25815.880139,26556.735732,2,101,1,1,0.23,2,1,0,0,0,1,20,1,4,5,NA +68696,7,2,1,44,NA,2,2,1,NA,NA,2,NA,2,2,4,NA,5,3,NA,2,2,2,2,2,2,2,2,2,2,35393.002863,36467.929589,2,93,3,3,0.58,4,4,0,1,1,1,65,2,1,3,NA +68697,7,2,1,10,NA,1,1,2,10,130,NA,NA,2,2,3,5,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,12477.812875,12675.267527,2,94,4,4,0.73,5,5,2,1,0,1,35,2,1,6,NA +68698,7,2,1,8,NA,1,1,1,8,107,NA,NA,2,2,2,2,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,13870.762641,14200.45921,2,102,7,7,1.33,6,6,1,3,0,1,34,2,2,1,1 +68699,7,2,2,18,NA,4,4,1,19,228,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13801.622751,14246.373765,1,100,10,10,2.59,5,5,0,1,0,2,40,1,5,1,NA +68700,7,2,2,4,NA,1,1,1,4,59,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,12261.362755,13536.873522,1,103,13,13,NA,4,4,2,0,0,2,27,2,2,6,NA +68701,7,2,2,27,NA,1,1,1,NA,NA,2,NA,2,2,6,NA,2,6,2,2,2,2,2,2,2,2,2,1,2,32455.694722,36034.785338,1,103,13,13,NA,4,4,2,0,0,2,27,2,2,6,NA +68702,7,2,1,56,NA,4,4,2,NA,NA,2,NA,2,2,7,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,20066.354173,20688.84721,1,96,6,6,2.24,1,1,0,0,0,1,56,2,3,3,NA +68703,7,2,1,63,NA,1,1,1,NA,NA,1,1,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,9235.951997,9415.956027,1,103,15,15,5,2,2,0,0,1,1,63,1,5,3,NA +68704,7,2,1,7,NA,3,3,2,7,95,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,18324.386573,20287.008963,2,95,7,7,1.13,6,6,0,3,1,1,52,1,4,1,4 +68705,7,2,1,6,NA,4,4,1,6,76,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12267.215138,12414.279886,2,102,5,5,0.76,5,5,1,3,0,2,30,1,4,4,NA +68706,7,2,1,26,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,21022.682584,20897.3615,1,100,5,5,1.05,3,3,1,0,0,2,35,1,4,6,NA +68707,7,2,1,54,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,166897.201244,167183.296853,2,91,15,15,5,4,4,0,0,0,1,54,1,5,1,NA +68708,7,2,2,61,NA,2,2,1,NA,NA,2,NA,2,2,6,NA,1,2,NA,2,2,2,2,2,2,1,2,2,2,6278.072933,7279.121105,2,103,5,5,0.65,6,6,1,0,1,2,61,2,1,2,NA +68709,7,2,2,30,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,2,5,3,1,2,2,1,2,2,NA,NA,NA,NA,12801.027411,15381.268364,2,90,77,77,NA,4,3,1,0,0,2,30,2,2,5,NA +68710,7,2,1,40,NA,2,2,1,NA,NA,2,NA,2,2,2,NA,4,1,NA,2,2,2,2,2,2,2,2,1,2,33029.272844,32544.619181,2,93,6,6,0.93,5,5,1,2,0,1,40,2,4,1,4 +68711,7,2,1,26,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,12084.002684,12472.760771,1,99,9,9,5,1,1,0,0,0,1,26,1,5,5,NA +68712,7,2,1,0,2,5,7,1,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7882.953266,8003.945501,2,96,7,7,1.79,4,4,1,0,0,2,30,1,4,6,NA +68713,7,2,2,22,NA,2,2,2,NA,NA,2,NA,2,1,6,NA,2,5,2,1,2,2,1,2,2,1,2,2,1,45798.520132,47350.399021,2,91,3,3,0.73,3,3,0,0,0,2,22,2,2,5,NA +68714,7,2,2,55,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,18441.731082,18102.807884,1,96,15,9,5,2,1,0,0,0,2,55,1,4,5,NA +68715,7,2,1,54,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,145342.530024,147904.745834,1,99,15,15,5,2,2,0,0,0,1,54,1,3,1,4 +68716,7,2,2,12,NA,1,1,1,12,151,NA,NA,1,1,NA,6,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,24481.187693,24971.637581,1,95,13,13,NA,5,5,1,2,0,2,34,2,1,1,1 +68717,7,2,1,80,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,9835.055907,10027.702409,2,99,10,10,4.76,2,2,0,0,2,1,80,1,2,2,NA +68718,7,2,2,6,NA,1,1,2,6,79,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,13231.432201,13706.598104,2,97,4,4,0.67,4,4,0,2,0,1,39,2,2,6,NA +68719,7,2,1,2,NA,5,6,2,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6185.185728,6679.834548,1,97,15,15,4.84,6,6,2,0,0,1,53,NA,NA,1,NA +68720,7,2,2,53,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,215228.012584,222579.783434,1,98,6,6,1.98,2,2,0,0,0,1,54,1,4,1,3 +68721,7,2,2,39,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,NA,NA,NA,NA,36053.766709,37679.125242,1,100,3,3,0.73,3,3,2,0,0,2,39,1,3,5,NA +68722,7,2,1,40,NA,2,2,1,NA,NA,2,NA,2,2,4,NA,2,1,NA,2,2,2,2,2,2,2,2,2,2,31740.385214,33170.19689,2,96,7,7,1.57,4,4,0,2,0,1,40,2,2,1,5 +68723,7,2,2,9,NA,1,1,1,9,110,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10118.363218,10311.586628,1,103,7,7,0.51,7,7,3,4,0,1,54,2,1,1,1 +68724,7,2,2,27,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,NA,NA,NA,NA,35160.335949,35576.957572,1,103,5,5,1.02,4,4,2,0,0,1,25,1,2,1,4 +68725,7,2,2,0,9,3,3,1,NA,10,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,27484.911887,26738.360643,1,92,14,14,3.9,4,4,2,0,0,2,28,1,3,1,3 +68726,7,2,2,52,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,27769.056387,27890.133764,1,94,2,2,0.42,3,3,0,0,0,2,52,1,4,1,1 +68727,7,2,2,9,NA,5,6,2,9,115,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6198.268014,6618.822195,3,90,12,12,NA,5,5,1,2,0,1,37,2,5,1,5 +68728,7,2,2,9,NA,2,2,1,9,117,NA,NA,1,1,NA,3,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,12307.832776,12608.996083,2,93,5,5,0.89,4,4,0,2,0,1,42,NA,NA,6,NA +68729,7,2,1,8,NA,1,1,1,8,100,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,12577.115885,12776.141954,2,96,6,6,1.11,6,6,0,2,1,1,40,2,2,1,2 +68730,7,2,1,80,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,NA,9260.072397,9783.740861,1,98,3,3,1.07,1,1,0,0,1,1,80,1,4,3,NA +68731,7,2,2,1,16,1,1,1,NA,16,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14326.094268,15816.39252,3,92,14,14,3.25,4,4,2,0,0,2,33,1,5,1,5 +68732,7,2,2,33,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,42456.72357,41469.55672,1,92,14,14,3.15,5,5,1,2,0,1,34,1,4,1,4 +68733,7,2,1,54,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,37557.946192,44552.872015,2,102,15,15,3.92,5,5,0,0,0,1,19,1,4,NA,NA +68734,7,2,2,1,17,3,3,1,NA,17,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,27529.278041,30383.810541,1,92,5,5,1.15,3,3,1,0,0,1,23,1,4,1,4 +68735,7,2,1,11,NA,4,4,2,11,136,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8453.214884,8599.856249,2,97,6,6,1.02,6,6,1,2,0,1,37,1,3,1,3 +68736,7,2,2,45,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,28499.00321,31184.438144,2,98,3,3,0.75,2,2,0,0,0,1,22,1,2,5,NA +68737,7,2,1,42,NA,1,1,2,NA,NA,2,NA,2,2,4,NA,2,1,NA,1,2,2,1,2,2,1,2,2,2,41527.444056,43502.112286,1,95,9,9,2.46,4,4,0,0,0,1,42,2,2,1,3 +68738,7,2,1,22,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,120220.968534,126279.549,1,98,6,6,1.78,2,2,0,0,0,2,48,1,4,5,NA +68739,7,2,1,31,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,3,4,NA,1,2,2,1,2,2,1,2,2,1,14204.262514,14001.792163,1,99,6,6,0.6,7,7,2,1,1,2,69,1,3,2,NA +68740,7,2,1,64,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,101090.822284,102038.91726,2,102,14,14,5,1,1,0,0,1,1,64,1,4,3,NA +68741,7,2,2,31,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,1,3,2,1,2,2,1,2,2,NA,NA,NA,NA,39561.667842,38928.923531,2,98,5,5,1.63,2,2,1,0,0,2,31,1,1,3,NA +68742,7,2,2,3,NA,2,2,1,4,48,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15358.480588,15565.033952,1,102,5,5,1.36,2,2,1,0,0,2,21,1,3,5,NA +68743,7,2,1,9,NA,5,7,2,9,116,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,5171.245544,5675.166629,1,99,15,15,4.47,4,4,0,2,0,2,52,2,5,1,5 +68744,7,2,1,33,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,19384.896286,22235.85388,1,94,5,5,1.04,4,4,0,2,0,2,29,1,3,1,3 +68745,7,2,2,61,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,31362.042024,31983.331006,1,94,4,4,1.4,1,1,0,0,1,2,61,1,4,3,NA +68746,7,2,2,60,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,3,1,NA,1,2,1,1,2,2,1,2,1,NA,17243.546687,17909.086027,1,92,7,7,2.1,3,3,0,0,2,1,37,2,5,5,NA +68747,7,2,2,10,NA,2,2,1,11,132,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15962.145468,16061.826248,2,98,6,6,0.78,7,7,1,3,1,2,63,1,2,4,NA +68748,7,2,1,70,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,18239.933451,19545.291055,2,102,7,7,1.68,5,5,0,0,3,1,70,2,4,1,4 +68749,7,2,2,21,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,15842.721579,15352.843701,2,99,3,3,0.42,6,6,1,2,0,2,43,1,4,6,NA +68750,7,2,2,16,NA,4,4,2,16,200,NA,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12209.74498,12781.910285,2,90,3,3,0.95,2,2,0,1,0,2,49,1,3,5,NA +68751,7,2,1,39,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,83226.861139,86401.777435,2,95,14,14,5,2,2,0,0,0,1,39,1,4,1,5 +68752,7,2,1,45,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,46745.699003,51362.782618,2,98,8,8,2.26,4,4,0,1,0,2,43,1,3,1,2 +68753,7,2,2,43,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,127315.335607,133282.596235,1,94,15,15,5,3,3,0,1,0,2,43,1,5,1,5 +68754,7,2,1,57,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,143642.364525,143888.596634,1,90,14,14,3.25,4,4,0,0,1,2,77,1,3,3,NA +68755,7,2,2,2,NA,1,1,1,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11512.764389,11879.078775,2,98,2,2,0.35,3,3,2,0,0,2,20,1,4,5,NA +68756,7,2,2,4,NA,1,1,1,4,53,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,10024.946819,10059.178608,2,93,77,77,NA,7,7,3,1,0,2,43,2,1,1,9 +68757,7,2,2,0,2,5,6,2,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9150.459338,9901.313011,1,97,15,15,5,4,4,2,0,0,1,40,2,5,1,5 +68758,7,2,1,78,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,1,2,NA,17703.366452,19320.397271,1,101,4,4,1.22,2,2,0,0,2,2,77,1,3,1,2 +68759,7,1,2,15,NA,2,2,NA,NA,NA,NA,NA,1,1,NA,8,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,15809.066118,0,2,93,3,3,0.63,3,3,0,1,0,1,53,2,2,1,4 +68760,7,2,1,24,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,37326.925742,39362.952436,2,91,6,1,0.31,4,1,0,0,0,1,25,NA,NA,5,NA +68761,7,2,2,4,NA,4,4,2,4,55,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9268.093277,10357.044767,1,99,3,3,0.54,3,3,1,0,0,2,29,1,4,1,4 +68762,7,2,2,34,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,2,1,2,2,1,2,2,NA,NA,NA,NA,60664.751082,63005.627956,1,102,14,14,4.05,3,3,0,2,0,2,34,1,4,3,NA +68763,7,2,1,26,NA,2,2,2,NA,NA,2,NA,2,2,4,NA,2,5,NA,1,2,2,2,2,2,1,2,2,1,35338.972549,37196.45724,2,90,4,4,0.81,3,3,0,0,0,1,39,2,3,5,NA +68764,7,2,1,3,NA,4,4,1,3,37,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9016.053035,9572.619158,2,100,7,7,1.38,5,5,1,0,0,2,45,1,2,3,NA +68765,7,2,1,25,NA,1,1,2,NA,NA,2,NA,2,2,3,NA,4,6,NA,1,2,2,1,2,2,1,2,2,2,41258.226616,42207.135518,2,99,15,1,0.27,2,1,0,0,0,1,31,1,5,6,NA +68766,7,2,1,6,NA,4,4,2,6,77,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10464.577474,10672.635694,1,96,99,99,NA,4,4,1,1,0,2,35,2,3,1,3 +68767,7,2,2,68,NA,4,4,2,NA,NA,2,NA,2,2,3,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,9680.216878,10112.428208,1,96,99,99,NA,2,2,0,0,1,2,68,2,4,5,NA +68768,7,2,2,77,NA,2,2,2,NA,NA,2,NA,2,2,6,NA,1,4,NA,2,2,2,2,2,2,1,2,2,NA,17318.187297,23904.945555,2,90,2,2,0.64,1,1,0,0,1,2,77,2,1,4,NA +68769,7,2,2,56,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,14680.520497,15280.64157,3,91,15,15,5,3,3,0,1,1,2,56,2,5,1,NA +68770,7,2,2,39,NA,1,1,1,NA,NA,2,NA,2,7,77,NA,1,6,2,2,2,2,1,2,2,1,2,1,2,29102.738194,30199.222574,2,103,77,77,NA,7,7,0,4,0,1,38,2,1,6,NA +68771,7,2,2,24,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,23845.8146,23474.128607,1,98,15,15,5,4,4,1,0,0,2,24,1,4,1,NA +68772,7,2,1,80,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,4,3,NA,1,1,2,1,2,2,NA,NA,NA,NA,11289.606124,12205.635507,1,94,8,8,1.39,7,7,2,0,1,2,52,1,5,2,NA +68773,7,2,2,56,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,163102.567998,164787.083347,1,99,9,9,4.35,2,2,0,0,1,1,66,1,2,1,3 +68774,7,2,1,21,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,43104.257334,46015.156479,2,101,5,5,1.36,2,2,0,0,0,2,22,1,4,5,NA +68775,7,2,2,18,NA,5,6,2,18,217,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,6226.949288,6291.898221,2,94,77,77,NA,6,6,2,0,0,2,18,1,3,NA,NA +68776,7,2,1,8,NA,3,3,1,9,109,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,42634.626688,43853.750605,1,102,14,14,4.05,3,3,0,2,0,2,34,1,4,3,NA +68777,7,2,1,17,NA,3,3,2,17,210,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,30100.326038,35344.542616,1,101,6,6,1.31,3,3,0,2,0,1,43,1,3,4,NA +68778,7,2,1,0,8,1,1,1,NA,8,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7284.164858,7692.652584,2,98,4,4,0.65,5,5,3,0,0,2,23,1,4,5,NA +68779,7,2,1,16,NA,1,1,1,16,193,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,27378.670648,27376.262696,2,96,9,9,4.21,2,2,0,1,0,2,50,1,4,4,NA +68780,7,2,1,78,NA,5,6,1,NA,NA,2,NA,2,1,8,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,16632.531676,17822.854094,1,100,10,10,4.63,2,2,0,0,2,1,78,2,5,1,5 +68781,7,2,1,34,NA,5,6,2,NA,NA,2,NA,2,2,2,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,13936.822202,14121.672299,1,93,15,6,2.3,6,1,0,0,0,1,34,2,5,5,NA +68782,7,2,2,0,8,4,4,2,NA,8,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4543.931297,4593.545672,1,96,14,14,3.34,4,4,1,1,0,2,43,1,5,77,NA +68783,7,2,1,22,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,32375.321924,36431.315201,1,101,2,2,0.22,4,4,1,0,0,2,25,1,4,6,NA +68784,7,2,2,18,NA,1,1,2,19,228,2,NA,2,2,3,12,NA,NA,NA,2,2,2,1,2,2,1,2,2,1,16594.391299,17940.930507,3,91,6,6,0.89,7,7,1,1,0,1,59,2,1,1,1 +68785,7,2,1,0,10,4,4,1,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6275.847063,6372.172481,2,100,1,1,0,4,4,2,0,0,2,23,1,4,5,NA +68786,7,2,1,80,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,33707.673642,36318.620408,2,95,15,15,5,2,2,0,0,2,1,80,1,5,1,5 +68787,7,2,1,65,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,149474.480274,150876.348421,1,100,6,6,1.31,3,3,0,0,2,1,65,1,5,1,5 +68788,7,2,1,9,NA,1,1,1,9,113,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13927.458372,14258.502552,1,92,6,6,1.12,4,4,0,2,0,1,20,1,2,1,2 +68789,7,2,1,16,NA,3,3,1,16,196,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,126777.533816,125822.536881,1,100,15,15,5,4,4,0,2,0,1,46,1,5,1,5 +68790,7,2,2,55,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,4,NA,1,2,2,1,2,2,1,2,2,1,38954.135779,38857.944364,1,91,3,3,0.62,3,3,0,1,0,2,55,1,4,4,NA +68791,7,2,2,45,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,19130.246369,18752.254654,2,95,14,14,3.47,4,4,0,0,0,2,45,1,4,1,4 +68792,7,2,2,5,NA,1,1,1,5,70,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15457.736897,16648.051651,2,98,5,5,0.59,7,7,2,1,2,2,71,1,2,1,1 +68793,7,2,1,73,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,68460.271241,72711.227332,1,102,7,7,2.86,2,2,0,0,2,1,73,1,5,1,3 +68794,7,2,1,74,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,87101.243392,92194.745773,1,101,14,14,4.96,2,2,0,0,2,1,74,1,4,1,3 +68795,7,1,2,4,NA,2,2,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13366.393396,0,2,94,7,7,1.18,7,7,1,4,0,2,31,1,4,6,NA +68796,7,2,1,4,NA,2,2,2,4,53,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,14505.510202,15161.207968,2,94,1,1,0.01,7,7,1,3,0,1,41,2,1,1,1 +68797,7,2,1,27,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,17138.242525,20070.705691,1,90,6,6,1.57,3,3,1,0,0,2,25,1,3,6,NA +68798,7,2,1,0,6,1,1,1,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7757.493251,8192.524698,3,92,13,13,NA,6,6,1,2,0,1,53,1,9,1,3 +68799,7,2,1,70,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,NA,46023.826844,48519.015788,1,91,99,99,NA,1,1,0,0,1,1,70,1,2,3,NA +68800,7,2,2,1,22,1,1,1,NA,22,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11512.764389,11552.07657,2,98,7,7,1.26,7,7,1,2,0,1,43,1,2,1,1 +68801,7,2,2,3,NA,4,4,1,3,46,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10295.166918,11223.20055,2,96,12,10,2.17,7,6,2,3,0,1,29,1,4,3,NA +68802,7,2,2,40,NA,4,4,1,NA,NA,2,NA,2,1,4,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,25189.042335,24671.456999,1,100,9,9,2.22,5,5,1,2,0,2,40,2,4,1,4 +68803,7,2,2,21,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,18070.666316,17788.997869,1,99,14,14,4.05,3,3,0,1,0,2,52,1,4,4,NA +68804,7,1,1,31,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,19788.748292,0,1,94,1,1,0.08,7,7,2,4,0,1,31,1,2,1,4 +68805,7,2,1,0,4,3,3,2,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,17113.022485,16817.175522,1,91,15,15,5,3,3,1,0,0,1,36,1,5,1,5 +68806,7,2,2,3,NA,5,6,1,3,40,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8171.700571,8311.029296,1,92,7,7,1.65,4,4,2,0,0,1,24,1,4,1,3 +68807,7,2,2,35,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,15388.376971,15419.798755,2,99,15,15,5,2,2,0,0,0,2,35,1,5,1,5 +68808,7,2,1,58,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,18032.281818,17974.767241,2,99,1,1,0.4,1,1,0,0,0,1,58,1,4,3,NA +68809,7,2,2,2,NA,4,4,2,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7348.24433,7906.792868,2,95,6,6,0.97,6,6,2,1,0,1,54,1,3,6,NA +68810,7,2,1,80,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,NA,12291.154515,13189.875012,1,95,2,2,0.66,1,1,0,0,1,1,80,1,3,5,NA +68811,7,2,1,0,7,1,1,1,NA,8,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6999.189812,6930.018579,3,92,12,12,NA,7,7,2,1,0,2,30,1,2,1,9 +68812,7,2,1,42,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,19184.316833,19115.012147,1,97,15,15,2.33,7,7,2,4,0,2,40,2,5,1,4 +68813,7,2,2,24,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,2,1,2,2,1,2,2,1,2,2,1,52701.331723,59294.433957,3,91,3,3,0.73,3,3,1,0,0,2,24,1,2,1,3 +68814,7,2,1,32,NA,4,4,2,NA,NA,2,NA,2,1,3,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,20133.630718,20200.188991,1,93,6,6,1.35,3,3,0,1,0,1,32,2,4,1,4 +68815,7,2,2,10,NA,5,6,2,10,123,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6412.057856,6879.064185,3,91,8,8,2.81,3,3,0,2,0,2,31,1,4,3,NA +68816,7,2,2,58,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,21097.069797,24201.517172,2,90,2,2,0.83,1,1,0,0,0,2,58,1,3,3,NA +68817,7,2,1,32,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,18353.275855,20231.959782,1,91,12,8,2.15,6,4,1,1,0,2,29,1,4,6,NA +68818,7,2,1,62,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,7410.50521,7700.344649,2,96,6,6,2.75,1,1,0,0,1,1,62,1,3,3,NA +68819,7,2,1,47,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,52941.648658,53777.896935,2,102,77,77,NA,4,4,0,1,0,1,47,1,2,1,3 +68820,7,2,2,2,NA,2,2,1,2,31,NA,NA,2,1,2,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,10164.721409,11222.125211,2,93,5,5,0.87,4,4,1,1,0,1,41,2,5,1,3 +68821,7,2,1,2,NA,4,4,1,2,29,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9438.902193,9727.203655,2,102,4,4,0.72,4,4,2,0,0,1,48,1,3,1,3 +68822,7,2,1,3,NA,2,2,2,3,45,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,15745.774489,16244.197679,2,91,4,4,0.67,5,4,2,0,2,2,66,2,1,1,NA +68823,7,2,1,64,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,7897.700656,8206.595267,2,95,7,7,2.31,2,2,0,0,2,2,63,1,3,1,3 +68824,7,2,2,80,NA,2,2,2,NA,NA,1,2,2,1,9,NA,2,1,NA,2,1,2,1,2,2,1,1,2,NA,18824.116627,20613.042179,2,90,6,6,2.24,2,2,0,0,2,1,75,2,4,1,2 +68825,7,2,1,51,NA,5,6,1,NA,NA,2,NA,2,2,6,NA,1,4,NA,1,2,1,1,2,1,1,2,2,3,16590.074977,17628.593761,1,92,2,2,0.33,5,5,0,1,0,1,51,2,1,4,NA +68826,7,2,1,7,NA,4,4,2,7,92,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10409.90361,10390.331705,1,96,3,2,0.16,7,6,1,4,0,2,32,1,2,5,NA +68827,7,2,1,43,NA,5,6,2,NA,NA,2,NA,2,1,4,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,17046.256569,17889.989739,1,96,9,9,4.1,2,2,0,0,0,2,45,2,5,1,5 +68828,7,2,1,24,NA,5,6,2,NA,NA,2,NA,2,1,99,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,10141.381563,10448.082757,3,90,15,15,5,3,3,0,0,0,1,46,2,3,1,3 +68829,7,2,2,0,6,2,2,1,NA,7,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7446.889459,7422.354625,2,96,6,6,1.12,4,4,2,0,0,1,27,2,2,6,NA +68830,7,2,2,39,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,13027.332011,13103.987136,2,103,77,77,NA,5,5,0,2,0,2,39,2,5,1,5 +68831,7,2,2,79,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,16612.938931,17191.011953,2,99,14,14,4.96,2,2,0,0,2,2,79,1,5,1,NA +68832,7,2,1,15,NA,5,6,2,15,189,NA,NA,2,2,2,8,NA,NA,NA,1,1,1,1,2,1,1,2,1,NA,6666.045669,7091.184391,3,90,6,6,1.31,3,3,0,1,0,1,49,2,3,1,4 +68833,7,2,1,41,NA,2,2,2,NA,NA,2,NA,77,NA,NA,NA,3,5,NA,2,2,2,2,2,2,2,2,1,2,25035.846455,25142.418345,2,99,99,4,1.61,5,1,0,1,0,1,40,2,1,6,NA +68834,7,2,1,7,NA,4,4,2,7,93,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14832.155253,15089.454697,1,97,15,15,5,4,4,1,1,0,1,35,1,5,1,5 +68835,7,1,1,49,NA,2,2,NA,NA,NA,2,NA,2,1,77,NA,1,6,NA,2,2,2,1,2,2,NA,NA,NA,NA,39096.402803,0,2,91,1,1,0.17,4,4,0,1,0,1,49,2,1,6,NA +68836,7,2,1,60,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,4299.99963,4413.31452,3,90,15,15,4.2,6,6,1,0,2,1,60,1,5,1,4 +68837,7,2,2,35,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,4,2,1,2,2,1,2,2,1,2,2,1,22326.231285,22166.696692,1,99,10,10,2.07,7,7,2,3,1,2,35,1,5,4,NA +68838,7,2,2,7,NA,1,1,1,7,93,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,12789.411811,13121.359297,1,102,2,2,0.52,3,3,0,2,0,2,36,2,3,4,NA +68839,7,2,1,80,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,44041.763669,47615.276255,1,92,10,10,3.67,3,3,0,0,2,1,52,1,4,77,NA +68840,7,2,1,31,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,19117.284298,19018.955883,2,95,7,7,2.58,2,2,0,0,0,2,57,1,4,3,NA +68841,7,2,1,49,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,21158.364877,21090.879552,1,96,7,7,2.75,2,2,0,0,0,1,49,1,4,1,5 +68842,7,2,2,43,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,3,2,1,2,2,1,2,2,1,2,2,1,29670.405171,29530.485322,2,95,4,4,0.76,4,4,0,1,2,1,80,1,1,2,NA +68843,7,2,1,52,NA,1,1,2,NA,NA,2,NA,2,2,2,NA,1,1,NA,2,2,2,1,2,2,2,2,2,2,22446.308035,24663.335125,2,94,4,2,0.54,4,2,0,0,0,1,46,NA,NA,1,NA +68844,7,2,1,8,NA,3,3,1,8,100,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,85148.03778,90558.20429,1,98,7,7,1.48,5,5,1,1,0,1,46,1,3,1,3 +68845,7,2,2,75,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,36067.495928,37024.300659,1,95,3,3,1.1,1,1,0,0,1,2,75,1,3,2,NA +68846,7,2,2,49,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,23742.825358,24088.979786,1,100,15,15,5,2,2,0,0,0,1,48,2,5,1,5 +68847,7,2,1,21,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,2,2,2,1,2,2,1,59682.963348,63262.110969,2,102,9,9,3.24,3,3,0,0,0,1,54,2,4,1,4 +68848,7,2,2,4,NA,3,3,2,4,49,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,20589.729566,21881.111334,1,97,6,6,1.03,6,6,2,2,0,2,38,1,5,1,4 +68849,7,2,1,5,NA,4,4,1,5,66,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10040.033098,10346.695479,1,100,3,3,0.52,3,3,1,1,0,2,25,1,3,5,NA +68850,7,2,1,27,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,52698.05363,59566.360508,3,92,7,7,1.65,4,4,1,1,0,1,27,1,3,1,3 +68851,7,2,2,13,NA,1,1,1,13,157,NA,NA,1,1,NA,6,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,18515.058419,19360.671834,2,96,6,6,0.87,6,6,1,3,0,1,46,2,1,1,1 +68852,7,2,1,7,NA,5,6,2,7,92,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9720.482616,10533.307174,2,91,7,7,1.56,4,4,1,1,0,2,37,2,5,1,5 +68853,7,2,2,37,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,27428.65319,29015.297283,2,91,2,2,0.26,4,4,0,1,0,1,20,1,3,5,NA +68854,7,2,1,65,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,1,5,NA,1,2,2,1,2,2,1,2,2,NA,10037.214229,10115.728475,2,92,6,6,2.31,2,2,0,0,2,2,65,1,4,5,NA +68855,7,2,1,70,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,71070.181743,73766.510327,1,95,6,6,1.94,2,2,0,0,2,2,69,1,2,1,4 +68856,7,2,2,14,NA,5,7,1,14,175,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15711.746539,15750.442176,1,98,14,14,3.16,6,6,2,2,0,1,39,1,5,1,5 +68857,7,2,2,12,NA,3,3,2,12,151,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,91797.787708,92992.465808,1,95,14,14,3.8,4,4,0,2,0,2,37,1,5,1,5 +68858,7,2,2,12,NA,2,2,2,12,148,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14437.97544,15197.369043,2,90,8,8,2.24,4,4,1,1,0,2,29,1,4,6,NA +68859,7,2,2,39,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,85444.349063,86035.699897,1,94,14,14,2.96,5,5,0,3,0,2,39,1,4,1,3 +68860,7,2,1,34,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,22188.836739,23248.471636,1,95,7,7,1.66,5,5,0,3,0,1,34,1,2,1,4 +68861,7,2,1,8,NA,1,1,1,8,100,NA,NA,1,1,NA,2,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,11159.151566,11057.808004,1,102,2,2,0.31,4,4,1,2,0,2,25,1,2,4,NA +68862,7,2,1,3,NA,5,7,2,3,40,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8269.653573,9275.321266,1,101,4,4,0.78,4,4,1,2,0,2,31,1,4,3,NA +68863,7,2,1,4,NA,5,6,2,4,50,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6319.053383,6623.952114,1,91,6,6,1.25,4,4,1,1,0,1,26,2,4,6,NA +68864,7,2,2,57,NA,2,2,2,NA,NA,2,NA,2,1,6,NA,1,1,NA,2,2,2,1,2,2,2,2,1,2,29695.385784,37858.742479,2,91,3,3,0.66,2,2,0,0,1,1,69,2,5,1,1 +68865,7,2,1,62,NA,4,4,2,NA,NA,2,NA,2,2,2,NA,4,1,NA,1,2,2,1,2,1,1,2,2,1,8460.109732,8526.287371,1,93,5,5,0.64,7,7,0,2,1,1,21,2,4,5,NA +68866,7,2,1,22,NA,2,2,2,NA,NA,2,NA,2,1,2,NA,4,6,NA,2,2,2,2,2,2,NA,NA,NA,NA,31312.870743,31739.689334,2,90,6,6,0.66,7,7,2,2,0,2,24,2,4,6,NA +68867,7,2,1,12,NA,3,3,1,12,151,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,79897.505873,82468.209663,2,100,6,6,1.7,3,3,0,1,0,2,33,1,4,6,NA +68868,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,47157.788417,52669.767304,2,95,10,10,4.3,2,2,0,0,2,1,80,1,5,1,4 +68869,7,2,2,54,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,156728.884529,156630.502182,1,100,15,15,5,3,3,0,0,0,1,53,1,5,1,4 +68870,7,2,2,0,10,4,4,2,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4581.358327,4631.381361,2,97,5,5,1.3,3,3,1,0,0,2,46,1,3,1,3 +68871,7,2,1,37,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,83239.679734,92023.913528,1,90,15,15,5,4,4,0,2,0,1,37,1,5,1,5 +68872,7,2,1,34,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,39040.678458,40784.183756,2,98,2,2,0.35,3,3,0,1,0,2,43,1,3,1,3 +68873,7,2,2,24,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,16131.725974,16820.579069,1,99,2,2,0.66,2,1,0,0,0,2,24,1,5,5,NA +68874,7,2,1,55,NA,2,2,2,NA,NA,2,NA,2,2,8,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,32634.009061,33534.701149,2,91,10,10,4.63,2,2,0,0,0,1,55,2,3,3,NA +68875,7,2,1,52,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,174520.785302,181786.280703,1,95,7,7,2.86,2,2,0,0,0,2,50,1,3,1,3 +68876,7,2,2,78,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,81416.374938,89993.518978,1,97,15,15,5,2,2,0,0,2,1,78,1,3,1,3 +68877,7,2,1,48,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,18533.049642,19387.053587,1,99,14,14,3.67,4,4,1,0,0,2,49,1,3,1,3 +68878,7,2,1,2,NA,2,2,2,2,27,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,10803.555682,10625.559962,2,94,1,1,0.16,2,2,1,0,0,2,25,2,3,1,NA +68879,7,2,1,2,NA,3,3,1,2,26,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,21718.301271,24669.801903,3,91,6,6,1,6,6,1,1,0,2,39,1,1,3,NA +68880,7,2,1,15,NA,5,7,1,15,184,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,59545.101745,58762.542429,1,102,8,8,1.6,7,7,0,4,0,2,39,1,4,1,4 +68881,7,2,2,35,NA,3,3,2,NA,NA,2,NA,2,1,1,NA,2,1,2,1,2,1,1,2,1,NA,NA,NA,NA,19498.713386,20960.418705,2,97,5,5,0.8,5,5,1,2,0,1,46,2,4,1,2 +68882,7,2,2,48,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,16313.554006,16926.636803,1,103,8,8,1.95,4,4,0,1,0,2,48,1,5,1,5 +68883,7,1,1,53,NA,2,2,NA,NA,NA,2,NA,2,2,7,NA,2,1,NA,2,2,2,1,2,2,NA,NA,NA,NA,23431.677775,0,2,93,3,3,0.63,3,3,0,1,0,1,53,2,2,1,4 +68884,7,2,2,54,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,24905.670199,26841.707501,2,101,3,3,0.65,3,3,0,1,0,2,54,1,3,5,NA +68885,7,2,2,11,NA,1,1,1,11,141,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12481.057866,12612.274737,1,102,4,4,0.61,5,5,2,2,0,2,27,2,2,5,NA +68886,7,2,2,44,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,83441.642088,87352.545854,1,99,15,15,5,4,4,0,2,0,2,44,1,5,1,5 +68887,7,2,1,1,19,1,1,1,NA,20,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12493.910388,13386.323284,3,92,3,3,0.54,4,4,3,0,0,2,22,1,3,5,NA +68888,7,2,1,74,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,NA,9257.537917,9255.717695,1,99,9,9,5,2,1,0,0,2,2,61,1,4,6,NA +68889,7,2,2,3,NA,4,4,2,3,41,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8674.686381,9059.886471,2,99,77,77,NA,4,4,1,1,0,2,47,1,2,77,NA +68890,7,2,2,8,NA,1,1,1,8,101,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,22618.378147,23255.85994,2,102,5,5,0.89,4,4,1,1,0,2,28,2,2,1,2 +68891,7,2,2,3,NA,1,1,1,3,40,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,15308.9293,16274.054403,2,98,4,4,0.48,6,6,2,0,2,2,65,2,1,2,NA +68892,7,2,1,75,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,8431.365248,9201.488687,1,96,10,10,3.04,4,4,0,0,2,1,56,1,3,3,NA +68893,7,2,1,15,NA,4,4,2,15,188,NA,NA,1,1,NA,11,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11023.237662,11433.168046,1,99,15,15,5,4,4,0,2,0,2,46,1,5,1,5 +68894,7,2,1,36,NA,5,7,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,65033.706797,66896.305599,1,102,8,8,1.6,7,7,0,4,0,2,39,1,4,1,4 +68895,7,2,2,74,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,12813.709202,13258.116643,2,103,14,14,3.47,4,4,1,0,1,1,47,2,5,1,5 +68896,7,2,1,4,NA,4,4,2,4,49,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8402.233801,8749.415211,2,97,3,3,0.4,6,6,2,3,0,2,25,1,2,5,NA +68897,7,2,2,1,15,5,6,2,NA,15,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6184.163292,6116.466669,1,91,15,15,3.25,7,7,1,2,0,2,31,1,5,1,5 +68898,7,2,1,3,NA,2,2,2,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,13891.873932,13527.718832,2,97,12,6,0.89,7,7,3,0,0,2,26,2,1,6,NA +68899,7,2,1,48,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,18790.641284,22550.069226,2,100,14,14,5,7,1,1,3,1,2,62,1,3,5,NA +68900,7,2,1,7,NA,3,3,2,7,93,NA,NA,2,2,2,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,49047.972936,54301.226542,1,93,10,10,2.48,5,5,2,1,0,1,40,2,5,1,5 +68901,7,2,2,47,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,112011.120236,112121.110185,2,92,15,15,5,2,1,0,0,0,1,52,1,5,6,NA +68902,7,2,2,78,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,12493.113557,12927.830854,2,99,77,77,NA,1,1,0,0,1,2,78,1,4,2,NA +68903,7,1,2,75,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,89167.746947,0,1,95,5,5,1.43,2,2,0,0,2,1,80,1,3,1,4 +68904,7,2,1,6,NA,4,4,2,6,73,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7758.863533,8127.805304,2,99,3,3,0.42,6,6,1,2,0,2,43,1,4,6,NA +68905,7,2,2,1,21,4,4,2,NA,21,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7618.827213,7815.48207,2,97,6,6,1.7,2,2,1,0,0,2,20,1,4,5,NA +68906,7,2,2,16,NA,1,1,2,16,195,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,2,2,2,1,2,2,1,12680.621719,13347.583861,2,90,6,6,1.15,5,5,0,2,0,2,47,2,1,1,5 +68907,7,2,2,26,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,3,1,2,2,1,2,2,1,2,2,1,119412.590109,122441.098321,1,92,6,6,1.62,3,3,1,0,0,2,26,1,5,1,5 +68908,7,2,2,59,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,15521.115746,16727.646581,2,100,9,9,2.46,4,4,1,1,1,2,59,1,3,1,3 +68909,7,2,1,16,NA,4,4,2,16,202,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13416.172328,13513.882801,1,96,15,15,5,4,4,1,1,0,1,50,1,3,1,4 +68910,7,2,1,74,NA,2,2,1,NA,NA,2,NA,2,1,8,NA,2,1,NA,2,2,2,1,2,2,1,2,2,NA,17419.161186,17783.358691,1,102,7,7,1.7,4,4,0,0,2,1,44,1,4,4,NA +68911,7,2,1,13,NA,4,4,1,13,164,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17606.165994,17558.40257,2,95,4,4,0.76,4,4,0,1,2,1,80,1,1,2,NA +68912,7,2,2,80,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,1,2,NA,1,1,2,1,2,2,1,2,1,NA,9509.326077,9839.130289,3,91,14,14,2.5,6,6,1,1,1,2,37,2,2,1,5 +68913,7,2,2,27,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,2,1,2,2,1,2,2,NA,NA,NA,NA,17260.508485,17587.688781,2,101,1,1,0.1,6,6,1,2,1,2,27,1,2,1,2 +68914,7,2,2,52,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,38093.351998,47908.278929,2,91,4,4,1.19,2,2,0,0,0,1,59,1,1,1,3 +68915,7,2,2,48,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,80418.665565,83274.564983,2,100,8,8,2.91,3,3,0,2,0,2,48,1,5,1,NA +68916,7,2,1,56,NA,1,1,1,NA,NA,2,NA,2,2,2,NA,1,1,NA,2,2,2,1,2,2,2,2,2,2,37426.314738,38162.090079,3,92,5,5,1.39,2,2,0,0,0,1,56,2,1,1,1 +68917,7,2,1,33,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,65331.560138,67202.689613,1,91,14,14,2.44,7,7,2,4,0,1,33,1,5,1,5 +68918,7,2,1,55,NA,1,1,2,NA,NA,2,NA,2,2,2,NA,1,5,NA,2,2,2,2,2,2,2,2,2,2,22446.308035,22401.210337,2,94,77,77,NA,4,4,0,0,0,1,28,2,1,3,NA +68919,7,2,2,37,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,71034.153987,71525.773464,1,98,7,7,1.66,5,5,2,1,0,2,37,1,5,1,3 +68920,7,2,2,48,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,17805.920521,18110.342663,2,93,12,12,NA,4,4,0,0,2,1,72,1,2,1,4 +68921,7,2,2,8,NA,3,3,1,8,96,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,45129.675368,44994.093254,1,98,10,10,2.2,6,6,1,3,0,2,31,1,4,6,NA +68922,7,2,2,74,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,88916.414931,91644.282892,1,101,14,14,4.96,2,2,0,0,2,1,74,1,4,1,3 +68923,7,2,1,13,NA,5,6,2,13,157,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11506.937395,12032.024805,1,97,7,7,1.48,5,5,0,1,0,2,46,2,4,1,NA +68924,7,2,1,20,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,104488.914565,106745.836574,1,98,4,1,0.18,4,1,0,0,0,1,22,1,5,5,NA +68925,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,8286.407536,8892.303775,1,91,3,3,0.98,1,1,0,0,1,1,80,1,3,2,NA +68926,7,2,2,3,NA,5,6,1,3,47,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6537.38756,6940.023785,1,92,12,12,NA,7,7,1,2,1,2,45,2,3,1,3 +68927,7,2,1,11,NA,4,4,2,11,137,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10669.652248,10854.743056,2,97,5,5,0.76,5,5,1,2,0,1,32,1,4,6,NA +68928,7,2,1,41,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,19260.892847,19291.900704,2,97,13,13,NA,1,1,0,0,0,1,41,1,2,5,NA +68929,7,2,2,19,NA,2,2,2,19,235,2,NA,2,7,77,13,NA,NA,NA,2,2,2,2,2,2,2,2,1,2,23968.380373,25913.276293,2,91,4,4,0.43,7,7,0,1,1,1,41,2,1,4,NA +68930,7,2,2,6,NA,4,4,1,6,75,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8031.102104,8647.40073,2,100,14,4,0.43,7,7,1,3,1,2,62,1,3,5,NA +68931,7,2,1,22,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,14424.961621,15273.975784,2,102,8,8,2.01,4,4,0,0,0,1,59,2,4,1,4 +68932,7,2,1,4,NA,4,4,1,4,54,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10040.033098,11070.778245,1,100,8,8,2.36,3,3,1,0,0,2,37,1,3,4,NA +68933,7,2,1,72,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,8517.336599,8684.171961,2,100,14,14,5,2,2,0,0,2,2,63,1,5,1,4 +68934,7,2,2,47,NA,1,1,1,NA,NA,2,NA,2,2,5,NA,1,4,NA,2,2,2,2,2,2,1,2,1,2,35815.777398,36002.553631,1,94,2,2,0.27,5,5,0,4,0,2,47,2,1,4,NA +68935,7,2,1,46,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,3,1,NA,2,2,2,2,2,2,2,2,2,2,31233.526521,31366.480522,1,100,8,4,1.43,6,1,1,0,0,1,33,2,3,6,NA +68936,7,2,2,36,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,26465.930618,28724.649216,2,100,4,4,0.86,3,3,0,2,0,2,36,1,3,5,NA +68937,7,2,1,31,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,19185.622388,22768.505116,2,95,15,10,3.67,5,3,0,0,0,1,47,1,5,1,3 +68938,7,2,1,9,NA,1,1,2,9,109,NA,NA,1,1,NA,3,NA,NA,NA,2,1,2,1,2,2,1,2,2,NA,11316.846999,12445.832216,3,91,4,4,1.02,2,2,0,1,0,2,24,2,1,5,NA +68939,7,2,1,7,NA,1,1,1,7,91,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,14820.807433,14905.891142,2,102,8,8,1.91,5,5,1,2,0,1,36,2,1,1,4 +68940,7,2,2,2,NA,2,2,2,2,27,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11981.824297,12363.063282,2,91,2,2,0.22,4,4,1,1,0,2,48,2,9,5,NA +68941,7,2,1,0,10,4,4,2,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6780.545196,6884.61702,1,96,14,14,3.47,4,4,1,1,0,2,27,1,3,6,NA +68942,7,2,2,14,NA,4,4,1,15,180,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12531.903464,12935.738352,2,100,5,5,1.08,3,3,0,1,0,2,50,1,4,3,NA +68943,7,2,2,0,2,4,4,2,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4099.350341,4144.110416,2,99,7,7,1.74,4,4,2,0,0,2,56,1,2,5,NA +68944,7,2,2,79,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,NA,20341.088581,21872.034752,1,93,2,2,0.64,1,1,0,0,1,2,79,1,4,3,NA +68945,7,2,2,27,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,17568.277926,19062.73336,1,90,2,2,0.56,2,2,1,0,0,2,27,1,3,5,NA +68946,7,2,2,64,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,82743.954233,85642.054874,2,91,15,15,4.2,6,6,2,0,2,1,63,1,1,1,3 +68947,7,2,2,65,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,1,10033.449917,10806.84762,2,95,13,13,NA,2,2,0,0,2,2,80,1,1,1,NA +68948,7,2,2,36,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,86578.861495,89037.775585,2,101,7,7,1.88,4,4,0,2,0,2,36,1,4,1,5 +68949,7,2,1,63,NA,1,1,2,NA,NA,2,NA,2,2,6,NA,1,1,NA,2,2,2,1,2,2,NA,NA,NA,NA,9145.939054,9651.644596,1,101,5,5,0.87,4,4,0,0,2,1,63,2,1,1,NA +68950,7,2,2,38,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,6,2,1,2,2,1,2,2,1,2,2,1,39561.667842,38494.210933,2,98,7,7,1.33,6,6,0,3,0,1,31,1,3,6,NA +68951,7,2,1,4,NA,1,1,1,4,57,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16775.083123,16973.400581,3,92,4,4,0.6,6,6,2,2,0,2,24,1,3,6,NA +68952,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,56397.521122,64147.609457,2,91,7,7,2.51,2,2,0,0,1,2,80,1,5,2,NA +68953,7,2,2,32,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,2,1,2,2,1,2,2,1,2,2,1,24919.497762,27697.191423,1,101,4,4,0.78,4,4,1,2,0,2,32,1,3,3,NA +68954,7,2,2,1,22,4,4,1,NA,22,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10927.526143,11412.763748,2,102,2,2,0.36,4,4,1,2,0,2,36,1,3,5,NA +68955,7,2,1,59,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,32720.69734,32680.7991,1,95,15,15,3.62,7,7,2,4,0,1,59,1,5,1,2 +68956,7,2,2,14,NA,3,3,1,14,177,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,28004.718304,30534.517049,1,94,7,7,1.21,6,6,2,2,0,1,31,1,2,6,NA +68957,7,2,1,12,NA,4,4,2,13,156,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11351.725436,11256.943498,2,95,6,6,1.85,2,2,0,1,0,2,48,1,4,5,NA +68958,7,2,1,12,NA,1,1,1,12,155,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,30061.88611,32302.400867,1,92,10,10,3.04,4,4,1,1,0,1,32,1,3,1,2 +68959,7,2,2,43,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,17777.254625,18901.462969,2,99,NA,77,NA,3,1,0,0,1,1,63,1,3,5,NA +68960,7,2,2,10,NA,2,2,1,10,128,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,2,2,2,1,2,2,1,15897.166957,16345.216522,2,102,4,4,0.57,6,6,2,3,0,2,26,2,3,1,NA +68961,7,2,2,64,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,117419.769432,119338.215671,2,95,15,15,5,2,2,0,0,2,1,70,1,5,1,5 +68962,7,2,1,14,NA,5,6,2,14,177,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11506.937395,12032.024805,1,97,15,15,5,3,3,0,1,0,2,45,2,5,1,5 +68963,7,2,2,2,NA,4,4,2,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6306.491784,7047.470907,2,90,6,6,1.34,4,4,1,0,0,1,38,2,4,6,NA +68964,7,2,1,20,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,19130.866571,19325.235628,2,99,6,6,2.95,1,1,0,0,0,1,20,1,3,5,NA +68965,7,2,2,2,NA,3,3,1,2,26,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,20820.221848,22126.060024,1,101,5,5,0.89,5,5,1,0,0,1,25,1,2,77,NA +68966,7,2,2,63,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,11696.973403,11982.125462,2,97,1,1,0,2,2,0,0,1,2,63,1,4,5,NA +68967,7,2,1,20,NA,4,4,1,NA,NA,2,NA,2,1,5,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,25815.880139,26503.609729,2,101,3,1,0,2,1,0,0,0,1,20,2,4,5,NA +68968,7,2,1,12,NA,1,1,1,12,151,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,22768.423624,22944.003607,3,92,4,4,0.81,3,3,0,2,0,2,31,1,3,1,NA +68969,7,2,1,0,1,1,1,2,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7040.676479,6971.095244,1,98,9,1,0.04,7,1,3,2,0,2,32,1,4,1,4 +68970,7,2,1,11,NA,1,1,2,11,136,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13285.093011,13153.997889,2,94,7,7,1.88,4,4,0,2,0,2,28,1,4,4,NA +68971,7,2,2,21,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,3,6,2,1,2,2,1,2,2,1,2,2,1,42583.505439,50840.190326,2,91,4,4,0.69,4,4,2,0,0,2,21,1,3,6,NA +68972,7,2,2,60,NA,2,2,2,NA,NA,2,NA,2,2,3,NA,1,1,NA,2,2,2,1,2,2,2,2,2,2,11771.283932,12488.02543,1,90,9,9,2.07,5,5,0,0,1,1,46,2,4,1,3 +68973,7,2,1,2,NA,4,4,2,2,32,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6837.992772,6921.398172,1,96,15,15,4.34,4,4,1,1,0,1,39,2,5,1,5 +68974,7,2,1,10,NA,4,4,1,10,123,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10311.165779,10434.780551,2,98,8,8,2.43,3,3,0,2,0,2,31,1,4,1,NA +68975,7,2,2,3,NA,3,3,1,3,38,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,85197.465687,87881.529962,1,92,15,15,5,4,4,2,0,0,2,46,1,5,1,5 +68976,7,2,1,44,NA,5,7,2,NA,NA,2,NA,2,2,3,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,12254.763576,12210.492386,2,90,3,3,0.65,5,3,1,2,0,1,44,2,5,1,5 +68977,7,2,1,80,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,1,2,1,2,2,1,2,2,NA,13251.84987,13511.423639,2,95,4,4,0.76,4,4,0,1,2,1,80,1,1,2,NA +68978,7,2,1,39,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,113559.363135,120841.424294,2,102,15,15,5,4,4,0,2,0,1,39,1,4,1,5 +68979,7,2,2,36,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,71034.153987,74518.988514,1,98,14,14,4.12,4,4,0,2,0,2,36,1,5,1,3 +68980,7,2,1,20,NA,1,1,2,NA,NA,2,NA,2,2,4,NA,2,1,NA,2,2,2,2,2,2,1,2,2,1,35669.2076,36620.108921,2,94,77,77,NA,4,4,0,0,0,1,28,2,1,3,NA +68981,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,NA,40870.323556,45647.400007,2,99,15,15,5,1,1,0,0,1,2,80,1,5,3,NA +68982,7,2,2,27,NA,5,6,2,NA,NA,2,NA,2,2,4,NA,3,1,1,1,2,2,1,2,2,1,2,2,1,17858.942687,18621.550977,1,97,15,15,4.84,6,6,2,0,0,1,53,NA,NA,1,NA +68983,7,2,1,67,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,11568.876339,11794.347884,1,102,6,6,2.75,1,1,0,0,1,1,67,1,5,3,NA +68984,7,2,2,0,9,3,3,1,NA,10,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,21671.775435,21083.121886,1,101,9,9,2.39,4,4,1,0,0,2,57,1,2,77,NA +68985,7,2,2,16,NA,4,4,1,16,201,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13895.342981,13964.270792,2,102,5,5,0.67,6,6,0,4,0,2,33,1,2,6,NA +68986,7,2,2,18,NA,4,4,2,19,228,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,18163.985724,21329.621847,2,101,12,12,NA,4,4,0,0,0,1,57,1,3,1,3 +68987,7,2,1,9,NA,2,2,2,9,109,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15882.795076,15889.831109,1,97,3,3,0.44,5,5,2,2,0,2,26,1,4,4,NA +68988,7,2,1,72,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,1,4,NA,1,2,2,1,2,2,1,2,2,NA,8497.912951,8999.288803,2,100,2,2,0.73,1,1,0,0,1,1,72,1,1,4,NA +68989,7,2,1,34,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,13601.994691,14463.629992,2,100,9,9,2.46,4,4,0,2,0,2,36,2,4,1,3 +68990,7,2,1,53,NA,1,1,2,NA,NA,2,NA,2,1,7,NA,1,1,NA,2,2,2,2,2,2,2,2,2,2,22446.308035,22116.943066,2,91,10,10,2.95,4,4,0,1,0,2,18,1,3,NA,NA +68991,7,2,1,40,NA,2,2,2,NA,NA,2,NA,2,2,6,NA,2,1,NA,2,2,2,2,2,2,1,2,2,2,34152.149953,40351.498105,1,90,5,5,1,4,4,0,2,0,1,40,2,2,1,1 +68992,7,2,2,53,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,17533.239798,17053.396696,2,99,3,3,0.44,5,5,1,1,0,2,53,1,4,1,3 +68993,7,2,2,34,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,19005.010125,19043.816772,1,92,2,2,0.24,5,5,0,2,0,1,35,2,4,1,3 +68994,7,2,1,19,NA,3,3,1,19,233,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,74191.50646,74370.660378,1,98,8,8,2.62,3,3,0,0,0,1,50,NA,NA,3,NA +68995,7,2,1,75,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,60942.568495,64726.722108,1,94,14,14,5,2,2,0,0,2,2,72,1,5,1,5 +68996,7,2,1,24,NA,5,6,1,NA,NA,2,NA,2,2,1,NA,4,5,NA,1,2,2,1,2,2,1,2,2,NA,14385.653726,15564.966804,2,101,7,5,1.84,2,1,0,0,0,1,23,2,4,5,NA +68997,7,2,1,7,NA,2,2,1,7,88,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,13599.766245,14493.354345,2,93,3,3,0.48,4,4,1,1,0,1,49,2,3,1,4 +68998,7,2,2,43,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,15206.604563,15895.992431,2,90,15,15,5,4,4,1,1,0,1,53,2,5,1,5 +68999,7,2,1,2,NA,4,4,1,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8022.100831,8353.575096,2,102,4,4,0.53,6,6,2,2,0,2,27,1,2,1,2 +69000,7,2,1,13,NA,3,3,2,13,163,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,26824.630008,26472.092796,1,95,1,1,0.12,3,3,0,2,0,2,40,1,5,3,NA +69001,7,2,1,68,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,6038.685119,6274.869975,1,96,6,6,1.57,3,3,0,0,1,1,42,1,3,NA,NA +69002,7,2,1,8,NA,1,1,1,8,106,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13927.458372,14007.413517,2,98,15,15,4.97,5,5,0,3,0,1,39,1,5,1,5 +69003,7,2,1,7,NA,2,2,2,7,88,NA,NA,2,2,3,0,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,9390.522479,10327.334743,2,90,2,2,0.32,4,4,1,2,0,2,34,2,1,77,NA +69004,7,2,1,16,NA,1,1,2,16,200,NA,NA,1,1,NA,9,NA,NA,NA,2,2,2,2,2,2,1,2,2,1,18120.499457,19917.650851,1,90,1,1,0.02,5,5,0,1,0,2,39,2,1,1,2 +69005,7,2,2,77,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,60723.387753,62586.321432,1,96,14,14,5,2,2,0,0,2,1,74,1,5,1,4 +69006,7,2,2,38,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,2,1,2,2,1,2,2,NA,NA,NA,NA,95214.22557,95506.977757,1,97,15,15,3.89,5,5,0,2,0,1,50,1,4,6,NA +69007,7,2,1,55,NA,2,2,1,NA,NA,2,NA,2,2,3,NA,2,4,NA,2,2,2,NA,NA,NA,2,2,1,2,24211.824535,26078.926124,2,93,3,3,0.43,4,4,0,0,0,1,45,2,2,6,NA +69008,7,1,2,65,NA,2,2,NA,NA,NA,2,NA,2,1,8,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,9325.158469,0,1,93,15,15,5,2,2,0,0,2,2,65,2,4,1,5 +69009,7,2,1,56,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,18416.819037,18519.889723,2,96,8,8,3.67,2,2,0,0,0,1,56,2,5,1,5 +69010,7,2,2,80,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,NA,13799.782578,14328.748539,2,103,7,7,1.48,5,5,0,1,1,2,80,1,4,3,NA +69011,7,2,2,59,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,170311.62251,172039.874492,1,94,15,15,5,4,3,0,0,1,1,33,1,2,5,NA +69012,7,2,1,1,14,2,2,2,NA,14,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8331.647763,8430.145707,2,90,8,8,1.72,5,5,1,2,0,1,20,2,1,1,2 +69013,7,2,1,35,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,18876.596264,19790.278241,1,101,3,3,0.44,5,5,0,3,0,1,35,1,3,1,4 +69014,7,2,1,78,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,60942.568495,64726.722108,1,91,10,10,4.3,2,2,0,0,2,1,78,1,4,1,4 +69015,7,2,1,0,1,2,2,1,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,7328.080818,7255.659238,2,102,15,15,2.43,7,7,3,2,0,1,28,2,5,1,4 +69016,7,2,2,13,NA,4,4,1,13,159,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14166.687432,14745.171396,1,100,1,1,0,4,4,1,2,0,2,35,1,2,5,NA +69017,7,2,1,58,NA,4,4,2,NA,NA,2,NA,2,2,7,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,16695.743237,21107.492082,3,90,12,12,NA,2,2,0,0,0,2,56,2,4,1,5 +69018,7,2,1,39,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,16058.989596,16964.610342,2,97,2,2,0.21,7,7,2,3,0,2,32,1,4,5,NA +69019,7,2,2,44,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,138322.767578,151356.795097,1,101,13,13,NA,2,2,0,0,0,1,40,1,2,1,3 +69020,7,2,1,42,NA,1,1,1,NA,NA,2,NA,2,1,8,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,35551.992846,35164.643493,3,91,15,14,4.03,5,4,2,0,0,1,42,2,4,1,5 +69021,7,2,1,18,NA,1,1,1,18,220,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,27186.265479,27336.512389,1,95,4,4,0.68,5,5,0,1,0,2,38,2,3,4,NA +69022,7,2,2,48,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,42424.587753,44729.774642,2,102,4,4,1.16,2,2,0,0,0,1,48,1,4,1,4 +69023,7,2,2,7,NA,5,7,1,7,90,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14676.903347,14493.499136,1,102,5,5,1.27,3,3,0,2,0,2,38,1,2,3,NA +69024,7,2,1,65,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,11764.405491,12074.424659,1,97,4,4,1.34,1,1,0,0,1,1,65,1,5,3,NA +69025,7,2,1,60,NA,1,1,1,NA,NA,2,NA,2,2,6,NA,1,1,NA,2,2,2,2,2,2,2,2,2,2,11937.570805,12597.633777,2,96,5,5,0.68,6,6,0,3,2,1,60,2,1,1,1 +69026,7,2,2,1,19,1,1,1,NA,19,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,9469.751474,10066.755659,1,102,13,13,NA,6,6,1,2,0,2,36,2,4,6,NA +69027,7,2,1,37,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,96536.931937,99301.799305,2,91,15,15,4.2,6,6,2,0,2,1,63,1,1,1,3 +69028,7,2,1,0,5,1,1,1,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,2,2,2,NA,NA,NA,NA,7757.493251,8192.524698,3,92,8,8,1.45,6,6,2,0,0,2,58,2,5,1,9 +69029,7,2,2,6,NA,4,4,2,6,79,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7631.175557,7797.231767,1,93,1,1,0.02,5,5,0,4,0,2,36,NA,NA,5,NA +69030,7,1,1,36,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,22188.836739,0,1,101,13,13,NA,3,3,1,0,0,2,20,1,2,6,NA +69031,7,2,1,22,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,3,5,NA,1,2,2,1,2,2,1,2,2,3,15196.92397,17064.888752,2,101,9,6,2.3,4,1,0,0,0,1,22,2,3,5,NA +69032,7,2,2,64,NA,1,1,1,NA,NA,2,NA,2,7,77,NA,1,2,NA,2,2,2,1,2,2,NA,NA,NA,NA,6287.91334,6572.718606,2,92,12,12,NA,7,7,0,1,2,2,64,2,1,2,NA +69033,7,2,1,2,NA,3,3,2,2,33,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,50064.977404,56868.769772,1,95,14,14,2.98,5,5,1,2,0,1,33,1,4,1,5 +69034,7,2,1,33,NA,2,2,1,NA,NA,2,NA,2,2,5,NA,2,6,NA,2,2,2,1,2,2,2,2,1,2,36418.962534,36838.502529,2,93,4,4,0.56,5,5,0,2,0,1,37,NA,NA,1,1 +69035,7,2,1,68,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,121588.761604,120347.630506,1,91,14,14,5,2,2,0,0,2,1,68,1,4,1,4 +69036,7,2,1,76,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,8764.234393,9213.337166,2,98,77,77,NA,2,2,0,0,2,2,70,1,3,1,2 +69037,7,2,1,41,NA,1,1,1,NA,NA,2,NA,2,1,4,NA,2,1,NA,2,2,2,2,2,2,1,2,2,2,37402.70356,39181.236579,2,102,15,15,5,3,3,1,0,0,1,41,2,2,1,5 +69038,7,2,2,29,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,99381.891022,103468.309204,2,92,15,15,5,2,1,0,0,0,2,29,1,5,1,NA +69039,7,1,1,39,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,83081.99261,0,2,92,15,15,5,2,1,0,0,0,1,41,1,4,5,NA +69040,7,2,2,46,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,92399.914697,92845.296279,2,92,15,15,5,5,5,0,3,0,2,46,1,5,1,5 +69041,7,2,1,8,NA,4,4,1,8,101,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10311.165779,10516.173846,2,98,4,4,1.29,2,2,0,1,0,2,27,1,2,5,NA +69042,7,2,1,33,NA,2,2,2,NA,NA,2,NA,2,1,6,NA,3,6,NA,2,2,2,1,2,2,1,2,2,1,43108.74283,43605.347908,2,91,7,7,1.29,6,6,2,2,0,1,33,2,3,6,NA +69043,7,2,1,5,NA,5,6,2,5,64,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4526.77644,4888.797036,3,90,12,12,NA,5,5,1,2,0,1,37,2,5,1,5 +69044,7,2,2,0,8,2,2,2,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,NA,NA,NA,NA,NA,NA,NA,7135.777159,7112.267328,1,90,7,7,1.56,4,4,1,1,0,2,37,1,2,77,NA +69045,7,2,2,65,NA,2,2,2,NA,NA,2,NA,2,1,8,NA,4,1,NA,2,2,2,1,2,2,1,2,2,2,13676.984152,14509.761798,2,91,8,8,3.3,2,2,0,0,2,1,65,NA,NA,1,4 +69046,7,2,1,3,NA,5,6,2,3,47,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8402.098771,9423.873047,3,91,7,7,2.16,3,3,1,0,1,2,36,2,5,1,NA +69047,7,2,2,61,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,98514.948291,98181.677236,1,99,15,15,5,2,2,0,0,2,1,73,1,4,1,5 +69048,7,2,2,11,NA,3,3,1,11,143,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18800.96526,18551.296274,1,94,6,6,1.26,5,5,0,2,0,2,38,1,4,1,NA +69049,7,2,1,71,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,1,2,1,2,2,1,1,2,NA,10776.442569,10987.528707,1,96,7,7,1,7,7,2,1,1,2,53,1,4,1,3 +69050,7,2,2,1,22,3,3,2,NA,23,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,39879.891371,42381.146401,1,91,14,14,3.06,5,5,2,0,0,2,30,1,5,1,5 +69051,7,2,2,5,NA,3,3,2,5,62,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,51483.624552,53105.566664,1,94,15,15,5,4,4,2,0,0,1,51,2,5,1,5 +69052,7,1,2,40,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,4,1,3,1,2,2,1,2,2,NA,NA,NA,NA,115926.402585,0,1,101,15,15,5,4,4,0,2,0,2,40,1,4,1,3 +69053,7,2,2,43,NA,2,2,2,NA,NA,2,NA,2,1,1,NA,3,6,2,2,2,2,2,2,2,2,2,2,2,34503.935186,34683.870273,2,91,12,12,NA,5,5,0,1,1,2,43,2,3,6,NA +69054,7,2,1,43,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,19633.637051,21699.358471,2,95,5,5,1.05,3,3,0,1,0,1,43,1,3,1,2 +69055,7,2,2,28,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,53638.260635,56251.206542,2,96,7,7,2.38,2,2,0,0,0,1,29,1,3,1,4 +69056,7,2,1,39,NA,5,6,2,NA,NA,2,NA,2,1,3,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,13593.59406,14525.996816,2,90,5,5,1.08,3,3,0,1,0,2,29,2,4,1,5 +69057,7,2,2,39,NA,1,1,1,NA,NA,2,NA,2,7,77,NA,4,1,2,2,2,2,1,2,2,NA,NA,NA,NA,29148.354549,28361.870708,2,92,12,12,NA,7,7,0,1,2,2,64,2,1,2,NA +69058,7,2,1,43,NA,1,1,1,NA,NA,2,NA,2,2,6,NA,1,6,NA,2,2,1,1,2,2,NA,NA,NA,NA,37324.655911,39220.856657,1,102,5,5,0.86,5,5,2,0,0,2,21,2,2,5,NA +69059,7,2,1,2,NA,4,4,2,2,28,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5662.231921,6243.536586,1,99,13,13,NA,4,4,1,0,0,2,26,1,4,4,NA +69060,7,2,1,20,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,137038.746155,146586.432966,2,101,3,3,0.92,2,1,0,0,0,1,21,1,4,5,NA +69061,7,2,2,49,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,26105.275101,26256.723843,1,98,9,9,4.03,2,2,0,1,0,2,49,1,5,3,NA +69062,7,2,2,70,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,3,2,NA,1,2,1,1,2,1,1,2,1,NA,10831.995402,11374.881633,3,90,77,77,NA,4,4,0,0,2,1,69,2,5,2,NA +69063,7,2,1,2,NA,1,1,2,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,10803.555682,11221.222518,2,91,6,6,1,6,6,1,3,0,2,35,2,2,1,1 +69064,7,2,2,6,NA,4,4,1,6,81,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11195.065587,11390.355382,2,96,2,2,0.31,4,4,0,2,0,2,30,NA,NA,6,NA +69065,7,2,1,28,NA,5,6,2,NA,NA,2,NA,2,2,2,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,14313.345971,15171.949804,3,91,15,6,2.75,2,1,0,0,0,2,30,NA,NA,6,NA +69066,7,2,1,74,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,60942.568495,64726.722108,1,94,9,9,3.97,2,2,0,0,2,1,74,1,4,1,4 +69067,7,2,1,53,NA,5,6,1,NA,NA,2,NA,2,2,77,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,16590.074977,17115.36835,1,92,12,12,NA,4,4,0,1,0,1,53,2,5,1,4 +69068,7,2,2,39,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,1,1,1,2,2,1,2,2,1,2,2,1,16614.865368,17238.21833,3,91,15,15,5,3,3,1,0,0,2,39,2,5,1,5 +69069,7,2,1,11,NA,4,4,1,11,136,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10269.191209,10473.364732,2,102,5,5,0.67,6,6,0,4,0,2,33,1,2,6,NA +69070,7,2,2,4,NA,5,6,2,4,49,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,6683.092466,6676.033575,3,91,6,6,1.34,4,4,1,1,0,1,36,2,4,1,NA +69071,7,2,1,4,NA,5,6,2,4,57,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7580.437211,8294.186048,2,92,12,12,NA,7,7,2,4,0,1,54,2,2,1,5 +69072,7,1,2,0,3,5,6,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6440.205112,0,2,103,14,14,3.86,4,4,2,0,0,2,37,2,5,1,NA +69073,7,2,2,3,NA,5,6,1,3,44,NA,NA,2,2,1,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8052.137959,8043.633038,1,100,7,7,2.2,3,3,1,0,0,2,28,2,2,1,3 +69074,7,2,1,19,NA,1,1,2,19,237,2,NA,2,2,4,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,26704.187335,28443.712885,1,95,9,9,2.46,4,4,0,0,0,1,42,2,2,1,3 +69075,7,2,1,2,NA,4,4,2,2,25,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5163.141902,5376.483607,2,99,13,13,NA,5,5,2,0,0,2,21,1,3,5,NA +69076,7,2,1,18,NA,3,3,1,18,220,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,24446.632088,24751.360191,1,94,4,4,0.79,3,3,0,1,0,1,49,1,2,3,NA +69077,7,2,2,58,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,35630.227837,37045.269032,2,102,6,6,2.75,1,1,0,0,0,2,58,1,2,3,NA +69078,7,2,2,59,NA,2,2,2,NA,NA,2,NA,2,1,7,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,27617.038547,29182.278408,1,93,14,14,5,2,2,0,0,0,2,59,2,5,5,NA +69079,7,2,1,32,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,18683.628164,19333.389409,1,98,5,4,1.7,3,1,0,0,0,1,32,1,5,5,NA +69080,7,2,1,16,NA,4,4,1,16,202,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,17606.165994,18413.211403,2,101,4,4,0.86,3,3,0,1,0,2,18,1,2,NA,NA +69081,7,2,2,23,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,15992.133387,15205.505219,2,95,15,15,3.85,7,7,0,3,1,2,62,1,4,2,NA +69082,7,2,1,8,NA,1,1,2,8,97,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14134.674028,14215.818763,1,96,8,8,2.62,3,3,0,1,0,1,41,2,3,1,5 +69083,7,2,1,14,NA,3,3,2,14,171,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,20051.633575,19994.174398,2,97,5,5,0.84,5,5,0,2,0,2,33,1,4,1,3 +69084,7,2,1,2,NA,4,4,1,2,29,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10232.679671,10545.226242,2,101,1,1,0.21,4,4,1,2,0,2,26,1,3,5,NA +69085,7,2,2,49,NA,2,2,1,NA,NA,2,NA,2,1,4,NA,2,5,NA,2,2,2,1,2,2,1,2,2,2,28065.587512,28753.959014,2,93,4,4,0.56,5,5,0,0,0,2,49,2,2,5,NA +69086,7,2,2,25,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,104934.725755,111516.131691,2,98,10,10,4.42,2,2,0,0,0,1,25,1,5,1,5 +69087,7,2,2,15,NA,3,3,2,15,189,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,36586.371708,39087.782259,1,98,3,3,0.5,5,5,0,3,0,2,56,1,3,3,NA +69088,7,2,2,67,NA,2,2,1,NA,NA,2,NA,2,1,8,NA,4,1,NA,2,2,2,1,2,2,2,2,2,2,10614.141896,11057.12801,2,93,4,4,0.99,2,2,0,0,2,1,72,2,3,1,4 +69089,7,2,1,61,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,12170.074646,12490.78413,1,97,9,7,3.36,2,1,0,0,1,1,61,1,5,3,NA +69090,7,2,1,2,NA,3,3,2,2,26,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,20538.767297,24065.985233,2,95,3,3,0.52,3,3,1,0,0,1,37,1,4,1,4 +69091,7,2,1,52,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,132969.642582,135979.403496,2,94,8,8,4.59,1,1,0,0,0,1,52,1,3,3,NA +69092,7,2,2,0,4,3,3,2,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16423.151355,17405.028297,1,99,15,15,5,3,3,1,0,0,2,31,1,5,1,5 +69093,7,2,1,16,NA,5,6,2,16,201,NA,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,9099.599144,9725.105491,1,90,9,9,2.6,4,4,0,1,0,2,49,2,2,1,5 +69094,7,2,1,3,NA,3,3,1,3,42,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,21357.821814,24096.698658,2,96,3,3,0.53,5,5,3,0,0,2,26,1,4,1,4 +69095,7,2,1,1,14,1,1,1,NA,15,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12387.68972,13272.515505,1,94,6,6,1.3,4,4,2,0,0,1,24,2,1,1,4 +69096,7,1,1,12,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13731.625553,0,1,100,8,8,1.95,4,4,0,2,0,2,42,1,4,1,4 +69097,7,2,1,31,NA,2,2,2,NA,NA,2,NA,2,2,4,NA,2,1,NA,2,2,2,1,2,2,2,2,2,2,36946.697686,39295.803447,1,98,3,3,0.4,7,7,2,3,0,2,31,2,5,1,2 +69098,7,2,1,14,NA,1,1,1,14,178,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18242.832494,18343.652859,1,102,6,6,1.34,4,4,0,1,0,2,48,2,3,1,1 +69099,7,2,1,6,NA,4,4,2,6,82,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9399.447563,9986.021526,2,90,7,7,1.61,4,4,1,1,1,2,65,1,3,2,NA +69100,7,1,2,77,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,14125.505993,0,1,99,14,14,5,2,2,0,0,2,1,79,NA,NA,1,5 +69101,7,2,1,58,NA,2,2,2,NA,NA,2,NA,2,2,5,NA,1,4,NA,2,2,2,2,2,2,2,2,2,2,25042.846308,24675.381142,1,93,14,6,2.94,5,1,1,0,0,2,22,2,1,6,NA +69102,7,2,2,61,NA,2,2,2,NA,NA,2,NA,2,1,8,NA,3,1,NA,1,2,2,1,2,2,2,2,2,2,5852.076897,6537.978856,2,90,7,7,0.89,7,7,1,3,3,1,60,2,3,1,3 +69103,7,2,1,22,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,1,5,NA,1,2,2,1,2,2,1,2,2,1,16995.648055,16598.645683,2,100,3,3,0.27,7,7,2,1,0,2,41,1,2,5,NA +69104,7,2,1,5,NA,1,1,2,5,66,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,14993.478359,14600.446315,1,97,6,3,0.63,7,3,2,1,0,1,29,2,2,1,1 +69105,7,2,1,55,NA,2,2,1,NA,NA,2,NA,2,2,3,NA,1,5,NA,2,2,2,2,2,2,1,2,2,2,37557.946192,37006.841228,2,102,5,5,1.08,3,3,0,0,0,1,55,2,1,5,NA +69106,7,2,2,0,8,5,7,2,NA,8,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7434.184594,7384.233557,1,93,15,15,5,3,3,1,0,0,2,34,1,5,1,5 +69107,7,2,1,69,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,7323.703412,7380.991723,2,100,4,4,0.97,3,3,0,0,3,2,80,1,5,2,NA +69108,7,2,1,30,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,20891.980831,22154.880695,2,97,5,5,1.08,3,3,0,0,0,1,38,1,4,5,NA +69109,7,2,1,1,19,1,1,1,NA,19,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,11793.948458,12249.904005,1,100,5,5,0.65,6,6,1,2,0,1,32,2,2,1,2 +69110,7,2,2,56,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,24870.513993,25282.537357,2,98,8,8,3.06,2,2,0,1,0,2,56,1,3,3,NA +69111,7,2,1,9,NA,3,3,2,9,110,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,40950.556053,42121.524492,2,95,15,15,4.77,4,4,0,2,0,2,36,1,4,1,5 +69112,7,2,2,23,NA,5,6,1,NA,NA,2,NA,2,2,1,NA,4,5,2,1,2,2,1,2,2,NA,NA,NA,NA,16929.836231,18556.498474,2,101,4,3,1.1,2,1,0,0,0,2,23,2,4,5,NA +69113,7,2,2,8,NA,3,3,1,8,97,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,51531.402068,50847.086518,1,94,6,6,1.57,3,3,0,1,0,2,28,1,4,1,4 +69114,7,2,2,37,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,NA,NA,NA,NA,NA,NA,NA,84761.905629,91116.013503,1,95,NA,NA,NA,5,5,0,2,0,2,37,1,3,1,NA +69115,7,2,1,79,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,8517.336599,8684.171961,2,100,4,4,1.02,2,2,0,0,1,1,79,1,1,2,NA +69116,7,2,1,14,NA,3,3,2,14,170,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,88198.948426,91036.751291,1,98,10,10,3.04,4,4,0,2,0,2,47,1,4,1,3 +69117,7,2,1,28,NA,4,4,2,NA,NA,2,NA,2,1,6,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,21399.459455,20960.973241,1,90,15,15,4.34,4,4,0,0,1,1,62,2,5,1,3 +69118,7,2,1,11,NA,5,6,2,11,133,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,1,1,2,2,NA,4852.395137,5120.382571,1,99,6,6,1.07,6,6,2,1,2,1,44,2,5,4,NA +69119,7,2,1,16,NA,4,4,1,16,203,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,15008.400374,15566.530345,1,100,7,7,2.78,2,2,0,1,0,2,37,2,4,5,NA +69120,7,2,2,39,NA,4,4,2,NA,NA,2,NA,2,2,3,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,27303.803575,27591.614113,1,96,3,3,0.43,4,4,1,1,0,2,39,2,4,1,3 +69121,7,2,2,5,NA,5,7,2,5,61,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,27257.164734,28966.726071,1,92,3,3,0.46,5,5,2,1,0,1,30,1,3,1,2 +69122,7,2,1,16,NA,4,4,2,16,197,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,10732.729133,10991.603368,3,90,10,10,3.67,3,3,0,1,0,2,52,2,3,5,NA +69123,7,2,2,63,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,128590.415432,131137.819973,1,102,15,15,5,2,2,0,0,2,2,63,1,4,1,4 +69124,7,2,2,19,NA,5,6,2,20,NA,2,NA,2,2,2,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,10353.070387,10520.518116,2,101,5,3,1.1,2,1,0,0,0,1,29,2,4,1,NA +69125,7,2,2,49,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,133853.800452,137185.265763,3,91,5,5,1.93,1,1,0,0,0,2,49,1,3,3,NA +69126,7,2,1,3,NA,3,3,1,3,47,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,77607.205684,90935.051698,1,98,6,6,1.31,3,3,1,0,0,1,30,1,5,1,5 +69127,7,2,1,8,NA,3,3,1,8,97,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,54897.892683,58386.014643,2,98,7,7,1.61,4,4,1,1,0,1,43,NA,NA,6,NA +69128,7,2,1,8,NA,4,4,1,8,97,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9184.716222,9199.031651,1,102,1,1,0,5,5,0,3,0,2,41,1,4,1,4 +69129,7,2,1,18,NA,2,2,1,18,225,2,NA,2,2,2,66,NA,NA,NA,2,2,2,2,2,2,1,2,2,2,22721.243258,22896.459408,2,102,8,8,1.09,7,7,1,3,0,2,33,2,1,6,NA +69130,7,2,1,47,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,31540.022655,39899.113022,2,91,3,3,0.86,2,2,0,0,0,2,41,1,4,1,3 +69131,7,2,2,25,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,22941.698794,22487.759922,2,96,5,5,1.08,3,3,0,0,0,1,50,1,3,1,4 +69132,7,2,1,6,NA,4,4,2,6,78,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11277.594097,11665.009628,1,90,5,5,0.74,5,5,0,2,0,2,18,1,4,NA,NA +69133,7,2,2,1,20,4,4,2,NA,21,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7623.406054,7742.751523,1,97,4,4,0.46,7,7,3,3,0,2,31,1,3,1,NA +69134,7,2,2,2,NA,4,4,2,2,35,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5687.793894,6002.477845,2,90,8,5,1.36,5,2,2,0,0,2,25,2,3,5,NA +69135,7,1,1,40,NA,5,6,NA,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,17210.953493,0,1,91,15,15,5,5,5,2,1,0,1,40,1,5,1,5 +69136,7,2,2,36,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,4,6,2,2,2,2,2,2,2,1,2,2,2,36453.846815,35470.245447,1,102,13,13,NA,6,6,1,2,0,2,36,2,4,6,NA +69137,7,2,1,56,NA,4,4,2,NA,NA,2,NA,2,2,8,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,15760.921402,15756.795819,3,90,15,15,5,4,4,0,0,0,1,56,2,4,1,5 +69138,7,2,2,16,NA,3,3,1,16,195,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,71832.578284,73443.760792,1,92,8,8,1.45,6,6,1,3,0,1,36,1,3,1,4 +69139,7,2,2,17,NA,2,2,1,17,209,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,2,2,2,NA,NA,NA,NA,27070.679378,27847.54398,1,92,6,6,0.93,5,5,0,2,0,1,47,2,1,1,1 +69140,7,2,1,80,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,44862.41765,53799.51702,1,92,7,7,2.64,2,2,0,0,2,1,80,1,3,1,3 +69141,7,2,1,80,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,8497.912951,8999.288803,1,96,6,6,1.82,2,2,0,0,2,1,80,1,1,1,9 +69142,7,2,1,72,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,38226.070503,39676.327756,1,99,9,9,5,1,1,0,0,1,1,72,1,5,2,NA +69143,7,2,2,10,NA,4,4,1,10,130,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7489.549692,8064.290136,2,100,8,8,1.1,7,7,3,3,0,2,58,1,3,5,NA +69144,7,2,2,71,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,14936.784897,17875.873101,2,94,5,5,2.2,1,1,0,0,1,2,71,1,3,2,NA +69145,7,2,1,18,NA,1,1,1,18,217,2,NA,1,1,NA,66,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,15469.666055,15805.71937,2,92,12,12,NA,7,7,0,1,2,2,64,2,1,2,NA +69146,7,2,1,41,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,28361.113525,28406.771707,1,97,8,8,4.7,1,1,0,0,0,1,41,1,3,3,NA +69147,7,2,1,39,NA,5,6,2,NA,NA,2,NA,2,2,4,NA,5,1,NA,1,2,2,1,2,1,1,2,2,1,17605.619977,18470.699991,3,91,15,15,5,3,3,0,1,0,2,40,2,5,1,5 +69148,7,2,1,5,NA,3,3,2,5,66,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,73006.119819,83450.013654,1,101,6,6,0.97,7,7,2,1,0,1,43,1,2,1,NA +69149,7,2,1,62,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,7791.74373,7821.068134,1,91,7,7,3.54,1,1,0,0,1,1,62,1,3,3,NA +69150,7,2,2,6,NA,4,4,2,6,77,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8757.841043,9104.895674,2,101,5,5,1.03,4,4,1,1,0,2,31,1,3,5,NA +69151,7,2,1,57,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,119599.307776,123574.267321,1,93,15,15,4.59,4,4,0,1,0,1,57,1,5,1,5 +69152,7,2,1,21,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,17420.978407,17743.990528,2,97,3,3,0.82,2,2,0,0,0,1,24,1,3,5,NA +69153,7,2,1,10,NA,4,4,2,10,124,NA,NA,2,1,3,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10229.206765,10406.656985,1,96,9,9,2.78,4,4,0,2,0,1,54,2,5,4,NA +69154,7,2,1,66,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,29999.543427,32474.673757,2,91,2,2,0.56,1,1,0,0,1,1,66,1,3,3,NA +69155,7,2,2,9,NA,3,3,2,9,110,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,74327.830279,75742.187091,2,91,6,6,1.34,4,4,1,2,0,2,33,1,4,3,NA +69156,7,2,1,12,NA,3,3,1,12,155,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,84860.612577,85065.529717,2,98,15,15,5,4,4,0,2,0,1,48,1,3,1,4 +69157,7,2,2,21,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,5,3,1,2,2,1,2,2,1,2,2,1,112960.559471,113970.503883,1,94,99,99,NA,5,5,1,1,0,2,21,1,3,5,NA +69158,7,2,1,44,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,32719.762791,33772.872733,1,91,1,1,0.2,2,2,0,0,0,1,44,1,2,1,2 +69159,7,2,2,22,NA,2,2,1,NA,NA,2,NA,2,2,2,NA,5,5,2,2,2,2,2,2,2,1,2,2,1,35424.746838,36356.556801,2,93,NA,3,0.98,4,1,0,0,0,1,28,NA,NA,4,NA +69160,7,2,1,17,NA,1,1,1,17,208,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,NA,NA,NA,NA,27186.265479,27776.842846,1,92,15,15,4.99,4,4,0,2,0,2,43,1,4,1,4 +69161,7,2,1,20,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,22233.683089,25178.838093,1,102,2,2,0.49,3,3,1,0,0,1,20,1,2,6,NA +69162,7,2,1,72,NA,2,2,1,NA,NA,2,NA,2,2,4,NA,4,5,NA,2,2,2,2,2,2,2,2,2,NA,12250.041239,12463.587232,2,100,1,1,0,1,1,0,0,1,1,72,2,4,5,NA +69163,7,2,2,10,NA,5,7,1,10,123,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9007.62445,9504.796896,2,102,15,15,5,4,4,0,2,0,1,39,1,4,1,5 +69164,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,51433.469947,56330.524019,1,98,7,7,3.8,1,1,0,0,1,2,80,1,5,2,NA +69165,7,2,1,72,NA,5,6,1,NA,NA,2,NA,2,1,8,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,18239.933451,19545.291055,2,102,8,8,3.67,2,2,0,0,2,1,72,2,5,1,NA +69166,7,2,1,60,NA,4,4,2,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,6038.685119,6085.921613,1,96,15,15,5,3,3,0,0,1,1,60,2,5,1,5 +69167,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,27681.279,30792.259764,1,91,3,3,1.29,1,1,0,0,1,2,80,1,2,2,NA +69168,7,2,1,75,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,1,4,NA,1,2,2,1,2,2,1,2,2,NA,8902.117734,9243.371936,1,97,15,15,5,6,6,0,1,1,2,53,1,4,1,NA +69169,7,2,1,10,NA,4,4,1,11,133,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10122.702296,10604.04698,2,100,3,3,0.42,5,5,0,1,0,2,51,1,4,5,NA +69170,7,2,2,51,NA,1,1,2,NA,NA,2,NA,2,2,6,NA,1,1,NA,2,2,2,2,2,2,2,2,2,2,22224.73066,22340.630739,2,91,10,10,2.95,4,4,0,1,0,2,18,1,3,NA,NA +69171,7,2,2,40,NA,2,2,1,NA,NA,2,NA,2,1,2,NA,4,5,2,2,2,2,2,2,2,2,2,1,2,32281.860274,32750.128834,2,93,7,7,2.31,2,2,0,0,1,2,40,2,4,5,NA +69172,7,2,2,65,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,9570.416297,9969.842041,2,98,6,6,2.75,1,1,0,0,1,2,65,1,4,3,NA +69173,7,2,1,14,NA,4,4,1,14,171,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14848.504688,14877.861397,1,98,8,8,1.95,4,4,0,2,0,2,31,1,2,1,5 +69174,7,2,2,12,NA,4,4,1,12,152,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11838.873374,11750.256617,2,100,15,15,4.47,4,4,0,2,0,1,39,NA,NA,1,5 +69175,7,2,2,32,NA,2,2,2,NA,NA,1,1,1,1,NA,NA,4,1,2,1,2,2,1,2,2,NA,NA,NA,NA,27127.983961,26396.013964,2,90,15,15,4.2,5,5,1,0,0,2,50,NA,NA,6,NA +69176,7,2,2,57,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,26668.458882,26828.838508,2,102,5,5,1.84,1,1,0,0,0,2,57,1,3,6,NA +69177,7,2,1,66,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,121588.761604,120347.630506,1,91,8,8,3.4,2,2,0,0,2,1,66,1,5,1,4 +69178,7,2,2,28,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,1,1,2,2,1,10800.351372,11472.015663,2,92,3,3,0.45,4,4,0,0,1,1,64,2,1,1,1 +69179,7,1,2,14,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15847.19263,0,1,98,15,15,5,4,4,0,2,0,2,50,1,5,1,5 +69180,7,2,2,1,16,4,4,2,NA,18,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7348.24433,7906.792868,2,95,10,10,2.32,6,6,1,2,0,1,44,1,4,1,4 +69181,7,2,2,37,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,5,2,1,2,2,1,2,2,1,2,2,1,90299.161173,91599.679037,1,95,7,7,2.54,2,2,0,1,0,2,37,1,1,5,NA +69182,7,2,2,8,NA,2,2,2,8,103,NA,NA,2,2,1,3,NA,NA,NA,2,1,2,1,2,2,2,2,2,2,10762.400563,12070.126078,2,90,3,3,0.46,5,5,1,3,0,2,35,2,1,4,NA +69183,7,2,1,6,NA,1,1,1,6,83,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10658.399025,10722.994279,1,102,8,8,1.33,7,7,1,4,0,2,32,1,3,1,2 +69184,7,2,1,56,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,32720.69734,34082.896551,1,92,4,4,1.16,2,2,0,0,1,1,56,1,2,1,3 +69185,7,2,1,60,NA,2,2,1,NA,NA,2,NA,2,2,5,NA,2,1,NA,2,2,2,1,2,2,2,2,1,2,6449.12882,6552.435629,2,93,7,7,1.83,3,3,0,1,1,1,60,2,2,1,4 +69186,7,1,1,5,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9016.053035,0,2,100,2,2,0.25,4,4,2,1,0,2,39,1,2,5,NA +69187,7,2,2,22,NA,2,2,2,NA,NA,2,NA,2,2,2,NA,1,5,2,2,2,2,2,2,2,NA,NA,NA,NA,31196.446669,31060.57243,2,99,99,1,0,5,1,0,1,0,1,40,2,1,6,NA +69188,7,2,2,8,NA,5,7,2,8,100,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9620.269705,10273.007637,2,91,12,12,NA,4,4,0,2,0,1,40,1,5,1,5 +69189,7,2,1,3,NA,4,4,1,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10040.033098,10162.494907,1,100,15,15,5,3,3,1,0,0,2,34,1,5,1,5 +69190,7,2,2,80,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,9,2,NA,1,1,2,1,2,2,1,1,2,NA,14971.827573,15430.401607,2,97,13,13,NA,4,4,1,0,1,2,45,1,2,5,NA +69191,7,2,1,0,11,1,1,1,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,7757.493251,8192.524698,3,92,1,1,0.18,5,5,2,2,0,2,31,2,1,5,NA +69192,7,2,2,0,2,5,7,2,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9288.555962,9478.459453,1,95,6,6,0.96,5,5,1,0,1,2,69,1,1,2,NA +69193,7,2,2,12,NA,2,2,2,12,147,NA,NA,1,1,NA,6,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,19480.517135,20370.224649,2,94,1,1,0.01,7,7,1,3,0,1,41,2,1,1,1 +69194,7,2,2,6,NA,4,4,1,6,79,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10332.067017,11124.939356,1,100,3,3,0.52,3,3,1,1,0,2,25,1,3,5,NA +69195,7,2,2,10,NA,3,3,2,10,130,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14935.786363,14737.445343,2,94,7,7,1.18,7,7,1,4,0,2,31,1,4,6,NA +69196,7,2,1,27,NA,5,7,1,NA,NA,2,NA,2,2,3,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,32866.0119,33575.905633,1,98,99,99,NA,3,1,0,0,0,2,22,1,4,5,NA +69197,7,2,2,2,NA,1,1,1,2,26,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,8832.868731,8863.029978,1,102,2,2,0.19,7,7,2,2,0,1,48,2,9,1,9 +69198,7,2,2,13,NA,1,1,2,13,158,NA,NA,1,1,NA,7,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,18368.872199,20151.001259,2,94,5,5,0.67,6,6,1,3,0,1,37,2,3,1,4 +69199,7,2,1,60,NA,5,6,2,NA,NA,2,NA,2,2,5,NA,2,4,NA,1,2,1,1,2,1,1,2,1,3,6814.038157,7682.939373,2,91,12,13,NA,7,1,0,4,2,2,72,2,1,2,NA +69200,7,2,1,34,NA,5,6,1,NA,NA,2,NA,2,1,3,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,22957.82581,23425.428596,2,102,15,15,3.92,5,5,1,2,0,1,34,2,5,1,5 +69201,7,2,2,44,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,20834.783335,21091.811515,2,94,15,15,5,5,5,0,2,1,1,47,2,5,1,5 +69202,7,2,1,9,NA,1,1,1,9,116,NA,NA,1,1,NA,3,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,17882.621856,17720.218058,3,92,7,7,1.3,5,5,1,2,0,2,33,2,2,1,1 +69203,7,2,2,66,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,8308.628726,8679.600111,2,95,9,9,4.92,1,1,0,0,1,2,66,1,5,3,NA +69204,7,2,2,16,NA,3,3,1,16,201,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,30430.369428,31312.351655,3,92,5,5,1.03,4,4,0,3,0,1,55,1,4,4,NA +69205,7,2,2,47,NA,5,6,1,NA,NA,2,NA,2,2,6,NA,3,1,NA,1,2,1,1,2,1,1,2,1,3,14872.222375,15689.845848,2,92,7,7,1.61,4,4,0,2,0,1,51,2,3,1,3 +69206,7,1,1,80,NA,2,2,NA,NA,NA,2,NA,2,1,8,NA,1,1,NA,2,2,2,2,2,2,NA,NA,NA,NA,13654.270555,0,2,93,7,7,2.31,2,2,0,0,2,1,80,2,1,1,1 +69207,7,2,2,30,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,27381.645976,29718.515739,2,95,5,4,1.52,3,1,0,0,0,1,31,1,4,5,NA +69208,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,1,2,NA,25840.959268,29976.982116,1,101,3,3,0.86,2,2,0,0,2,2,80,1,2,1,1 +69209,7,1,2,47,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,35469.911999,0,2,91,6,6,2.78,1,1,0,0,0,2,47,1,4,3,NA +69210,7,2,1,23,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,25815.880139,26556.735732,2,101,1,1,0.09,2,1,0,0,0,1,23,1,5,5,NA +69211,7,2,1,0,2,5,6,1,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8377.359485,8321.07116,2,96,4,4,0.97,3,3,1,0,0,1,31,2,5,1,5 +69212,7,2,1,38,NA,1,1,1,NA,NA,2,NA,2,2,3,NA,2,4,NA,2,2,2,1,2,2,1,2,2,2,41241.224595,41716.316195,2,102,6,6,1.03,5,5,1,1,0,1,37,1,2,1,2 +69213,7,2,2,47,NA,3,3,1,NA,NA,2,NA,2,2,7,NA,5,1,NA,2,2,2,1,2,2,2,2,2,2,27349.117265,27628.99562,2,93,6,6,1.65,2,2,0,0,0,1,52,2,3,1,5 +69214,7,2,2,0,1,4,4,2,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4137.127382,4416.757179,2,97,1,1,0.12,5,5,1,2,0,2,24,1,3,5,NA +69215,7,2,2,9,NA,1,1,1,9,112,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,19194.228411,19883.529671,2,96,7,7,1.34,5,5,0,2,0,1,24,2,2,5,NA +69216,7,2,1,35,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,22937.913723,23137.542903,1,100,3,3,0.43,4,4,0,2,0,1,35,1,4,1,3 +69217,7,2,2,16,NA,5,7,2,16,193,NA,NA,1,1,NA,10,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,31716.869763,32129.640601,1,101,3,3,0.92,2,2,0,1,0,2,53,1,5,3,NA +69218,7,2,2,2,NA,1,1,1,2,29,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,9132.13761,10082.124987,1,103,13,13,NA,4,4,2,0,0,2,27,2,2,6,NA +69219,7,2,1,4,NA,2,2,1,4,53,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,15915.595287,17052.411707,2,96,6,6,1.25,4,4,1,1,0,1,31,2,3,1,3 +69220,7,2,2,21,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,2,6,1,1,2,2,1,2,2,1,2,2,1,52280.406546,52747.829022,1,92,1,1,0,2,1,0,0,0,1,30,1,3,6,NA +69221,7,2,2,51,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,17950.494975,18684.288461,1,92,15,15,5,4,4,0,2,0,1,55,1,5,1,5 +69222,7,2,1,6,NA,3,3,2,6,76,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,47178.298856,52231.302145,2,95,8,8,2.17,4,4,1,1,0,1,43,1,4,1,5 +69223,7,2,1,24,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,100722.771154,105550.354971,2,92,14,8,4.13,2,1,0,0,0,2,25,1,5,5,NA +69224,7,2,2,59,NA,2,2,2,NA,NA,2,NA,2,1,4,NA,1,6,NA,2,2,2,1,2,2,2,2,2,2,18341.621382,19145.40337,2,90,6,6,1.21,4,4,0,0,0,2,59,2,1,6,NA +69225,7,2,2,17,NA,1,1,2,17,209,2,NA,2,2,4,12,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,17544.592739,19246.751055,3,92,6,6,1,6,6,1,1,0,1,42,2,1,1,4 +69226,7,2,2,10,NA,4,4,2,10,127,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7588.605543,8103.359102,1,99,14,14,4.21,4,4,0,2,0,2,44,1,5,1,5 +69227,7,2,2,62,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,14994.337564,15663.818698,1,100,15,15,5,2,2,0,0,1,2,48,1,5,5,NA +69228,7,2,1,17,NA,3,3,2,17,215,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,61479.689958,61628.148021,2,100,15,15,4.5,6,6,0,4,0,1,45,1,5,1,5 +69229,7,2,1,43,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,93164.281583,96130.599912,2,95,8,8,2.17,4,4,1,1,0,1,43,1,4,1,5 +69230,7,2,2,8,NA,1,1,1,8,102,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15962.145468,16412.026403,3,92,4,4,0.81,3,3,0,2,0,2,31,1,3,1,NA +69231,7,2,1,10,NA,4,4,2,10,131,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12701.072484,14129.347101,2,91,6,6,0.78,7,7,1,4,0,2,38,2,2,77,NA +69232,7,2,1,0,6,2,2,2,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,2,2,2,NA,NA,NA,NA,6837.213048,7220.636221,2,91,1,1,0.02,5,5,1,2,0,2,27,2,3,1,2 +69233,7,2,2,2,NA,3,3,2,2,29,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,26167.521666,28880.852575,1,93,6,6,1.16,4,4,2,0,0,2,33,1,5,1,4 +69234,7,2,1,8,NA,4,4,2,8,107,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12176.538896,12609.8265,2,97,2,2,0.27,4,4,0,2,0,1,51,1,2,4,NA +69235,7,2,2,3,NA,5,7,2,3,45,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,27969.562936,30869.748923,3,91,7,7,1.57,4,4,2,0,0,2,29,2,3,1,3 +69236,7,2,1,33,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,18417.587863,18945.077049,2,97,4,4,1.35,2,2,0,0,0,2,27,1,4,1,4 +69237,7,2,2,49,NA,2,2,2,NA,NA,1,2,2,1,7,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,46417.079566,46883.794079,1,97,15,15,5,2,2,0,0,0,2,49,2,5,1,4 +69238,7,2,2,5,NA,3,3,2,5,64,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,54058.97777,57449.540919,1,90,8,8,1.67,5,5,2,1,0,2,28,1,4,1,5 +69239,7,2,2,19,NA,5,6,1,19,239,2,NA,2,2,1,15,NA,NA,NA,1,2,1,1,2,1,1,2,1,NA,9200.381964,9723.240452,2,101,2,1,0.32,2,1,0,0,0,2,20,NA,NA,5,NA +69240,7,2,2,7,NA,5,7,1,7,89,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8504.389189,9345.267202,2,93,6,6,1.95,2,2,0,1,0,1,30,1,4,5,NA +69241,7,2,1,36,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,19332.808712,19683.545891,1,90,15,15,5,1,1,0,0,0,1,36,1,5,5,NA +69242,7,1,1,25,NA,2,2,NA,NA,NA,2,NA,2,7,77,NA,2,5,NA,2,2,2,1,2,2,NA,NA,NA,NA,44074.735764,0,2,91,1,1,0.17,4,4,0,1,0,1,49,2,1,6,NA +69243,7,2,2,45,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,105483.169118,109229.181554,1,93,15,15,4.59,4,4,0,2,0,2,45,1,5,1,5 +69244,7,1,2,10,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7899.813226,0,2,100,15,15,5,4,3,0,2,0,1,42,1,3,5,NA +69245,7,2,2,29,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,21398.47235,20994.797177,1,103,14,8,4.21,2,1,0,0,0,2,29,1,5,5,NA +69246,7,2,1,19,NA,5,7,2,19,235,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,7672.605662,7940.039559,1,93,14,14,5,2,2,0,0,0,2,53,2,5,3,NA +69247,7,2,2,80,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,NA,12344.929687,12774.490696,1,93,2,2,0.83,1,1,0,0,1,2,80,1,4,3,NA +69248,7,2,2,43,NA,5,6,2,NA,NA,2,NA,2,1,4,NA,3,1,2,1,2,1,NA,NA,NA,1,2,1,NA,18255.735511,22006.513457,2,91,6,6,1.57,3,3,0,1,0,1,41,2,3,1,3 +69249,7,2,1,34,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,1,2,1,2,2,1,1,2,NA,19923.530941,20672.635795,2,95,6,6,1.08,4,4,1,0,0,2,42,1,4,4,NA +69250,7,2,2,56,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,1,17622.141982,18017.336291,2,95,8,8,2.97,2,2,0,0,0,2,56,1,5,2,NA +69251,7,2,2,5,NA,1,1,1,5,67,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,14665.744588,16191.375588,2,96,5,5,0.89,4,4,1,1,0,2,36,2,4,6,NA +69252,7,2,1,11,NA,1,1,1,11,140,NA,NA,2,2,3,5,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,14820.807433,15173.085782,2,102,7,7,1.79,4,4,0,2,0,1,40,2,2,6,NA +69253,7,2,2,45,NA,2,2,2,NA,NA,2,NA,2,2,4,NA,2,3,NA,2,2,2,2,2,2,1,2,2,2,36457.299109,41822.014095,1,90,5,5,1.79,1,1,0,0,0,2,45,2,2,3,NA +69254,7,2,1,4,NA,1,1,1,4,50,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,15835.271712,16336.527884,1,100,8,3,0.68,6,3,1,0,0,1,33,2,3,6,NA +69255,7,2,1,80,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,42993.150248,46481.579201,1,92,6,6,1.98,2,2,0,0,2,1,80,1,5,1,4 +69256,7,2,1,56,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,32720.69734,34082.896551,1,101,3,3,0.88,2,2,0,0,0,1,56,1,2,1,4 +69257,7,2,2,25,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,24344.236685,23945.277508,2,96,6,6,1.48,4,4,1,1,0,2,25,1,4,5,NA +69258,7,2,2,51,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,21621.615608,21991.273471,1,100,15,15,5,4,4,0,0,0,1,54,1,5,1,5 +69259,7,2,1,30,NA,5,7,1,NA,NA,2,NA,2,1,6,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,84910.063417,90031.493834,2,96,14,6,2.75,3,1,0,0,0,1,30,2,5,5,NA +69260,7,2,2,3,NA,5,6,2,3,44,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4882.863582,4877.706148,1,99,7,7,2.89,2,2,1,0,0,2,35,2,5,1,NA +69261,7,2,2,51,NA,3,3,1,NA,NA,2,NA,2,1,8,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,27769.056387,28050.845299,1,94,99,99,NA,3,3,0,0,2,1,74,NA,NA,1,NA +69262,7,2,2,2,NA,1,1,1,2,28,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12871.484115,13281.030392,2,102,14,14,3.58,4,4,2,0,0,1,25,2,3,1,1 +69263,7,2,1,73,NA,1,1,1,NA,NA,2,NA,2,1,9,NA,1,1,NA,1,2,2,1,2,2,2,2,2,NA,14673.422679,15506.302145,2,98,5,5,0.59,7,7,2,1,2,2,71,1,2,1,1 +69264,7,2,1,69,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,11212.469396,11300.176858,1,100,15,15,5,3,3,0,0,1,1,69,1,5,1,4 +69265,7,2,2,11,NA,1,1,1,11,133,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17053.854294,17233.146259,3,92,1,1,0.26,2,2,0,1,0,2,45,1,2,3,NA +69266,7,2,1,27,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,17265.374984,17186.028516,2,93,4,4,0.56,5,5,2,1,0,1,27,1,2,6,NA +69267,7,2,1,29,NA,3,3,2,NA,NA,2,NA,2,2,3,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,94165.180484,100725.804227,2,99,14,14,5,2,2,0,0,0,2,28,1,5,1,5 +69268,7,2,2,11,NA,4,4,1,11,135,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11076.064101,11269.278002,2,102,4,4,0.53,6,6,2,2,0,2,27,1,2,1,2 +69269,7,2,1,16,NA,3,3,2,16,195,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,NA,NA,NA,NA,91343.020442,91081.271456,1,98,7,7,1,7,7,2,2,0,2,34,1,4,3,NA +69270,7,2,1,66,NA,5,6,2,NA,NA,2,NA,2,1,5,NA,4,1,NA,1,2,1,1,2,1,1,2,1,3,9048.959172,9513.611982,1,93,12,12,NA,4,4,0,0,2,1,66,2,4,1,2 +69271,7,2,1,1,21,1,1,1,NA,22,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12569.23571,12239.751631,2,102,15,15,2.43,7,7,3,2,0,1,28,2,5,1,4 +69272,7,2,2,43,NA,2,2,1,NA,NA,2,NA,2,2,4,NA,1,6,2,2,2,2,1,2,2,NA,NA,NA,NA,32606.880052,32776.922157,2,93,4,4,0.56,5,5,0,2,0,1,37,NA,NA,1,1 +69273,7,2,1,5,NA,4,4,2,5,66,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8890.779467,9258.147648,3,91,1,1,0.07,6,6,2,3,0,2,30,1,2,3,NA +69274,7,2,2,21,NA,4,4,2,NA,NA,2,NA,2,1,3,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,18446.691823,17539.327743,1,90,4,4,0.58,6,6,0,3,0,2,21,2,5,5,NA +69275,7,2,1,13,NA,4,4,2,13,158,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11351.725436,11265.8817,2,95,99,99,NA,2,2,0,1,1,2,80,1,2,2,NA +69276,7,2,1,16,NA,1,1,1,16,199,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,22768.423624,22886.980387,2,98,15,15,5,3,3,0,1,0,1,38,1,4,1,3 +69277,7,2,1,24,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,14313.345971,15171.949804,3,91,6,6,2.94,2,1,0,0,0,1,24,1,5,5,NA +69278,7,2,2,78,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,NA,13549.492282,14020.967918,2,93,6,6,2.28,2,2,0,0,1,2,78,1,5,3,NA +69279,7,2,2,58,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,126314.769628,126413.297707,2,95,15,15,5,2,2,0,0,1,1,61,1,5,1,5 +69280,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,22419.63376,27869.657009,1,94,3,3,1.29,1,1,0,0,1,2,80,1,3,2,NA +69281,7,2,1,3,NA,3,3,2,3,47,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,76114.759421,89186.300704,1,98,15,15,5,4,4,1,1,0,1,40,1,4,1,5 +69282,7,2,2,19,NA,3,3,2,19,236,2,NA,1,1,NA,12,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,31627.471241,33789.841724,1,101,1,1,0.08,3,3,1,0,0,2,19,1,2,NA,NA +69283,7,2,2,73,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,NA,10298.451562,11068.740647,1,93,99,1,0.32,2,1,0,0,1,1,50,NA,NA,5,NA +69284,7,2,1,53,NA,2,2,1,NA,NA,2,NA,2,2,7,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,26651.800212,26887.922292,2,92,3,3,0.92,1,1,0,0,0,1,53,2,4,3,NA +69285,7,2,2,26,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,37537.641876,38018.476349,2,97,5,5,0.84,5,5,0,2,0,2,33,1,4,1,3 +69286,7,2,1,39,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,19096.438335,22378.694988,1,93,15,15,5,1,1,0,0,0,1,39,2,5,5,NA +69287,7,2,1,54,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,173139.914798,174527.091604,1,95,14,14,5,2,2,0,0,0,1,54,1,4,1,3 +69288,7,2,2,69,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,9518.80186,10252.529496,2,100,3,3,0.75,2,2,0,0,2,1,67,1,3,1,2 +69289,7,2,2,5,NA,2,2,1,5,69,NA,NA,2,1,3,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,15979.952759,16987.381382,2,102,7,7,1.53,5,5,1,2,0,2,37,2,4,1,4 +69290,7,2,2,1,21,1,1,2,NA,21,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,9955.153132,10990.75621,2,94,4,4,0.81,4,4,2,0,0,1,26,2,2,1,2 +69291,7,2,1,0,9,5,6,2,NA,10,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,1,NA,NA,NA,NA,4326.150649,4507.366261,1,99,6,6,1.07,6,6,2,1,2,1,44,2,5,4,NA +69292,7,2,1,12,NA,3,3,1,12,147,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,109750.935844,116575.440818,1,94,7,7,1.52,4,4,0,2,2,1,61,2,1,1,5 +69293,7,2,1,9,NA,3,3,1,9,119,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,23188.935049,25672.571973,3,91,7,7,1.1,7,7,0,4,0,1,40,1,4,1,3 +69294,7,2,1,5,NA,4,4,2,5,66,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6946.177172,7374.968672,2,90,6,6,1.03,6,6,3,1,0,1,45,2,2,1,2 +69295,7,2,1,49,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,28813.038041,30658.109612,1,94,5,5,1.2,3,3,0,1,0,1,49,1,4,5,NA +69296,7,2,2,6,NA,5,6,2,6,78,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9849.323746,10517.603056,2,91,10,10,3.04,4,4,1,1,0,1,37,2,5,1,5 +69297,7,2,2,7,NA,2,2,1,7,86,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13498.913367,14670.348602,2,93,7,7,1.56,4,4,1,1,0,1,35,2,4,1,4 +69298,7,2,1,1,20,4,4,2,NA,21,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6429.93791,7090.057975,1,90,3,3,0.63,3,3,1,1,0,2,32,1,4,5,NA +69299,7,2,1,72,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,14781.102246,16162.46005,1,97,12,12,NA,4,4,0,0,2,1,72,1,2,1,3 +69300,7,2,1,23,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,25815.880139,29159.620934,2,101,1,1,0.33,1,1,0,0,0,1,23,1,4,5,NA +69301,7,2,2,64,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,99831.393624,101809.075589,2,94,8,8,3.4,2,2,0,0,2,2,64,1,4,1,2 +69302,7,2,2,14,NA,4,4,1,14,176,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17373.928778,17416.718116,2,96,8,8,1.72,5,5,0,3,0,1,39,1,5,1,4 +69303,7,2,2,12,NA,1,1,1,12,154,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,29109.978779,29945.36646,3,92,10,10,2.82,4,4,0,1,1,1,36,1,3,1,5 +69304,7,2,1,11,NA,3,3,2,11,138,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,44777.275016,47565.734765,1,91,14,14,3.06,5,5,0,3,0,2,46,1,5,1,5 +69305,7,2,1,14,NA,4,4,2,14,175,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12462.601191,12584.643654,2,97,4,4,0.57,5,5,1,3,0,2,33,1,3,5,NA +69306,7,2,2,0,5,4,4,1,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7123.540273,7201.320939,2,101,1,1,0.16,3,3,2,0,0,2,21,1,2,5,NA +69307,7,2,1,58,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,21168.33083,21825.00909,2,99,5,5,1.79,1,1,0,0,0,1,58,1,2,3,NA +69308,7,2,1,12,NA,4,4,2,13,156,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11351.725436,11256.943498,2,95,8,8,1.61,6,6,1,3,0,2,48,1,3,5,NA +69309,7,2,2,45,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,27149.46917,27176.128744,1,94,2,1,0,2,1,0,0,0,1,53,1,3,6,NA +69310,7,2,2,18,NA,2,2,2,18,224,2,NA,2,2,2,66,NA,NA,NA,2,2,2,2,2,2,2,2,2,2,16896.101801,17234.594007,1,93,14,8,2.01,5,4,1,0,0,2,22,2,1,6,NA +69311,7,2,2,16,NA,1,1,1,16,198,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,2,2,2,1,2,2,1,20502.928313,21226.512457,3,92,9,9,2.46,4,4,0,2,0,1,43,2,3,1,4 +69312,7,1,2,6,NA,2,2,NA,NA,NA,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13257.060167,0,2,90,14,14,3.06,5,5,1,2,0,1,42,1,4,1,5 +69313,7,2,1,1,14,4,4,2,NA,14,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6580.937346,6661.20735,2,97,5,5,1.08,3,3,1,0,0,1,28,1,3,5,NA +69314,7,2,1,50,NA,4,4,2,NA,NA,2,NA,2,2,4,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,16117.991297,17081.203544,1,96,7,7,1.69,4,4,0,1,0,2,19,2,4,NA,NA +69315,7,1,1,11,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15653.970322,0,1,91,6,6,1.13,6,6,1,3,0,1,40,1,4,6,NA +69316,7,2,2,17,NA,5,6,2,17,214,2,NA,2,2,2,12,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,7588.544207,7881.983727,3,91,4,4,0.69,5,5,0,2,0,1,45,2,4,1,1 +69317,7,2,2,3,NA,4,4,1,3,42,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10447.689164,11241.830083,1,102,7,7,1.8,5,4,1,0,2,1,47,1,3,5,NA +69318,7,2,1,4,NA,4,4,1,4,54,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11324.865632,11670.771889,2,96,2,2,0.44,3,3,2,0,0,2,22,1,2,5,NA +69319,7,2,1,42,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,18790.641284,19715.999527,2,100,15,1,0.05,4,1,0,2,0,1,42,1,3,5,NA +69320,7,2,2,58,NA,1,1,1,NA,NA,2,NA,2,2,2,NA,4,1,NA,2,2,2,1,2,2,NA,NA,NA,NA,29087.427528,29444.125326,1,101,3,3,0.41,5,5,0,2,1,2,36,2,4,4,NA +69321,7,2,1,55,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,21390.017054,21518.859775,2,99,15,15,5,2,2,0,0,0,2,51,1,5,1,5 +69322,7,2,1,34,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,22188.836739,24460.137584,1,92,4,4,0.61,5,5,1,2,0,1,34,1,3,6,NA +69323,7,2,1,63,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,7903.072331,8212.17704,2,99,NA,77,NA,3,2,0,0,1,1,63,1,3,5,NA +69324,7,2,1,42,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,153755.392794,158780.137655,1,91,15,15,5,3,3,0,0,0,2,50,1,4,1,4 +69325,7,2,2,36,NA,5,6,2,NA,NA,2,NA,2,2,7,NA,5,6,2,1,2,2,1,2,2,1,2,2,1,20039.469886,21176.851739,1,97,15,15,5,3,3,1,0,0,1,40,1,3,1,5 +69326,7,2,2,2,NA,5,6,1,2,33,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6213.806926,6511.003426,1,95,4,4,0.62,5,5,2,0,2,2,29,2,3,5,NA +69327,7,2,2,10,NA,3,3,2,10,131,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,55626.447796,54887.751745,1,95,15,15,5,4,4,0,2,0,2,42,1,5,1,5 +69328,7,2,2,71,NA,5,6,2,NA,NA,2,NA,2,1,8,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,13495.958207,13916.488113,1,96,9,9,4.23,2,2,0,0,2,2,71,2,5,1,5 +69329,7,2,2,50,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,42559.487719,42202.626733,1,98,3,2,0.62,2,1,0,0,0,2,50,1,2,3,NA +69330,7,2,2,24,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,2,1,2,2,1,2,2,NA,NA,NA,NA,23614.167119,30467.110717,2,97,1,1,0.33,2,2,1,0,0,2,24,1,2,5,NA +69331,7,2,2,13,NA,4,4,2,13,166,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10848.628906,11198.221038,1,99,4,4,0.41,7,7,2,4,0,2,43,1,4,4,NA +69332,7,2,1,15,NA,4,4,1,15,186,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17606.165994,20773.995354,2,101,9,9,2.46,4,4,0,2,0,1,42,1,3,1,3 +69333,7,2,2,76,NA,5,7,1,NA,NA,2,NA,2,1,5,NA,1,1,NA,1,2,2,1,2,2,1,2,1,NA,33487.945981,34633.22923,1,102,10,10,3.22,4,4,0,0,2,2,29,2,5,5,NA +69334,7,2,2,58,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,24938.6524,26291.237881,2,98,5,5,1.24,3,3,0,0,1,2,58,1,2,5,NA +69335,7,2,1,54,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,32720.69734,32838.149884,1,95,5,5,1.84,1,1,0,0,0,1,54,1,4,3,NA +69336,7,2,1,30,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,19401.570044,22254.979865,1,92,6,6,1.24,4,4,1,1,0,1,30,1,3,3,NA +69337,7,2,2,23,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,2,1,2,2,1,2,2,NA,NA,NA,NA,22912.222762,23105.605227,2,96,6,6,1.35,3,3,1,1,0,2,23,1,2,5,NA +69338,7,2,2,13,NA,1,1,1,13,164,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15690.47168,16249.379042,1,102,8,8,1.33,7,7,1,4,0,2,32,1,3,1,2 +69339,7,2,1,22,NA,1,1,1,NA,NA,2,NA,2,2,2,NA,1,6,NA,2,2,2,2,2,2,1,2,2,2,38560.502118,39812.43256,2,102,8,8,1.09,7,7,1,3,0,2,33,2,1,6,NA +69340,7,2,1,14,NA,5,6,2,14,179,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6666.045669,7091.184391,3,90,10,10,2.41,5,5,1,2,0,1,44,2,4,1,5 +69341,7,2,1,6,NA,1,1,1,7,84,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,11159.151566,11057.808004,1,102,2,2,0.31,4,4,1,2,0,2,25,1,2,4,NA +69342,7,2,1,23,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,16645.008535,17770.553389,2,95,2,2,0.4,2,2,0,0,0,2,43,1,1,1,NA +69343,7,2,1,20,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,118671.226879,120869.497653,2,91,15,15,5,3,3,0,0,0,2,54,1,4,1,4 +69344,7,2,1,21,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,25815.880139,26091.362984,2,101,5,5,1.5,2,2,0,0,0,1,47,1,4,3,NA +69345,7,2,1,11,NA,3,3,1,11,141,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18216.94614,18737.854061,1,94,3,3,0.39,6,6,2,2,0,2,25,1,4,1,2 +69346,7,2,1,18,NA,2,2,1,18,226,2,NA,2,2,4,13,NA,NA,NA,2,2,2,1,2,2,1,2,2,1,15506.325263,16662.012915,1,103,5,5,0.74,5,5,0,1,0,1,47,2,1,1,1 +69347,7,2,1,49,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,1,20137.063643,20085.335673,2,95,6,6,0.9,6,6,1,1,0,1,49,1,1,1,1 +69348,7,2,2,13,NA,3,3,1,13,166,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,31627.471241,33789.841724,1,98,6,6,1.11,5,5,1,2,0,2,32,1,2,1,2 +69349,7,2,1,74,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,59483.758768,62962.247193,1,96,14,14,5,2,2,0,0,2,1,74,1,5,1,4 +69350,7,1,2,77,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,12888.823036,0,2,99,7,7,3.13,1,1,0,0,1,2,77,1,5,2,NA +69351,7,2,2,31,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,66503.043118,69008.73133,2,98,7,7,1.94,3,3,1,0,0,2,31,1,4,1,NA +69352,7,2,1,0,10,1,1,1,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9064.168162,9228.63108,3,92,12,12,NA,4,4,2,0,0,1,30,1,3,1,4 +69353,7,2,2,2,NA,4,4,2,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7871.443574,8074.618887,1,96,9,9,2.88,3,3,1,0,0,1,27,1,3,1,5 +69354,7,2,1,42,NA,1,1,1,NA,NA,2,NA,2,2,6,NA,1,4,NA,2,2,2,1,2,2,2,2,2,2,34205.013302,34329.398365,2,102,7,7,1.04,7,7,1,2,0,2,37,2,1,1,2 +69355,7,2,2,27,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,3,6,2,1,2,2,1,2,2,NA,NA,NA,NA,44119.608456,46238.164206,2,98,1,1,0.14,3,2,2,0,0,2,27,1,3,6,NA +69356,7,2,2,62,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,11696.973403,11982.125462,2,101,5,5,1.08,3,3,0,1,1,2,62,1,4,2,NA +69357,7,2,1,8,NA,4,4,1,8,103,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,8894.789377,9317.745565,2,100,3,3,0.27,7,7,2,1,0,2,41,1,2,5,NA +69358,7,2,1,11,NA,3,3,1,11,134,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,41342.668304,42524.849071,1,102,8,8,2.42,4,4,0,2,0,2,34,1,4,1,3 +69359,7,2,1,8,NA,4,4,1,8,106,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9022.8939,9530.778148,2,100,3,3,0.31,7,7,3,2,0,2,28,1,3,1,3 +69360,7,2,2,0,0,5,7,1,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6280.554922,6238.355238,2,92,10,10,3.78,3,3,1,0,0,1,35,1,4,6,NA +69361,7,2,1,66,NA,4,4,1,NA,NA,2,NA,2,1,7,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,10209.064769,10089.274206,1,98,6,6,1.57,3,3,0,0,2,1,66,2,2,1,4 +69362,7,2,1,5,NA,4,4,1,5,67,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8892.687359,9565.637195,2,96,12,10,2.17,7,6,2,3,0,1,29,1,4,3,NA +69363,7,2,2,22,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,NA,NA,NA,NA,44119.608456,46238.164206,3,92,3,3,0.54,4,4,3,0,0,2,22,1,3,5,NA +69364,7,2,2,11,NA,1,1,1,11,143,NA,NA,1,1,NA,5,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,10118.363218,11093.371216,2,103,77,77,NA,7,7,0,4,0,1,38,2,1,6,NA +69365,7,2,2,59,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,1,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,185476.232403,190233.31946,1,95,4,4,1.47,1,1,0,0,0,2,59,1,1,5,NA +69366,7,2,2,73,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,89167.746947,90120.008289,1,95,15,15,5,2,2,0,0,2,1,72,1,3,1,4 +69367,7,2,1,2,NA,3,3,2,3,36,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,46257.816906,54201.886729,2,94,15,15,4.59,4,4,1,1,0,2,37,1,5,1,5 +69368,7,2,1,52,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,16851.334496,16952.838472,2,95,14,14,5,2,2,0,0,0,1,52,1,4,1,NA +69369,7,2,1,66,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,1,3,NA,1,2,2,1,2,2,1,2,2,1,6910.118936,7233.371983,2,95,2,2,0.63,1,1,0,0,1,1,66,1,1,3,NA +69370,7,2,1,17,NA,1,1,1,18,216,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,20560.901695,21038.44606,2,96,10,10,3.78,3,3,0,1,0,1,42,1,3,1,3 +69371,7,2,1,32,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,22650.334558,22327.472235,1,93,12,12,NA,5,1,0,2,0,1,32,1,2,5,NA +69372,7,2,1,24,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,23022.732862,22484.94345,2,102,5,3,0.92,5,1,2,1,0,1,24,1,4,6,NA +69373,7,2,2,20,NA,3,3,1,NA,NA,2,NA,2,2,2,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,114492.825466,119073.624167,2,101,3,2,0.73,3,1,0,0,0,2,20,2,4,5,NA +69374,7,1,2,52,NA,2,2,NA,NA,NA,2,NA,2,2,5,NA,1,6,NA,2,2,2,1,2,2,NA,NA,NA,NA,24004.6026,0,2,91,1,1,0.17,4,4,0,1,0,1,49,2,1,6,NA +69375,7,2,1,40,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,148501.534483,154474.828602,2,91,15,15,5,2,2,0,0,1,2,66,1,5,3,NA +69376,7,2,1,19,NA,3,3,1,19,236,2,NA,2,1,5,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,41421.091412,40909.179995,1,94,3,3,0.93,2,2,0,0,0,2,41,2,2,3,NA +69377,7,1,1,70,NA,5,6,NA,NA,NA,2,NA,2,1,3,NA,5,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,17564.38036,0,2,102,5,5,1.36,2,2,0,0,2,1,70,2,5,1,4 +69378,7,2,2,20,NA,2,2,2,NA,NA,2,NA,2,2,2,NA,3,5,2,2,2,2,1,2,2,2,2,2,2,39788.68078,43305.780488,2,99,3,3,0.52,3,3,0,0,1,2,38,2,3,3,NA +69379,7,2,1,30,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,22188.836739,22824.336433,1,92,1,1,0,2,1,0,0,0,1,30,1,3,6,NA +69380,7,2,1,20,NA,2,2,1,NA,NA,1,2,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,39915.513053,42587.888675,2,98,1,1,0.13,4,4,2,0,0,2,52,1,2,4,NA +69381,7,2,1,6,NA,2,2,1,6,77,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13837.588743,14145.695126,1,92,9,9,2.93,3,3,0,1,0,2,30,1,5,1,5 +69382,7,2,1,6,NA,5,6,2,6,79,NA,NA,2,2,1,0,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,9720.482616,11328.640802,2,91,99,99,NA,7,4,0,4,0,1,36,2,9,1,2 +69383,7,2,2,10,NA,5,7,2,10,127,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,5010.242859,5375.15147,3,91,15,15,4.47,4,4,0,3,0,2,44,2,5,1,NA +69384,7,2,1,7,NA,4,4,2,7,90,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10665.048307,10877.092316,1,96,4,4,1.12,2,2,0,1,0,2,44,1,2,5,NA +69385,7,2,1,12,NA,5,6,2,12,154,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6666.045669,7091.184391,3,90,77,77,NA,7,7,1,2,0,1,41,2,3,6,NA +69386,7,2,1,52,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,19541.667675,19738.253068,2,95,3,3,1.21,1,1,0,0,0,1,52,1,3,5,NA +69387,7,2,1,25,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,71632.519751,73567.29218,2,100,8,8,4.13,1,1,0,0,0,1,25,1,3,5,NA +69388,7,2,1,61,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,11568.876339,13082.418262,1,102,4,4,0.78,4,4,0,1,1,1,61,1,3,1,1 +69389,7,2,2,22,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,3,6,2,1,2,2,1,2,2,1,2,2,1,53638.260635,55237.528848,2,96,5,1,0.37,2,1,0,0,0,2,22,1,3,6,NA +69390,7,2,1,62,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,96485.877517,101155.423058,2,95,9,9,3.97,2,2,0,0,1,1,62,1,2,1,2 +69391,7,2,2,52,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,30868.065568,31427.853631,3,92,10,10,3.77,3,3,0,1,0,2,52,1,4,6,NA +69392,7,2,1,35,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,13147.594977,13793.622874,1,102,15,15,4.59,4,4,1,1,0,1,35,1,5,1,5 +69393,7,2,1,33,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,23511.361566,23589.086028,1,100,14,14,4.45,3,3,1,0,0,1,33,1,4,1,4 +69394,7,2,2,25,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,30275.274308,39061.30289,2,101,4,4,1.22,2,2,1,0,0,2,25,1,4,5,NA +69395,7,2,1,25,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,20813.587171,20953.352876,2,93,6,6,1.47,3,3,0,0,0,2,47,1,4,5,NA +69396,7,2,1,10,NA,4,4,2,10,127,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8439.71412,8914.772112,2,99,7,7,1.19,6,6,1,3,0,2,38,1,3,5,NA +69397,7,2,1,46,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,30152.053647,30291.005728,2,101,14,14,4.03,4,4,0,1,0,2,40,1,5,1,5 +69398,7,2,1,3,NA,4,4,1,3,37,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9016.053035,9388.597537,2,100,99,99,NA,6,6,2,1,0,2,44,1,3,1,4 +69399,7,1,1,58,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,25583.266805,0,1,100,10,10,4.63,2,2,0,0,1,1,58,1,5,1,4 +69400,7,2,1,45,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,NA,NA,NA,1,2,2,1,21600.805431,21945.582953,2,96,3,3,0.38,5,5,1,2,0,2,30,1,3,5,NA +69401,7,2,1,0,0,1,1,1,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,4724.065742,4677.378988,2,93,77,77,NA,7,7,3,1,0,2,43,2,1,1,9 +69402,7,2,2,59,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,14262.400197,16582.236492,1,93,14,14,5,2,2,0,0,0,1,36,2,5,1,NA +69403,7,2,1,61,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,115789.798768,119024.647099,1,90,6,6,2.86,1,1,0,0,1,1,61,1,5,3,NA +69404,7,2,1,57,NA,4,4,2,NA,NA,2,NA,2,1,7,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,20536.772571,20857.586819,1,90,15,15,5,2,2,0,0,0,1,57,2,4,1,5 +69405,7,2,1,59,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,152467.08796,155127.202914,1,91,8,8,2.17,4,4,0,0,0,1,59,1,4,1,5 +69406,7,2,1,16,NA,5,6,2,16,197,NA,NA,2,2,2,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,8168.705487,9098.657657,1,93,7,7,1.64,5,5,0,2,0,1,47,2,5,1,1 +69407,7,2,1,14,NA,5,6,1,14,173,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,1,1,2,2,1,6121.087833,6878.034577,2,92,7,7,1.17,6,6,0,1,1,1,78,2,1,1,3 +69408,7,2,2,16,NA,1,1,1,16,202,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,2,2,1,1,2,2,1,13963.420591,14243.160208,2,103,2,2,0.42,3,3,0,2,0,2,51,2,2,5,NA +69409,7,2,2,50,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,21605.242088,21013.957961,3,91,14,14,5,1,1,0,0,0,2,50,1,5,5,NA +69410,7,2,2,46,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,23409.362971,23343.581342,2,96,15,15,5,3,3,0,1,0,1,55,1,5,1,4 +69411,7,2,1,75,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,68266.732554,70856.701199,1,95,7,7,2.72,2,2,0,0,2,1,75,1,5,1,5 +69412,7,2,2,75,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,3,NA,1,2,2,1,2,2,1,2,2,NA,38833.86357,40362.1181,3,92,3,3,0.93,2,2,0,0,1,2,75,1,1,3,NA +69413,7,2,2,50,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,15521.115746,15477.500537,2,100,5,5,1.08,3,3,0,1,0,2,50,1,4,3,NA +69414,7,2,2,4,NA,3,3,2,4,56,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,51483.624552,56822.002088,1,91,4,4,1.29,2,2,1,0,0,2,26,1,4,5,NA +69415,7,2,2,15,NA,1,1,2,15,182,NA,NA,2,2,4,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18368.872199,18995.639955,2,94,12,12,NA,4,4,0,2,0,1,47,2,2,1,2 +69416,7,2,1,2,NA,5,6,2,3,37,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8100.706553,9085.828699,1,98,15,15,5,4,4,1,1,0,1,40,NA,NA,1,5 +69417,7,2,1,27,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,124091.929364,126503.690206,1,95,12,12,NA,6,6,2,0,0,2,42,1,2,1,5 +69418,7,2,1,71,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,60803.589953,64579.113865,1,91,15,15,5,2,2,0,0,2,1,71,1,5,1,4 +69419,7,2,1,57,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,25963.141347,25880.331023,1,92,10,10,4.3,2,2,0,0,0,2,55,1,4,1,5 +69420,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,NA,NA,NA,1,2,2,NA,60163.952904,72064.333099,1,97,NA,NA,NA,2,1,0,0,2,1,80,1,3,6,NA +69421,7,2,2,68,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,149765.47604,152732.36321,1,92,7,7,2.64,2,2,0,0,2,2,68,1,4,1,4 +69422,7,2,2,37,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,3,2,1,2,2,1,2,2,1,2,2,1,38477.954475,38315.213578,1,97,15,15,5,6,6,0,1,1,2,53,1,4,1,NA +69423,7,2,1,6,NA,3,3,1,6,74,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,58429.74688,62860.392832,1,100,6,6,1.78,3,3,1,1,0,2,35,1,5,4,NA +69424,7,2,1,4,NA,4,4,2,4,54,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7359.751824,8115.329859,2,99,5,5,1.26,3,3,1,0,0,2,50,2,3,5,NA +69425,7,2,2,66,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,15268.186173,15857.48365,1,102,14,14,5,2,2,0,0,2,1,65,2,5,1,5 +69426,7,2,2,14,NA,5,6,2,14,175,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11975.458482,12226.374363,1,97,14,14,2.87,5,5,0,3,0,2,40,2,5,1,5 +69427,7,2,1,44,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,18533.049642,18774.610796,1,99,3,3,0.54,3,3,1,0,0,2,29,1,4,1,4 +69428,7,2,2,42,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,33331.144292,35071.927834,1,101,7,7,2.71,2,2,0,0,0,1,43,1,4,1,4 +69429,7,2,2,18,NA,1,1,1,18,221,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,24481.187693,25353.22751,1,95,4,4,0.68,5,5,0,1,0,2,38,2,3,4,NA +69430,7,2,2,67,NA,5,6,1,NA,NA,2,NA,2,2,4,NA,1,1,NA,1,2,1,1,2,1,1,2,2,NA,14102.354333,14719.644428,3,91,14,4,1.02,6,2,0,0,2,1,48,2,1,1,1 +69431,7,2,2,79,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,12183.823561,12607.778632,2,100,9,9,4.35,2,2,0,0,2,2,79,1,5,1,3 +69432,7,2,1,0,5,4,4,2,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5782.580039,5871.334502,2,99,7,7,1.65,4,4,2,1,0,2,29,1,3,4,NA +69433,7,2,1,53,NA,1,1,1,NA,NA,2,NA,2,2,5,NA,1,1,NA,2,2,2,2,2,2,1,2,2,2,29883.483388,29823.443389,1,102,7,7,1.89,3,3,0,0,0,1,53,2,1,1,1 +69434,7,2,2,43,NA,1,1,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,40880.818805,42051.054889,1,101,4,4,0.84,3,3,0,1,0,1,42,1,4,1,4 +69435,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,47157.788417,52669.767304,2,95,15,15,5,2,2,0,0,2,1,80,1,5,1,5 +69436,7,2,1,46,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,28353.771379,28938.361413,1,92,8,8,4.66,1,1,0,0,0,1,46,1,4,5,NA +69437,7,2,2,6,NA,3,3,2,6,83,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,19880.837381,19616.828143,1,95,6,6,1.3,4,4,0,3,0,2,46,1,4,3,NA +69438,7,2,1,16,NA,3,3,2,16,201,NA,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,29222.804528,30590.757203,1,90,7,7,1.55,5,5,0,3,0,1,51,2,3,1,2 +69439,7,2,1,67,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,7903.072331,8272.775405,2,99,8,8,3.57,2,2,0,0,1,1,67,1,2,1,2 +69440,7,2,1,3,NA,5,6,2,3,46,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6940.398869,7784.416682,2,100,15,15,5,4,4,1,1,0,1,36,2,5,1,5 +69441,7,2,2,9,NA,3,3,2,9,110,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,62419.284609,61940.470984,1,101,14,14,4.5,3,3,0,1,0,1,39,1,2,1,5 +69442,7,2,1,19,NA,4,4,1,19,229,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,17606.165994,17558.40257,2,101,2,1,0.18,4,1,0,0,0,1,19,1,4,NA,NA +69443,7,2,2,29,NA,5,6,1,NA,NA,2,NA,2,2,5,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,11378.639129,11910.020755,1,102,15,15,3.82,5,5,1,1,0,1,29,1,4,1,4 +69444,7,2,2,2,NA,4,4,2,2,33,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7618.827213,8513.998744,2,97,5,5,1.63,2,2,1,0,0,2,33,1,3,5,NA +69445,7,2,2,41,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,2,1,2,2,1,2,2,1,2,2,1,18490.479848,17984.43936,2,100,3,3,0.27,7,7,2,1,0,2,41,1,2,5,NA +69446,7,2,1,25,NA,1,1,1,NA,NA,2,NA,2,2,3,NA,1,5,NA,2,2,2,1,2,2,1,2,2,2,38560.502118,39812.43256,2,102,5,5,0.59,7,7,1,3,0,1,37,2,1,6,NA +69447,7,2,2,13,NA,4,4,1,14,168,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,16659.324602,16974.753267,1,92,15,15,4.44,5,5,0,3,0,2,43,1,5,6,NA +69448,7,2,1,3,NA,4,4,1,3,41,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8892.687359,9565.637195,2,96,4,4,0.4,7,7,3,2,0,2,25,1,2,5,NA +69449,7,2,1,46,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,19260.892847,19877.962631,2,97,12,12,NA,3,3,0,0,0,1,33,1,4,5,NA +69450,7,2,2,39,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,93796.829073,96460.739647,1,100,15,15,5,4,4,1,1,0,1,40,1,5,1,5 +69451,7,2,1,67,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,7736.56115,7765.677873,1,99,13,13,NA,3,3,0,0,2,1,67,1,2,1,2 +69452,7,2,2,56,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,175633.860713,177416.12057,3,91,15,15,5,4,4,0,0,1,1,60,NA,NA,4,NA +69453,7,2,2,54,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,171038.159272,172773.783849,3,92,15,15,5,3,3,0,0,0,1,56,NA,NA,1,4 +69454,7,2,2,13,NA,4,4,2,13,158,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18163.985724,18749.311901,2,101,6,6,0.96,5,5,0,4,0,2,36,1,4,4,NA +69455,7,2,2,80,NA,3,3,1,NA,NA,2,NA,2,1,4,NA,3,1,NA,1,2,1,1,2,2,1,2,1,NA,49191.372812,61149.379277,3,91,15,15,3.33,6,6,0,2,2,1,80,2,3,1,3 +69456,7,2,1,52,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,21897.080981,21827.239495,3,91,12,12,NA,2,2,0,0,0,1,52,1,5,1,5 +69457,7,2,1,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,13408.721263,14895.884708,2,98,3,3,0.68,2,2,0,0,2,1,80,1,1,1,3 +69458,7,2,1,60,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,167711.394252,174540.034956,1,101,7,7,2.31,2,2,0,0,1,1,60,1,3,1,3 +69459,7,2,2,62,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,1,15207.312407,15896.113669,2,98,10,10,4.43,2,2,0,0,1,2,47,1,4,3,NA +69460,7,2,1,50,NA,2,2,2,NA,NA,2,NA,2,1,6,NA,1,1,NA,2,2,2,2,2,2,2,2,2,2,23259.140149,22917.848121,1,90,10,10,2.44,5,5,1,0,0,2,56,2,1,1,1 +69461,7,2,2,13,NA,5,6,2,13,160,NA,NA,1,1,NA,7,NA,NA,NA,1,1,1,1,2,1,1,2,2,1,6937.463063,7205.726089,3,90,15,15,3.23,6,6,0,2,0,1,50,2,2,1,2 +69462,7,2,2,36,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,4,2,1,2,2,1,2,2,1,2,2,1,42468.064168,42460.239922,2,101,6,6,0.96,5,5,0,4,0,2,36,1,4,4,NA +69463,7,2,1,20,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,27771.028362,29170.559675,3,92,4,4,1.16,2,2,0,0,0,2,20,1,2,1,2 +69464,7,2,1,39,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,105261.096488,116369.237268,1,97,15,15,5,4,4,0,2,0,1,39,1,5,1,NA +69465,7,2,2,50,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,134213.669088,137679.44344,1,93,7,7,2.16,3,3,0,1,0,2,50,1,5,3,NA +69466,7,2,2,8,NA,5,6,1,8,99,NA,NA,1,1,NA,3,NA,NA,NA,1,1,1,1,2,1,1,2,1,1,6189.617175,6489.651129,2,92,5,5,0.64,7,7,1,2,1,1,66,2,1,1,3 +69467,7,1,1,3,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,77702.196479,0,1,95,14,14,3.8,4,4,1,1,0,1,36,1,4,1,5 +69468,7,2,1,69,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,7736.56115,7645.782314,1,99,6,6,1.84,2,2,0,0,2,1,69,1,3,1,4 +69469,7,2,1,0,2,1,1,1,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,8519.229538,8996.978293,1,101,4,4,0.57,5,5,1,2,0,1,28,2,1,1,1 +69470,7,2,2,4,NA,1,1,1,4,51,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,16462.187772,17500.018071,3,92,7,7,1.3,5,5,1,2,0,2,33,2,2,1,1 +69471,7,2,2,72,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,62212.598767,64340.261278,1,94,14,14,5,2,2,0,0,2,2,72,1,5,1,5 +69472,7,2,1,38,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,18544.003944,19241.239961,2,100,14,14,3.76,4,4,1,1,0,1,38,1,3,1,NA +69473,7,2,1,79,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,8456.543684,8955.478754,2,92,7,7,3.13,1,1,0,0,1,1,79,1,1,2,NA +69474,7,2,2,66,NA,2,2,1,NA,NA,2,NA,2,2,5,NA,3,5,NA,2,2,2,1,2,2,1,2,2,2,11570.073931,12052.956309,2,93,7,7,1.74,4,4,1,0,1,2,24,NA,NA,4,NA +69475,7,2,2,24,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,20430.250572,20111.803159,2,97,5,5,0.76,5,5,0,0,0,2,50,1,4,5,NA +69476,7,2,2,0,5,4,4,2,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4584.111679,4588.281921,1,97,4,4,0.46,7,7,3,3,0,2,31,1,3,1,NA +69477,7,2,1,0,5,1,1,1,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,6390.260233,6748.618798,2,96,6,6,1,6,6,1,3,0,2,32,2,1,6,NA +69478,7,2,2,46,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,34874.122648,37228.07844,3,92,6,6,0.74,7,7,2,1,0,2,46,1,2,1,4 +69479,7,2,2,47,NA,1,1,1,NA,NA,2,NA,2,2,5,NA,1,1,NA,2,2,2,1,2,2,NA,NA,NA,NA,25713.328161,27565.019075,2,103,10,10,1.63,7,7,1,4,0,1,31,NA,NA,1,4 +69480,7,2,2,1,13,4,4,1,NA,13,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8480.466509,9125.076563,1,100,9,9,2.22,5,5,1,2,0,2,40,2,4,1,4 +69481,7,2,2,0,2,1,1,2,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,6787.112205,7016.795893,2,94,7,7,1.33,6,6,2,0,0,2,32,2,2,1,2 +69482,7,2,2,3,NA,1,1,1,3,41,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,17282.036547,19079.832121,2,102,3,3,0.45,4,4,2,0,0,1,21,2,2,6,NA +69483,7,2,1,4,NA,5,6,1,4,52,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10273.602479,10769.310961,1,92,77,77,NA,4,4,1,1,0,2,40,2,4,1,4 +69484,7,2,1,17,NA,1,1,1,17,210,2,NA,2,2,5,10,NA,NA,NA,2,2,2,2,2,2,1,2,2,1,19996.544021,19901.195571,1,100,7,7,1.3,5,5,0,3,0,1,43,2,2,1,4 +69485,7,2,1,0,0,3,3,2,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,22329.779038,21943.745693,1,98,14,14,3.93,3,3,1,0,0,1,36,1,5,1,5 +69486,7,2,2,67,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,11679.736252,12242.903977,1,103,8,8,4.66,1,1,0,0,1,2,67,1,5,3,NA +69487,7,2,1,21,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,14852.674152,15542.18804,1,92,14,14,3.9,4,4,0,0,0,2,55,2,5,1,5 +69488,7,2,2,65,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,33784.29429,34197.992084,1,95,5,5,1.3,3,3,0,0,1,2,19,1,3,NA,NA +69489,7,2,2,62,NA,5,6,2,NA,NA,2,NA,2,2,7,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,12941.046565,13394.767563,1,93,9,9,5,1,1,0,0,1,2,62,2,4,5,NA +69490,7,2,1,0,3,3,3,2,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,22795.485282,22401.400888,1,95,9,9,2.46,4,4,2,0,0,2,25,1,5,1,5 +69491,7,2,2,67,NA,2,2,2,NA,NA,2,NA,2,1,7,NA,1,2,NA,2,2,2,2,2,2,2,2,2,2,10490.803278,11351.088215,1,93,2,2,0.77,1,1,0,0,1,2,67,2,1,2,NA +69492,7,2,2,15,NA,4,4,2,15,185,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18163.985724,18905.695776,2,101,3,3,0.54,3,3,0,2,0,2,36,1,3,5,NA +69493,7,2,2,17,NA,4,4,2,17,209,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11711.384457,11558.024533,2,95,7,7,1.74,4,4,0,2,0,2,47,1,5,4,NA +69494,7,2,2,37,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,97803.500399,98104.213748,1,95,8,8,1.28,7,7,1,4,0,1,32,1,3,1,3 +69495,7,2,2,22,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,3,5,2,1,2,2,1,2,2,1,2,2,3,16239.242782,18510.062544,2,101,9,3,1.1,4,1,0,0,0,1,22,2,3,5,NA +69496,7,2,2,9,NA,4,4,2,9,116,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7631.175557,7916.380746,1,93,12,12,NA,3,3,0,1,0,2,48,1,3,5,NA +69497,7,2,1,26,NA,5,6,2,NA,NA,2,NA,2,1,4,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,13749.764747,14666.581717,1,90,4,4,0.78,4,4,0,0,1,1,69,2,4,1,3 +69498,7,2,1,31,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,59510.728426,64021.429591,1,99,15,15,5,3,3,1,0,0,2,31,1,5,1,5 +69499,7,2,2,42,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,129098.803996,133683.475932,1,93,15,15,5,4,4,0,2,0,2,42,1,5,1,NA +69500,7,2,1,19,NA,3,3,2,19,234,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,119111.433099,126517.990149,2,94,15,15,3.82,5,5,0,0,0,1,50,1,5,1,5 +69501,7,2,2,0,9,3,3,2,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10692.488346,11331.751026,1,101,2,2,0.22,4,4,1,0,0,2,25,1,4,6,NA +69502,7,2,2,50,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,143785.115498,143265.966876,1,99,8,8,4.87,1,1,0,0,0,2,50,1,5,5,NA +69503,7,2,2,44,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,2,1,2,2,1,2,2,1,2,2,1,35933.117795,41598.834451,1,98,2,2,0.72,1,1,0,0,0,2,44,1,4,3,NA +69504,7,2,1,54,NA,5,6,2,NA,NA,2,NA,2,1,4,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,13002.519536,13402.475336,1,93,15,15,4.59,4,4,0,2,0,2,45,1,5,1,5 +69505,7,2,1,60,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,6,NA,1,2,2,1,2,2,1,2,2,1,27043.072221,28144.17465,2,101,5,4,1.47,2,1,0,0,1,2,49,1,3,6,NA +69506,7,2,1,80,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,12256.510142,13615.881666,1,95,4,4,1.26,2,2,0,0,2,1,80,1,1,1,3 +69507,7,2,2,8,NA,5,6,2,8,103,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10699.45895,11290.011566,1,97,10,10,3.67,3,3,0,1,0,1,47,1,5,1,5 +69508,7,2,1,37,NA,1,1,2,NA,NA,2,NA,2,2,3,NA,1,1,NA,2,2,2,2,2,2,2,2,2,2,34887.439952,36924.956604,2,94,7,7,1.04,7,7,0,3,0,1,37,2,1,1,3 +69509,7,2,1,62,NA,2,2,2,NA,NA,2,NA,2,1,8,NA,1,1,NA,2,2,2,2,2,2,1,2,2,NA,8609.250304,11228.904188,2,90,4,4,1.02,2,2,0,0,1,1,62,2,1,1,1 +69510,7,2,1,19,NA,5,6,1,19,234,2,NA,2,1,4,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,6558.308393,6849.983523,2,92,99,1,0.28,4,1,0,0,0,1,19,1,4,NA,NA +69511,7,2,2,65,NA,4,4,1,NA,NA,2,NA,2,2,3,NA,2,4,NA,1,2,2,1,2,2,1,2,2,1,13998.494211,15077.525188,2,102,4,4,1.38,1,1,0,0,1,2,65,2,2,4,NA +69512,7,2,1,17,NA,3,3,2,17,213,2,NA,1,1,NA,12,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,17395.533107,17264.495057,1,99,13,13,NA,4,4,0,2,0,1,55,NA,NA,1,4 +69513,7,2,1,46,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,18533.049642,19320.837782,1,99,15,15,5,4,4,0,2,0,2,46,1,5,1,5 +69514,7,2,1,57,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,20181.678047,20475.67653,1,96,14,14,3.99,4,4,0,0,0,2,53,1,3,1,4 +69515,7,2,1,63,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,6612.194774,6663.917441,2,99,7,7,3.55,2,1,0,0,1,1,63,1,4,3,NA +69516,7,2,1,74,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,52448.388619,54438.22579,1,99,9,9,3.74,2,2,0,0,2,2,73,1,3,1,4 +69517,7,2,1,0,7,4,4,2,NA,7,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6246.568228,6652.820193,2,95,7,7,1.41,5,5,2,0,0,2,53,1,3,3,NA +69518,7,2,2,2,NA,4,4,2,2,29,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6226.488588,6570.976462,2,99,6,6,1.03,6,6,3,0,0,1,33,1,3,6,NA +69519,7,2,2,22,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,NA,NA,NA,NA,19520.240895,25185.107635,2,95,1,1,0.13,2,2,1,0,0,2,22,1,3,5,NA +69520,7,2,1,22,NA,3,3,1,NA,NA,2,NA,2,1,6,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,101419.325386,103801.228657,1,100,15,15,4.63,5,5,0,0,0,1,51,1,5,1,3 +69521,7,2,1,74,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,48254.793439,51076.634961,2,100,6,6,2.04,2,2,0,0,2,1,74,1,4,1,3 +69522,7,2,2,25,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,NA,NA,NA,NA,52701.331723,53172.517558,1,94,3,3,0.39,6,6,2,2,0,2,25,1,4,1,2 +69523,7,2,1,56,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,128128.531162,128588.454794,1,99,8,8,4.78,1,1,0,0,0,1,56,1,3,3,NA +69524,7,2,2,61,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,9518.80186,9943.806181,2,100,12,12,NA,2,2,0,0,1,1,56,1,5,1,4 +69525,7,2,2,44,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,18462.756377,17957.474615,1,99,2,2,0.48,2,2,0,0,0,2,44,1,3,1,3 +69526,7,2,1,19,NA,3,3,2,19,239,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,22313.526699,26201.091455,1,99,5,2,0.73,4,1,0,0,0,1,19,1,3,NA,NA +69527,7,2,1,25,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,39031.957066,39638.562591,1,95,6,4,1.47,2,1,0,0,0,2,28,1,2,6,NA +69528,7,2,1,80,NA,1,1,1,NA,NA,1,2,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,14673.422679,14929.213705,2,98,15,15,4.56,4,4,0,0,3,1,80,1,1,1,NA +69529,7,2,1,7,NA,3,3,2,8,97,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,82670.203859,85919.643529,1,97,14,14,3.36,4,4,0,2,0,2,49,1,5,1,5 +69530,7,2,2,9,NA,3,3,2,9,119,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,46660.163959,46766.329713,1,98,15,15,5,5,5,0,1,0,1,53,1,5,1,5 +69531,7,2,1,28,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,26847.643051,28917.411142,1,98,1,1,0.16,3,3,1,0,0,1,28,1,2,6,NA +69532,7,2,2,47,NA,5,6,2,NA,NA,2,NA,2,1,5,NA,3,1,NA,1,2,2,1,2,1,NA,NA,NA,NA,19150.604366,19847.194665,3,91,6,6,1.81,3,3,0,1,0,2,47,2,3,1,3 +69533,7,2,2,20,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,114993.808573,116714.079488,1,98,7,4,1.34,4,1,0,0,0,2,20,NA,NA,5,NA +69534,7,2,2,29,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,6,2,1,2,2,1,2,2,1,2,2,1,21503.272394,20634.528185,1,96,14,10,5,2,1,0,0,0,2,29,1,5,6,NA +69535,7,2,1,16,NA,5,7,1,16,199,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,59545.101745,58762.542429,1,102,8,8,1.6,7,7,0,4,0,2,39,1,4,1,4 +69536,7,2,2,57,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,126314.769628,126413.297707,2,95,8,8,3.53,2,2,0,0,0,1,57,1,4,1,4 +69537,7,2,1,49,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,140932.152825,151077.472396,1,97,15,15,5,4,4,0,2,0,1,49,1,5,1,5 +69538,7,2,2,19,NA,2,2,2,20,NA,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,26657.121865,27597.898247,1,97,15,15,5,3,3,0,0,0,1,45,1,4,1,3 +69539,7,2,1,80,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,27199.141352,29187.923269,1,98,7,7,3.58,1,1,0,0,1,1,80,1,2,2,NA +69540,7,2,2,45,NA,4,4,2,NA,NA,2,NA,2,1,6,NA,3,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,24625.307946,26182.57746,1,93,2,2,0.61,2,2,0,0,1,2,45,2,3,5,NA +69541,7,2,1,20,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,34952.089182,39581.970787,1,94,4,4,1,3,3,0,1,0,2,41,1,4,5,NA +69542,7,2,2,40,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,3,1,2,2,1,2,2,1,2,2,1,35126.205635,36772.568368,1,95,3,3,0.65,3,3,1,0,0,1,58,1,3,3,NA +69543,7,2,2,9,NA,4,4,1,9,112,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,9139.784234,9759.758014,2,100,14,14,4.86,3,3,0,1,0,2,41,1,4,3,NA +69544,7,1,2,16,NA,1,1,NA,NA,NA,NA,NA,1,1,NA,10,NA,NA,NA,2,2,2,1,2,2,NA,NA,NA,NA,20347.899985,0,2,94,5,5,0.65,6,6,0,2,0,1,53,NA,NA,6,NA +69545,7,2,2,17,NA,3,3,1,17,213,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,30430.369428,31312.351655,3,92,5,5,1.03,4,4,0,3,0,1,55,1,4,4,NA +69546,7,2,1,26,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,15976.466658,17286.192057,2,96,8,6,2.39,2,1,0,0,0,1,26,2,5,5,NA +69547,7,2,1,73,NA,4,4,2,NA,NA,2,NA,2,1,7,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,8543.37447,9341.78969,3,90,14,14,2.97,5,5,0,2,1,1,73,2,3,2,NA +69548,7,2,2,7,NA,4,4,2,8,96,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7710.907339,8302.634544,2,99,77,77,NA,4,4,1,1,0,2,47,1,2,77,NA +69549,7,2,2,66,NA,1,1,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,10429.953328,10902.368494,2,94,15,15,3.42,6,6,0,1,2,1,40,1,3,1,4 +69550,7,2,1,58,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,16287.780872,16385.890285,1,96,9,6,2.3,2,1,0,0,0,1,58,1,4,6,NA +69551,7,2,2,12,NA,4,4,1,12,148,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11838.873374,11750.256617,2,97,15,15,5,4,4,0,2,0,1,47,NA,NA,6,NA +69552,7,2,2,64,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,1,10999.00871,11813.793381,2,98,6,6,1.25,4,4,1,0,1,1,46,1,2,6,NA +69553,7,2,2,70,NA,2,2,2,NA,NA,2,NA,2,1,7,NA,1,1,NA,2,2,2,1,2,2,2,2,2,NA,15705.521724,21678.922586,3,90,12,12,NA,6,6,0,0,2,1,70,2,1,1,1 +69554,7,2,1,6,NA,4,4,1,6,73,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9344.689579,9327.120408,2,96,4,4,0.4,7,7,3,2,0,2,25,1,2,5,NA +69555,7,2,2,11,NA,4,4,2,11,136,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7282.523598,7776.514874,2,99,6,6,1.11,5,5,0,4,0,2,34,1,4,5,NA +69556,7,2,1,59,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,17738.246838,17681.670095,2,95,2,2,0.54,1,1,0,0,0,1,59,1,4,1,NA +69557,7,2,2,0,1,1,1,1,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8775.375504,8746.463784,2,102,14,14,3.58,4,4,2,0,0,1,25,2,3,1,1 +69558,7,2,2,27,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,2,1,2,2,1,2,2,1,2,2,1,47973.37979,51335.952518,1,101,7,7,1.82,4,4,2,0,0,2,27,1,2,1,3 +69559,7,2,2,8,NA,1,1,2,8,100,NA,NA,1,1,NA,2,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,14300.71869,15541.734563,2,94,9,9,2.1,5,5,1,2,0,1,31,2,4,1,4 +69560,7,2,1,26,NA,2,2,1,NA,NA,2,NA,2,2,3,NA,2,5,NA,2,2,2,2,2,2,1,2,2,1,59682.963348,66132.07802,2,102,5,5,1.08,3,3,0,0,0,1,55,2,1,5,NA +69561,7,2,2,19,NA,4,4,1,20,NA,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11224.041366,11682.365019,1,96,5,5,0.53,7,7,2,2,0,2,38,1,9,6,NA +69562,7,2,1,80,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,1,2,NA,27199.141352,29187.923269,1,98,77,77,NA,2,2,0,0,2,1,80,1,1,1,3 +69563,7,2,2,5,NA,5,6,1,5,67,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8818.200077,8968.551716,2,102,6,6,1.52,4,4,2,0,0,1,30,2,4,1,4 +69564,7,2,1,37,NA,4,4,2,NA,NA,2,NA,2,1,4,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,18743.758781,18547.428727,1,98,15,15,5,6,6,3,0,0,1,37,2,5,1,4 +69565,7,2,2,6,NA,2,2,2,6,72,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,10276.40638,10435.186077,2,99,99,99,NA,5,3,0,1,0,1,40,2,1,6,NA +69566,7,2,1,80,NA,2,2,1,NA,NA,2,NA,2,1,8,NA,1,1,NA,2,2,2,2,2,2,2,2,1,NA,13654.270555,14429.301836,2,93,12,12,NA,2,2,0,0,2,2,79,NA,NA,1,1 +69567,7,2,2,10,NA,3,3,1,10,122,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18800.96526,18551.296274,1,94,3,3,0.37,5,5,0,3,0,2,29,1,4,4,NA +69568,7,2,2,11,NA,4,4,1,11,137,NA,NA,2,2,2,3,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8504.389189,8822.229593,2,93,6,6,2.24,3,1,1,1,0,2,31,2,3,3,NA +69569,7,2,2,61,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,4,1,NA,1,2,1,1,2,1,1,2,1,3,17243.546687,17909.086027,1,92,6,6,2.15,2,2,0,0,2,2,61,2,4,1,5 +69570,7,1,1,8,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,73471.277275,0,2,101,8,8,1.72,5,5,0,3,0,1,37,1,3,1,3 +69571,7,2,1,19,NA,5,6,2,20,NA,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11506.937395,12032.024805,1,97,7,7,1.48,5,5,0,1,0,2,46,2,4,1,NA +69572,7,2,2,42,NA,5,6,2,NA,NA,2,NA,2,2,5,NA,4,4,2,1,2,1,1,2,1,NA,NA,NA,NA,13568.706187,14164.354411,3,90,8,4,1.61,3,1,0,0,1,2,68,2,2,4,NA +69573,7,2,2,53,NA,4,4,2,NA,NA,2,NA,2,1,5,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,15790.702799,16017.473382,2,90,2,2,0.48,2,2,0,0,1,2,53,2,3,1,3 +69574,7,2,2,48,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,163194.688032,166437.638141,1,97,14,14,4.96,2,2,0,0,0,1,59,1,4,1,5 +69575,7,2,2,12,NA,4,4,2,12,146,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11990.226944,12023.57752,2,95,2,2,0.26,3,3,0,2,0,2,31,1,3,5,NA +69576,7,2,1,2,NA,4,4,1,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7325.198118,7777.386797,1,100,13,13,NA,5,5,2,0,0,2,54,1,4,5,NA +69577,7,2,1,52,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,4,NA,1,2,2,1,2,2,1,2,2,1,18061.358948,18207.066814,2,93,3,3,1.07,1,1,0,0,0,1,52,1,3,4,NA +69578,7,2,2,6,NA,1,1,1,6,73,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15962.145468,16412.026403,2,98,2,2,0.35,3,3,0,1,0,2,43,1,3,1,3 +69579,7,2,2,4,NA,5,6,1,4,59,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6443.362832,6436.557151,1,98,15,15,5,3,3,1,0,0,2,37,2,5,1,5 +69580,7,2,1,23,NA,4,4,2,NA,NA,2,NA,2,2,2,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,20623.434727,20610.774284,1,93,3,3,0.7,3,3,1,0,0,1,23,2,4,1,2 +69581,7,2,1,23,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,16386.190684,16050.428992,2,90,15,15,5,4,4,0,0,0,1,57,2,5,1,5 +69582,7,2,2,30,NA,2,2,2,NA,NA,2,NA,2,7,77,NA,1,2,2,2,2,2,2,2,2,NA,NA,NA,NA,35353.005268,36684.976775,2,94,1,1,0.01,7,7,1,3,0,1,41,2,1,1,1 +69583,7,2,2,4,NA,5,6,2,4,58,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4962.240532,5199.576603,2,94,77,77,NA,6,6,2,0,0,2,18,1,3,NA,NA +69584,7,2,2,0,6,5,7,1,NA,7,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14926.308861,15231.47558,1,102,8,8,1.91,5,5,1,2,0,2,38,1,5,1,4 +69585,7,1,2,4,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,53166.229434,0,1,98,7,7,1,7,7,2,2,0,2,34,1,4,3,NA +69586,7,2,1,2,NA,4,4,2,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5255.532858,5319.636438,2,99,1,1,0.1,3,3,1,1,0,2,28,1,4,5,NA +69587,7,2,1,77,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,16823.6553,18089.239033,1,92,9,9,3.64,2,2,0,0,2,1,77,1,5,1,4 +69588,7,2,2,10,NA,3,3,2,10,127,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,66519.408962,66670.760406,1,98,15,15,4.34,4,4,0,2,0,1,51,1,5,1,5 +69589,7,2,1,0,2,3,3,2,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,17418.612172,17117.482228,1,91,14,14,5,3,3,1,0,0,2,30,1,5,1,5 +69590,7,2,2,19,NA,4,4,2,19,235,2,NA,1,1,NA,14,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12857.456314,12921.235691,2,97,4,4,0.81,4,4,1,0,0,2,51,1,2,4,NA +69591,7,2,2,27,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,122655.643802,123752.268878,3,91,15,15,5,2,2,0,0,0,1,29,1,4,1,4 +69592,7,1,1,16,NA,1,1,NA,NA,NA,NA,NA,2,2,3,10,NA,NA,NA,1,2,2,1,2,1,NA,NA,NA,NA,18242.832494,0,1,102,99,99,NA,5,5,0,2,1,1,52,2,1,1,1 +69593,7,2,2,1,18,4,4,2,NA,19,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6306.491784,6469.273037,2,90,9,9,3.18,3,3,1,0,0,2,38,2,4,5,NA +69594,7,2,1,31,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,22188.836739,22911.854766,1,95,6,6,1.09,5,5,0,3,0,1,31,1,4,1,4 +69595,7,2,2,3,NA,3,3,2,3,37,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,68579.013834,75690.025736,1,95,15,15,5,3,3,1,0,0,1,26,1,3,1,4 +69596,7,2,1,64,NA,4,4,2,NA,NA,2,NA,2,1,7,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,8219.195224,8283.488354,2,99,10,10,3.67,3,3,0,0,1,1,64,2,4,1,5 +69597,7,2,2,2,NA,5,6,2,2,32,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6075.554662,6069.137471,1,93,15,15,5,3,3,1,0,0,1,37,1,5,1,5 +69598,7,2,1,34,NA,3,3,2,NA,NA,2,NA,2,2,2,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,87891.395784,90408.650551,2,99,15,15,5,1,1,0,0,0,1,34,2,5,1,NA +69599,7,2,1,21,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,2,5,NA,2,2,2,1,2,2,1,2,2,1,42077.383821,44759.048785,1,102,4,4,0.67,4,4,0,1,0,1,23,2,4,5,NA +69600,7,2,1,65,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,6815.198656,6994.794831,3,90,15,15,4.34,4,4,0,0,1,1,65,1,3,1,4 +69601,7,2,1,17,NA,3,3,2,17,205,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,93665.036597,95017.313859,1,91,15,15,5,4,4,0,1,0,1,45,1,5,1,5 +69602,7,2,1,49,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,1,5,NA,1,1,2,2,1,2,1,1,2,NA,35406.972937,36103.049421,2,98,3,3,0.98,2,2,0,0,1,2,80,1,1,2,NA +69603,7,2,1,26,NA,1,1,2,NA,NA,2,NA,2,2,3,NA,2,1,NA,2,2,2,2,2,2,2,2,2,2,35669.2076,40318.090187,2,94,4,4,0.81,4,4,2,0,0,1,26,2,2,1,2 +69604,7,2,2,1,15,1,1,1,NA,16,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,1,1,2,1,NA,NA,NA,NA,14326.094268,14518.763259,3,92,4,4,0.65,4,4,2,0,0,2,24,2,2,1,2 +69605,7,2,1,12,NA,2,2,1,12,147,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14532.438529,15479.089621,2,93,14,14,3.52,5,5,1,2,0,1,44,1,5,1,5 +69606,7,2,2,11,NA,4,4,1,11,137,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10332.067017,11124.939356,1,100,12,12,NA,3,3,0,1,0,2,52,1,3,1,3 +69607,7,2,1,40,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,1,3,NA,1,2,2,1,2,2,1,2,2,1,32980.717958,34025.01199,1,95,2,2,0.46,1,1,0,0,0,1,40,1,1,3,NA +69608,7,2,1,75,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,NA,9662.124837,10964.58979,2,92,4,4,1.43,1,1,0,0,1,1,75,1,3,3,NA +69609,7,2,1,4,NA,4,4,2,4,53,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9885.965005,10187.921537,2,97,3,1,0.44,3,1,2,0,0,2,20,1,2,5,NA +69610,7,2,1,20,NA,5,7,1,NA,NA,2,NA,2,1,5,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,14385.653726,15040.55165,2,101,99,2,0.46,4,1,0,0,0,1,18,NA,NA,NA,NA +69611,7,2,2,8,NA,5,7,1,8,98,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9007.62445,9504.796896,2,102,15,15,5,4,4,0,2,0,1,39,1,4,1,5 +69612,7,2,2,15,NA,3,3,1,16,192,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,74658.856536,76060.378937,1,100,15,15,5,5,5,0,3,0,1,47,1,5,1,5 +69613,7,2,2,27,NA,5,6,2,NA,NA,2,NA,2,1,5,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,11739.283384,12336.327776,1,96,15,15,5,5,5,0,0,0,1,58,2,5,1,5 +69614,7,1,1,3,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,81535.075159,0,3,91,8,8,3.4,2,2,1,0,0,2,31,1,3,5,NA +69615,7,2,2,12,NA,1,1,1,12,150,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18515.058419,19360.671834,2,96,6,6,1.12,4,4,0,3,0,1,26,1,2,77,NA +69616,7,2,2,26,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,44672.331977,48301.986589,1,98,2,2,0.36,5,5,3,0,0,1,25,1,3,1,3 +69617,7,2,2,25,NA,3,3,1,NA,NA,2,NA,2,1,6,NA,4,3,2,1,2,2,1,2,2,1,2,2,1,97925.559493,100647.602701,1,91,15,6,2.69,3,1,0,0,0,1,27,1,3,6,NA +69618,7,2,2,64,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,127865.461733,133989.246473,1,101,4,4,1.26,2,2,0,0,2,1,62,1,3,1,3 +69619,7,2,2,41,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,4,2,1,2,2,1,2,2,1,2,2,1,19075.861607,18884.31701,1,96,6,6,1.21,4,4,0,2,0,2,41,1,4,4,NA +69620,7,2,1,49,NA,2,2,2,NA,NA,2,NA,2,1,7,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,31347.36219,32073.699502,2,90,6,6,1.21,4,4,0,0,0,2,59,2,1,6,NA +69621,7,2,1,35,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,1,30631.476666,32101.68524,2,101,8,8,2.81,3,3,0,1,0,1,35,1,1,1,2 +69622,7,2,1,58,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,27140.404673,28346.53309,1,95,5,5,1.1,3,3,0,0,1,2,63,1,4,1,5 +69623,7,2,1,4,NA,1,1,1,4,50,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,19411.993395,20798.549942,1,92,14,14,3.9,4,4,2,0,0,2,29,1,4,1,4 +69624,7,2,1,67,NA,5,6,1,NA,NA,2,NA,2,2,6,NA,3,1,NA,1,2,1,NA,NA,NA,1,2,1,3,11145.558675,11717.869264,2,96,NA,NA,NA,4,4,0,0,1,1,67,2,3,1,2 +69625,7,2,1,29,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,111450.827181,113182.912698,3,91,15,15,5,2,2,0,0,0,1,29,1,4,1,4 +69626,7,2,1,53,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,161135.312305,165002.304429,2,101,14,14,4.86,3,3,0,1,0,1,53,1,4,1,5 +69627,7,2,2,13,NA,4,4,2,13,158,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13621.250519,13659.137754,1,93,7,7,2.72,2,2,0,1,0,2,45,1,3,3,NA +69628,7,2,1,9,NA,1,1,1,9,116,NA,NA,2,2,3,3,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,14821.597351,14686.992722,3,92,6,6,0.86,7,7,1,4,0,2,36,2,1,1,1 +69629,7,2,2,16,NA,3,3,1,16,197,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,39616.634313,47751.80094,2,101,3,3,0.59,4,3,0,2,0,1,39,1,1,6,NA +69630,7,2,1,23,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,33592.259589,34050.148008,1,103,7,7,0.51,7,7,3,4,0,1,54,2,1,1,1 +69631,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,1,2,1,2,2,1,2,2,NA,29183.224814,31443.714435,1,95,7,7,2.3,3,3,0,0,2,1,80,1,4,1,2 +69632,7,2,1,44,NA,2,2,2,NA,NA,1,2,2,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,31640.296506,32279.766727,2,94,8,8,2.01,4,4,1,1,0,1,44,2,4,1,4 +69633,7,2,1,38,NA,1,1,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,42890.643983,44071.237251,1,98,15,15,5,5,5,2,1,0,1,38,1,4,1,5 +69634,7,2,2,14,NA,2,2,2,14,174,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,22139.315046,23195.552704,3,91,6,6,0.83,6,6,1,3,0,1,37,1,4,1,4 +69635,7,2,2,56,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,175997.804296,180603.118894,1,101,7,7,2.31,2,2,0,0,1,1,60,1,3,1,3 +69636,7,2,1,2,NA,2,2,1,3,37,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10136.626471,10860.663695,2,100,14,14,3.58,4,4,1,1,0,1,33,1,4,1,5 +69637,7,2,2,58,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,189736.955264,194603.321172,1,98,6,6,2.6,1,1,0,0,0,2,58,1,2,3,NA +69638,7,2,2,5,NA,3,3,1,5,62,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,53166.229434,56500.79967,1,98,7,7,1.66,5,5,2,1,0,2,37,1,5,1,3 +69639,7,1,1,48,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,20480.361635,0,2,99,6,6,2.69,1,1,0,0,0,1,48,1,3,5,NA +69640,7,2,2,23,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,2,1,2,2,1,2,2,1,2,2,1,14883.664782,16969.371761,2,90,5,5,1.08,3,3,1,1,0,2,23,1,2,5,NA +69641,7,2,2,23,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,1,2,1,2,2,NA,NA,NA,NA,109290.289961,113677.204054,1,100,15,15,5,3,3,0,0,0,1,53,1,5,1,4 +69642,7,2,1,19,NA,4,4,1,19,232,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,17606.165994,17558.40257,2,101,1,1,0.05,1,1,0,0,0,1,19,1,4,NA,NA +69643,7,2,2,0,10,1,1,1,NA,10,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7565.515117,8068.295221,1,100,3,3,0.43,4,4,2,0,0,1,20,1,3,6,NA +69644,7,2,2,64,NA,5,6,1,NA,NA,2,NA,2,2,4,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,11838.431472,12295.352662,2,94,8,8,1.8,6,6,0,1,2,1,74,2,5,1,5 +69645,7,2,2,71,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,49260.413155,50771.674072,2,100,99,99,NA,2,2,0,0,2,1,72,1,4,1,4 +69646,7,2,1,9,NA,3,3,2,10,120,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,82670.203859,86374.629723,1,97,15,15,4.07,5,5,0,3,0,1,36,1,5,1,5 +69647,7,2,1,36,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,113559.363135,116811.761686,2,102,14,14,3.44,5,5,1,2,0,2,34,1,4,6,NA +69648,7,2,1,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,32471.790416,34987.007487,2,96,15,15,5,2,2,0,0,2,2,80,2,5,1,5 +69649,7,2,1,27,NA,5,6,1,NA,NA,2,NA,2,2,3,NA,5,5,NA,1,2,2,1,2,2,1,2,2,3,14385.653726,15533.829525,2,101,7,5,1.84,2,1,0,0,0,1,27,2,5,5,NA +69650,7,2,1,48,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,36244.629058,36151.524069,1,98,3,2,0.72,2,1,0,0,0,2,50,1,2,3,NA +69651,7,2,1,15,NA,4,4,1,15,185,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18120.648572,18071.489418,1,100,3,3,0.43,4,4,0,2,0,1,35,1,4,1,3 +69652,7,2,2,74,NA,5,6,1,NA,NA,2,NA,2,1,8,NA,1,1,NA,1,2,1,1,2,1,1,2,1,NA,12833.793728,13278.897744,2,92,5,5,1.08,3,3,0,0,2,1,46,NA,NA,5,NA +69653,7,2,1,28,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,108410.783716,111887.48668,1,94,9,9,3.14,3,3,1,0,0,1,28,1,5,1,5 +69654,7,2,1,20,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,23484.626749,23642.328802,2,96,14,14,4.26,3,3,0,0,0,1,20,1,4,5,NA +69655,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,22419.63376,27869.657009,1,94,2,2,0.72,1,1,0,0,1,2,80,1,3,2,NA +69656,7,2,1,62,NA,4,4,2,NA,NA,2,NA,2,2,7,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,7514.993062,8122.478925,2,90,14,14,4.59,3,3,0,0,1,2,56,2,3,1,1 +69657,7,2,2,4,NA,5,6,1,4,56,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6899.969666,7508.722153,1,94,10,10,3.04,4,4,2,0,0,2,30,1,4,1,5 +69658,7,2,1,73,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,11034.04089,11250.172797,2,95,14,14,5,2,2,0,0,2,1,73,1,5,1,4 +69659,7,2,2,12,NA,3,3,2,12,151,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,42712.452836,43268.322789,2,94,3,3,0.95,2,2,0,1,0,2,45,1,5,3,NA +69660,7,2,1,66,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,NA,NA,NA,NA,NA,NA,NA,11764.405491,12715.399053,1,97,NA,NA,NA,7,7,0,3,1,2,47,NA,NA,1,NA +69661,7,2,2,57,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,1,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,11446.604914,11507.133903,2,92,3,3,0.45,4,4,0,0,1,1,64,2,1,1,1 +69662,7,2,2,7,NA,1,1,2,7,93,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,14300.71869,14671.891945,2,94,7,7,1.17,6,6,1,2,0,2,30,2,3,6,NA +69663,7,2,1,3,NA,3,3,1,4,48,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,78932.667512,89054.807173,3,92,14,14,2.74,6,6,2,2,0,1,35,1,5,1,4 +69664,7,2,1,3,NA,5,6,2,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5492.796032,5932.072263,2,100,14,14,3.06,5,5,1,0,1,2,31,2,5,1,5 +69665,7,2,2,50,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,16058.142925,15728.179634,2,101,7,7,1.3,5,5,2,0,1,2,50,1,4,1,3 +69666,7,2,2,70,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,69047.315371,69784.701831,1,95,8,8,2.7,3,3,0,1,2,1,69,1,5,1,3 +69667,7,2,2,63,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,118611.064701,118209.809508,1,91,8,8,3.4,2,2,0,0,2,1,66,1,5,1,4 +69668,7,2,1,61,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,120367.559207,121496.443862,2,95,15,15,5,2,2,0,0,1,1,61,1,5,1,5 +69669,7,2,2,66,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,1,9680.216878,10112.428208,1,96,15,15,5,1,1,0,0,1,2,66,1,5,2,NA +69670,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,60148.377616,67408.231176,1,92,6,6,1.98,2,2,0,0,2,1,80,1,5,1,4 +69671,7,2,2,58,NA,2,2,2,NA,NA,2,NA,2,2,7,NA,1,4,NA,2,2,2,2,2,2,2,2,1,2,20130.149569,20235.126587,1,90,99,99,NA,6,6,0,3,0,2,58,2,1,4,NA +69672,7,2,1,69,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,2,1,NA,1,2,1,1,2,1,1,2,1,3,5201.567667,5487.342926,2,92,10,6,1.12,7,4,1,1,1,2,27,2,3,1,3 +69673,7,2,2,2,NA,4,4,2,2,32,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6247.52442,6810.692829,1,99,10,10,2.07,7,7,2,3,1,2,35,1,5,4,NA +69674,7,2,1,60,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,7736.56115,7645.782314,1,99,8,8,1.76,5,5,0,2,1,1,37,1,4,1,3 +69675,7,2,2,58,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,1,24977.658912,25631.246482,2,95,5,5,1.52,2,2,0,0,0,2,58,1,2,2,NA +69676,7,2,1,5,NA,2,2,1,5,69,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16632.464801,16654.939181,1,94,2,2,0.26,4,4,2,1,0,2,25,1,4,5,NA +69677,7,2,1,13,NA,4,4,1,13,157,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13653.432599,13680.426553,2,96,5,5,1.07,4,4,0,3,0,2,46,1,4,3,NA +69678,7,2,2,1,18,1,1,1,NA,20,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13464.808163,14865.509546,1,101,9,9,2.88,3,3,1,0,0,1,36,2,2,1,4 +69679,7,2,1,26,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,17420.978407,17095.959542,2,100,8,8,3.06,2,2,0,0,0,1,26,1,5,1,5 +69680,7,2,1,37,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,16058.989596,16124.245459,2,97,3,3,0.33,6,6,2,0,0,2,32,1,2,1,3 +69681,7,2,1,4,NA,4,4,2,4,52,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7299.892005,7750.518524,2,99,9,9,1.78,6,6,1,1,0,1,46,1,3,6,NA +69682,7,2,1,67,NA,2,2,2,NA,NA,2,NA,2,1,8,NA,1,2,NA,2,2,2,2,2,2,1,2,2,NA,8609.250304,11228.904188,2,90,4,4,1.02,2,2,0,0,1,1,67,2,1,2,NA +69683,7,2,1,8,NA,4,4,2,9,108,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8017.552697,8398.795399,1,99,10,10,2.07,7,7,2,3,1,2,35,1,5,4,NA +69684,7,2,1,65,NA,2,2,1,NA,NA,2,NA,2,1,4,NA,1,3,NA,2,2,2,2,2,2,2,2,2,2,9404.30514,9554.950099,2,93,3,3,0.58,4,4,0,1,1,1,65,2,1,3,NA +69685,7,2,2,17,NA,1,1,1,17,205,2,NA,2,2,3,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,24654.448233,25524.546766,2,96,6,6,1.12,4,4,0,1,0,1,57,2,1,1,4 +69686,7,2,1,5,NA,1,1,1,5,67,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,17048.276421,17071.31266,1,94,5,5,0.87,4,4,1,1,0,1,35,2,1,1,1 +69687,7,2,2,47,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,141912.982157,152670.471787,1,97,15,15,5,4,4,0,2,0,1,49,1,5,1,5 +69688,7,2,1,42,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,4,NA,1,2,2,1,2,2,NA,NA,NA,NA,17036.36313,17063.789746,1,99,14,14,5,1,1,0,0,0,1,42,1,4,4,NA +69689,7,2,1,51,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,15413.22404,15402.649971,1,97,15,15,5,4,4,0,0,0,1,51,2,5,1,5 +69690,7,2,2,2,NA,3,3,2,2,27,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,37915.354974,40293.39486,2,91,15,15,5,5,5,1,2,0,1,37,1,4,6,NA +69691,7,2,2,36,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,24919.497762,30093.052062,1,101,1,1,0.08,6,6,0,1,0,1,51,1,2,5,NA +69692,7,2,1,50,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,2,4,NA,1,2,2,1,2,2,1,2,2,1,29903.342494,29985.789069,1,95,12,5,1.84,4,1,0,0,0,1,29,1,3,6,NA +69693,7,2,2,37,NA,1,1,2,NA,NA,2,NA,1,1,NA,NA,4,3,2,1,2,2,1,2,2,1,2,2,1,43463.010321,44104.658285,1,98,6,6,1.98,2,2,0,1,0,2,37,1,4,3,NA +69694,7,2,1,15,NA,4,4,2,15,191,NA,NA,1,1,NA,10,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9757.309092,9852.859452,1,96,15,15,5,6,6,1,1,1,2,44,1,3,1,3 +69695,7,2,1,80,NA,4,4,2,NA,NA,2,NA,2,1,9,NA,9,3,NA,1,2,2,1,2,2,1,2,2,NA,8992.410435,9337.125921,2,90,4,4,1.54,1,1,0,0,1,1,80,2,9,3,NA +69696,7,2,2,56,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,32144.824104,32969.273278,2,97,3,3,1.1,1,1,0,0,0,2,56,1,2,3,NA +69697,7,2,2,22,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,23845.8146,22808.13483,1,98,12,2,0.54,4,1,0,0,0,1,21,1,4,6,NA +69698,7,2,1,49,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,20851.046913,21183.857295,2,99,2,2,0.19,6,6,0,1,0,1,59,1,2,5,NA +69699,7,1,1,11,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10229.206765,0,1,96,14,14,2.96,5,5,0,3,0,1,46,NA,NA,1,5 +69700,7,2,2,27,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,3,5,3,1,2,2,1,2,2,NA,NA,NA,NA,42583.505439,50840.190326,2,91,2,2,0.42,3,3,1,1,0,2,27,1,3,5,NA +69701,7,2,1,52,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,17636.923031,17665.316481,2,101,6,6,2.57,1,1,0,0,0,1,52,1,3,5,NA +69702,7,2,1,42,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,97539.00155,100726.587936,1,99,77,77,NA,3,3,0,0,0,1,42,1,4,6,NA +69703,7,2,1,0,3,4,4,1,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7441.732415,8231.273488,2,98,3,3,0.54,3,3,1,1,0,2,29,1,2,1,NA +69704,7,2,1,30,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,109181.566304,114466.270601,2,91,15,3,1.07,7,1,0,0,1,1,49,NA,NA,5,NA +69705,7,2,1,42,NA,4,4,1,NA,NA,2,NA,2,2,4,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,17221.349323,18312.731752,1,103,8,8,1.95,4,4,0,1,0,2,48,1,5,1,5 +69706,7,2,2,9,NA,5,6,1,9,110,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,8290.163782,8692.019106,1,92,2,2,0.24,5,5,0,2,0,1,35,2,4,1,3 +69707,7,2,2,4,NA,4,4,2,4,56,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12736.176535,13301.727395,1,97,15,15,5,4,4,1,1,0,1,35,1,5,1,5 +69708,7,2,1,14,NA,1,1,1,14,179,NA,NA,1,1,NA,8,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,15469.666055,15805.71937,2,92,12,12,NA,7,7,0,1,2,2,64,2,1,2,NA +69709,7,2,2,62,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,128065.93322,127632.692688,1,98,4,4,1.52,1,1,0,0,1,2,62,1,4,5,NA +69710,7,2,2,28,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,51744.846443,52360.821424,1,97,4,3,0.93,3,2,0,0,0,1,35,1,3,1,4 +69711,7,2,2,51,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,16675.763807,16530.996917,2,95,8,8,1.85,5,5,1,2,0,1,55,1,2,1,3 +69712,7,2,1,31,NA,5,6,2,NA,NA,2,NA,2,1,5,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,23631.037942,24059.753898,1,91,9,9,5,1,1,0,0,0,1,31,2,5,5,NA +69713,7,2,1,17,NA,2,2,2,17,207,2,NA,1,1,NA,12,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,24585.624844,25010.051033,3,91,6,6,0.83,6,6,1,3,0,1,37,1,4,1,4 +69714,7,2,1,18,NA,4,4,1,18,226,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,17606.165994,17558.40257,2,101,99,99,NA,4,1,0,0,0,1,18,1,4,NA,NA +69715,7,2,2,43,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,4,2,1,2,2,1,2,2,1,2,2,1,15598.269927,16258.702668,1,99,4,4,0.41,7,7,2,4,0,2,43,1,4,4,NA +69716,7,2,2,63,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,126687.376548,128757.240271,1,101,9,9,2.6,4,4,0,1,2,2,63,1,4,1,4 +69717,7,2,1,3,NA,1,1,1,3,37,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,19476.194601,19502.51153,2,102,15,15,5,4,4,2,0,0,1,32,1,5,1,5 +69718,7,2,2,15,NA,3,3,1,15,182,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,82923.224369,87859.866176,2,100,8,8,2.91,3,3,0,2,0,2,48,1,5,1,NA +69719,7,2,1,3,NA,3,3,2,3,39,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,31190.854587,34157.026846,1,95,2,2,0.22,4,4,2,1,0,2,22,1,2,5,NA +69720,7,2,2,3,NA,4,4,1,3,40,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10437.988787,10901.48845,2,100,5,5,0.94,4,4,2,0,0,2,33,1,4,6,NA +69721,7,2,2,22,NA,4,4,2,NA,NA,2,NA,2,2,2,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,14500.122872,13786.884381,1,96,10,10,1.8,7,7,1,1,0,1,57,2,1,1,3 +69722,7,2,1,7,NA,4,4,2,7,86,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7758.863533,8127.805304,2,99,3,3,0.42,6,6,1,2,0,2,43,1,4,6,NA +69723,7,2,2,9,NA,3,3,2,9,117,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,22371.648216,22397.198208,1,92,4,4,0.61,5,5,1,2,0,1,34,1,3,6,NA +69724,7,2,1,58,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,28585.875492,28917.983006,1,91,5,5,1.2,3,3,0,0,1,1,58,1,2,1,2 +69725,7,2,1,5,NA,3,3,1,5,62,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,73006.119819,82368.252941,1,101,14,14,3.15,5,5,2,1,0,1,35,1,4,1,5 +69726,7,1,1,53,NA,3,3,NA,NA,NA,1,2,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,30582.99679,0,1,97,4,3,1.07,2,1,0,0,1,2,66,NA,NA,5,NA +69727,7,2,1,4,NA,5,6,1,4,55,NA,NA,2,2,2,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7042.228842,7250.600343,2,103,9,9,3.14,3,3,1,0,0,1,32,2,5,1,5 +69728,7,2,1,35,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,20071.705576,20986.552878,3,91,14,14,5,2,2,0,0,0,1,35,2,5,1,5 +69729,7,2,2,3,NA,4,4,2,3,37,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10389.292229,11178.99433,2,101,7,7,1.3,5,5,2,0,1,2,50,1,4,1,3 +69730,7,2,2,70,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,NA,11194.560864,11943.741966,2,95,5,5,1.88,1,1,0,0,1,2,70,1,3,3,NA +69731,7,2,2,19,NA,4,4,1,19,236,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,18163.985724,18749.311901,2,101,99,1,0.02,2,1,0,0,0,2,19,1,4,NA,NA +69732,7,2,1,33,NA,5,6,2,NA,NA,2,NA,2,1,3,NA,5,1,NA,1,2,1,1,2,1,1,2,1,3,12327.761744,13173.339372,3,90,5,5,0.93,4,4,1,0,0,1,48,2,4,1,NA +69733,7,1,1,67,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,7117.971973,0,2,100,3,3,0.75,2,2,0,0,2,1,67,1,3,1,2 +69734,7,2,1,26,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,74110.989124,87044.270957,2,95,8,8,4.48,1,1,0,0,0,1,26,1,5,5,NA +69735,7,2,1,20,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,14949.232836,15463.9021,1,100,99,99,NA,6,6,0,1,0,1,53,2,2,1,3 +69736,7,2,2,21,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,29040.300396,28462.118402,2,101,1,1,0.14,4,1,0,0,0,2,21,1,4,5,NA +69737,7,2,1,31,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,58170.292683,59516.479078,3,92,8,8,2.36,3,3,0,0,0,1,34,NA,NA,5,NA +69738,7,2,2,51,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,34802.051557,35120.431265,1,101,4,4,1.16,2,2,0,1,0,2,51,1,4,3,NA +69739,7,2,2,21,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,NA,NA,NA,NA,17260.508485,17587.688781,2,97,6,6,1.02,6,6,1,2,0,1,37,1,3,1,3 +69740,7,2,2,66,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,95538.505899,97099.44822,2,95,14,14,5,2,2,0,0,2,2,66,1,5,1,5 +69741,7,2,1,10,NA,1,1,1,10,129,NA,NA,1,1,NA,4,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,17882.621856,17720.218058,3,92,3,3,0.51,5,5,1,2,0,2,34,2,1,6,NA +69742,7,2,1,4,NA,5,6,2,4,55,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6138.820061,6885.358348,1,99,10,10,4.76,2,2,1,0,0,2,36,2,5,3,NA +69743,7,2,1,46,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,28813.038041,29276.135189,1,94,7,7,1.65,5,4,0,0,0,1,46,1,4,1,4 +69744,7,1,1,12,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13416.172328,0,1,96,14,14,2.96,5,5,0,3,0,1,46,NA,NA,1,5 +69745,7,2,2,50,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,27005.036261,27122.782392,1,102,1,1,0,3,1,0,0,1,2,50,1,3,3,NA +69746,7,2,2,43,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,115926.402585,118970.086068,1,101,15,15,5,4,4,0,2,0,1,43,1,4,1,5 +69747,7,2,2,34,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,3,2,1,2,2,NA,NA,NA,1,2,2,1,21229.081867,21886.919672,3,90,5,5,0.87,4,4,0,0,0,2,43,2,3,5,NA +69748,7,2,2,50,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,160743.928829,162404.084268,1,95,7,7,2.86,2,2,0,0,0,2,50,1,3,1,3 +69749,7,2,1,12,NA,2,2,2,12,151,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,16033.31661,17623.465787,2,90,5,5,0.76,5,5,0,4,0,2,32,1,2,3,NA +69750,7,2,1,44,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,79677.823556,83116.431703,1,99,15,15,4.47,4,4,0,2,0,2,43,1,5,1,5 +69751,7,2,2,0,5,1,1,2,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6787.112205,6644.319314,2,94,8,8,2.43,3,3,1,0,0,1,24,2,4,1,4 +69752,7,2,2,79,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,81062.798322,83549.725067,1,101,4,4,1.75,1,1,0,0,1,2,79,1,5,2,NA +69753,7,2,2,63,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,14204.126838,14796.942631,1,92,5,5,1.41,2,2,0,0,2,1,60,1,2,1,4 +69754,7,2,1,80,NA,4,4,2,NA,NA,2,NA,2,1,5,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,10160.645851,10359.669924,1,96,77,77,NA,7,7,0,3,1,2,43,77,5,5,NA +69755,7,2,2,65,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,156359.467613,158914.124584,2,102,14,14,5,2,2,0,0,2,2,65,1,5,1,5 +69756,7,2,1,2,NA,4,4,1,2,33,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4778.010882,5139.584556,2,93,99,99,NA,7,6,1,0,0,1,19,1,3,NA,NA +69757,7,2,1,19,NA,5,7,2,19,229,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11125.932433,11147.929312,1,96,10,10,3.04,4,4,0,1,0,2,43,1,5,1,4 +69758,7,2,2,42,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,3,2,1,2,2,1,2,2,1,2,2,1,21127.557839,23583.17383,1,102,4,4,0.97,3,3,0,1,0,2,19,1,2,NA,NA +69759,7,2,1,51,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,4,NA,1,2,2,1,2,2,1,2,2,1,32720.69734,32838.149884,1,95,1,1,0.18,1,1,0,0,0,1,51,1,4,4,NA +69760,7,2,1,5,NA,4,4,2,5,65,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9446.305539,9734.833129,2,95,1,1,0,4,4,2,1,0,2,27,1,4,5,NA +69761,7,2,2,80,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,14859.685983,15314.825218,1,95,3,3,0.96,1,1,0,0,1,2,80,1,2,2,NA +69762,7,2,1,15,NA,1,1,1,15,190,NA,NA,2,2,3,9,NA,NA,NA,2,1,2,1,2,2,2,2,2,2,24230.15013,23997.357824,3,92,6,6,0.86,7,7,1,4,0,2,36,2,1,1,1 +69763,7,2,2,6,NA,4,4,2,6,81,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7282.523598,8846.731146,2,99,5,5,0.76,5,5,0,2,0,1,51,1,2,1,2 +69764,7,2,2,22,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,18097.801029,17328.248994,2,100,14,14,3.06,5,5,1,0,0,1,50,1,5,1,5 +69765,7,2,2,65,NA,2,2,2,NA,NA,2,NA,2,1,8,NA,3,3,NA,2,2,2,1,2,2,1,2,1,2,11495.911371,12347.505602,2,99,3,3,0.52,3,3,0,0,1,2,38,2,3,3,NA +69766,7,2,2,4,NA,2,2,1,4,54,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15979.952759,16987.381382,2,102,14,14,3.25,5,5,2,0,0,1,27,1,5,1,5 +69767,7,2,1,56,NA,5,7,2,NA,NA,1,2,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,151766.599459,154414.492891,3,91,7,7,1.97,4,4,0,0,1,2,77,1,5,2,NA +69768,7,2,2,20,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,23845.8146,23041.888919,1,98,3,2,0.81,4,1,0,0,0,2,21,NA,NA,5,NA +69769,7,2,2,0,4,3,3,2,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,21671.775435,21083.121886,1,98,7,7,1.83,3,3,1,0,0,2,26,1,5,1,4 +69770,7,2,2,24,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,6,2,1,2,2,1,2,2,1,2,2,1,13495.651715,13078.348337,2,99,NA,77,NA,7,7,1,0,1,2,51,1,2,1,3 +69771,7,2,1,3,NA,5,6,2,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,10276.262805,11525.953064,1,97,15,15,5,4,4,2,0,0,2,35,2,4,1,4 +69772,7,2,2,3,NA,4,4,2,3,39,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11671.9972,12190.293097,1,93,4,4,1.03,3,3,1,1,0,2,35,2,3,4,NA +69773,7,2,1,40,NA,4,4,1,NA,NA,2,NA,2,1,5,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,23242.990557,23331.304109,1,100,9,9,2.22,5,5,1,2,0,2,40,2,4,1,4 +69774,7,2,1,54,NA,2,2,2,NA,NA,2,NA,2,1,6,NA,2,1,NA,2,2,2,2,2,2,2,2,2,2,20167.650721,25203.089486,3,90,12,7,3.58,2,1,0,0,1,1,71,2,2,1,NA +69775,7,2,1,8,NA,2,2,2,8,101,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15039.041447,15306.786696,3,91,6,6,0.83,6,6,1,3,0,1,37,1,4,1,4 +69776,7,2,1,57,NA,1,1,2,NA,NA,2,NA,2,2,7,NA,1,1,NA,2,2,2,2,2,2,2,2,2,2,22446.308035,22116.943066,2,94,7,7,1.33,6,6,0,1,0,1,55,2,2,1,1 +69777,7,2,2,60,NA,1,1,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,10003.290711,10218.574955,1,99,10,10,2.58,5,5,0,1,2,1,65,1,5,1,3 +69778,7,2,1,42,NA,1,1,2,NA,NA,2,NA,2,2,5,NA,3,6,NA,2,2,2,2,2,2,2,2,2,2,31640.296506,31576.726829,2,94,9,9,4.21,3,2,0,0,0,2,48,2,2,6,NA +69779,7,2,1,13,NA,3,3,2,13,166,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,77169.155154,76948.022242,1,98,14,14,3.9,4,4,0,3,0,2,31,1,4,1,NA +69780,7,2,1,9,NA,3,3,2,9,118,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,66868.503099,69864.859716,1,98,14,14,3.15,5,5,0,3,0,1,34,1,4,1,4 +69781,7,2,1,0,10,3,3,2,NA,10,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,26076.0211,27915.503824,2,91,15,15,5,4,4,2,0,0,2,33,1,5,1,5 +69782,7,2,1,52,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,20075.522681,20698.300141,2,98,77,77,NA,1,1,0,0,0,1,52,1,3,5,NA +69783,7,2,2,66,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,13023.675419,13480.293434,2,96,2,2,0.55,1,1,0,0,1,2,66,2,5,5,NA +69784,7,2,1,69,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,10717.375231,11218.730451,2,101,2,2,0.64,1,1,0,0,1,1,69,1,2,5,NA +69785,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,22419.63376,25250.873067,1,94,3,3,1.08,1,1,0,0,1,2,80,1,2,2,NA +69786,7,2,2,1,22,3,3,1,NA,23,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,46813.021927,47428.160802,1,94,15,15,4.77,4,4,2,0,0,1,48,1,4,1,5 +69787,7,2,2,57,NA,2,2,1,NA,NA,2,NA,2,1,9,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,22969.116046,23893.408664,2,93,9,9,3.97,2,2,0,0,1,2,57,2,3,1,1 +69788,7,2,1,14,NA,2,2,1,14,169,NA,NA,1,1,NA,6,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,30061.88611,30025.949584,1,92,6,6,0.93,5,5,0,2,0,1,47,2,1,1,1 +69789,7,2,2,53,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,16181.169973,15916.061734,2,100,99,99,NA,1,1,0,0,0,2,53,1,2,3,NA +69790,7,2,1,12,NA,5,6,1,12,146,NA,NA,1,1,NA,6,NA,NA,NA,1,1,1,1,2,1,1,2,2,1,6886.223812,7737.788899,2,92,7,7,1.61,4,4,0,2,0,1,51,2,3,1,3 +69791,7,1,2,63,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,30036.804187,0,2,100,4,4,1.29,2,2,0,0,2,1,65,1,3,1,3 +69792,7,2,1,5,NA,4,4,1,5,66,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11324.865632,11670.771889,2,96,3,3,0.54,4,4,2,1,0,2,25,1,4,2,NA +69793,7,2,1,35,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,20181.692021,20449.370526,1,92,2,2,0.24,5,5,0,2,0,1,35,2,4,1,3 +69794,7,2,1,9,NA,2,2,1,10,120,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8889.501355,9473.596146,2,93,14,14,3.52,5,5,1,2,0,1,44,1,5,1,5 +69795,7,1,2,80,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,1,2,1,2,2,NA,NA,NA,NA,16321.652472,0,2,101,1,1,0.08,2,2,0,0,2,2,80,1,1,2,NA +69796,7,2,2,3,NA,4,4,1,3,47,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11990.08101,12901.460915,1,100,15,15,3.87,6,6,1,3,0,2,39,1,4,1,4 +69797,7,2,2,31,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,1,1,2,2,1,2,2,1,2,2,1,74517.751389,77393.175383,2,94,14,14,3.36,4,4,2,0,0,1,31,1,3,1,5 +69798,7,2,2,21,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,65591.951555,69705.816211,2,101,2,2,0.46,2,1,0,0,0,2,21,1,4,5,NA +69799,7,2,2,8,NA,4,4,2,8,96,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7814.742747,8587.431439,2,95,7,7,1.55,5,5,0,3,0,1,30,1,4,1,4 +69800,7,2,1,10,NA,5,6,2,10,131,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6262.834446,6755.01452,3,90,77,77,NA,7,7,1,2,0,1,41,2,3,6,NA +69801,7,2,2,3,NA,5,6,2,3,36,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,3864.413878,3822.111022,1,99,14,14,2.66,7,7,3,1,0,1,35,1,5,1,5 +69802,7,2,2,17,NA,3,3,1,17,207,2,NA,1,1,NA,12,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,36586.371708,39087.782259,1,101,4,4,0.58,6,6,0,4,0,2,41,1,3,5,NA +69803,7,2,1,44,NA,5,6,2,NA,NA,2,NA,2,1,8,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,19184.316833,20543.822351,1,97,15,15,5,4,4,1,1,0,1,44,2,5,1,5 +69804,7,2,1,6,NA,3,3,1,6,80,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,47373.769078,49181.31317,1,103,15,15,5,3,3,0,1,0,1,46,1,5,1,5 +69805,7,2,1,1,19,5,6,1,NA,19,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6389.003009,6767.308805,3,91,14,14,3.06,5,5,3,0,0,1,34,2,5,1,5 +69806,7,2,1,75,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,8763.51401,8935.17143,2,100,6,6,1.62,3,3,0,0,2,1,75,1,5,1,NA +69807,7,2,2,61,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,10083.559248,10533.779383,1,96,14,14,4.06,3,3,0,0,1,2,61,1,4,5,NA +69808,7,1,1,80,NA,4,4,NA,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,1,2,1,2,2,NA,NA,NA,NA,7041.644998,0,2,100,13,13,NA,2,2,0,0,2,2,77,1,3,1,4 +69809,7,2,1,4,NA,4,4,2,4,51,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8973.990262,9344.796725,2,95,1,1,0.09,5,5,3,1,0,2,31,1,2,1,NA +69810,7,2,2,14,NA,2,2,1,14,178,NA,NA,2,2,2,9,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,15809.066118,16348.490248,2,93,5,5,1.26,3,3,0,1,0,1,55,2,2,1,2 +69811,7,2,1,59,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,4,NA,1,2,2,1,2,2,1,2,2,1,124170.603852,124019.195449,2,98,6,6,2.75,1,1,0,0,0,1,59,1,4,4,NA +69812,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,47636.23298,52171.746701,1,91,9,9,4.27,2,2,0,0,2,1,80,1,4,1,3 +69813,7,2,2,30,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,28351.482206,28369.098474,1,96,9,9,3.35,3,3,0,0,0,2,42,1,4,5,NA +69814,7,2,2,15,NA,2,2,2,15,187,NA,NA,1,1,NA,9,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,18368.872199,19023.186366,2,91,10,10,2.95,4,4,0,1,0,2,18,1,3,NA,NA +69815,7,2,2,70,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,15205.189409,15734.277598,2,96,7,7,2.72,2,2,0,0,1,2,70,1,4,2,NA +69816,7,2,2,20,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,20000.263815,22894.1152,1,102,12,12,NA,7,7,3,2,0,2,52,1,4,5,NA +69817,7,2,1,33,NA,5,7,2,NA,NA,2,NA,2,1,5,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,16045.513116,17473.610556,1,90,6,6,0.92,6,6,2,0,2,2,30,2,5,1,5 +69818,7,2,2,19,NA,5,6,1,20,NA,2,NA,1,1,NA,15,NA,NA,NA,1,2,1,NA,NA,NA,1,2,2,1,9278.834813,9462.75742,1,92,2,2,0.33,5,5,0,1,0,1,51,2,1,4,NA +69819,7,2,2,11,NA,3,3,1,11,140,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,71426.628275,70878.719996,2,101,10,10,2.33,6,6,1,3,0,1,39,1,2,1,4 +69820,7,2,2,6,NA,1,1,1,7,84,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15962.145468,16664.698857,2,98,6,6,0.63,7,7,2,2,1,1,60,1,3,1,2 +69821,7,2,2,66,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,7869.59899,8476.202883,2,100,1,1,0.14,1,1,0,0,1,2,66,1,3,2,NA +69822,7,2,1,64,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,1,1,NA,1,2,1,1,2,1,1,2,1,3,8636.698123,9111.200197,2,92,3,3,0.45,4,4,0,0,1,1,64,2,1,1,1 +69823,7,2,2,55,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,18441.731082,18102.807884,2,100,1,1,0,2,2,0,0,0,2,55,1,5,3,NA +69824,7,2,1,64,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,2,1,NA,1,2,1,1,2,1,1,2,1,3,8275.049402,8531.146449,1,99,6,6,1.07,6,6,2,1,2,1,44,2,5,4,NA +69825,7,2,2,43,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,139800.409559,140918.856987,1,100,15,15,5,5,5,0,3,0,1,47,1,5,1,5 +69826,7,2,1,3,NA,3,3,2,3,47,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,20717.313101,23374.052614,2,97,5,5,0.8,5,5,1,2,0,1,46,2,4,1,2 +69827,7,2,1,30,NA,2,2,2,NA,NA,2,NA,2,2,4,NA,2,4,NA,2,2,2,2,2,2,1,2,1,2,27605.196104,27396.850962,2,99,12,77,NA,5,1,0,1,0,1,30,2,2,4,NA +69828,7,2,2,18,NA,4,4,2,19,228,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,NA,NA,NA,1,2,2,1,13176.946531,13078.313981,2,99,6,3,0.94,3,2,0,0,0,1,41,1,3,6,NA +69829,7,2,1,18,NA,4,4,1,18,221,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,19844.605924,19989.134915,2,102,14,14,4.05,3,3,0,1,0,1,18,1,2,NA,NA +69830,7,2,2,4,NA,2,2,1,4,56,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,13301.733639,13724.969642,2,93,3,3,0.48,4,4,1,1,0,1,49,2,3,1,4 +69831,7,2,2,80,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,1,2,NA,1,2,1,1,2,1,1,2,1,NA,13689.379977,14234.742701,2,92,2,2,0.88,1,1,0,0,1,2,80,2,1,2,NA +69832,7,2,1,61,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,1,7074.645577,7351.348885,2,95,7,7,3.31,1,1,0,0,1,1,61,1,3,2,NA +69833,7,2,2,73,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,29534.722322,30544.805853,3,91,77,77,NA,2,2,0,0,2,1,73,1,5,1,5 +69834,7,1,2,37,NA,5,6,NA,NA,NA,2,NA,2,1,5,NA,5,1,3,1,2,2,1,2,2,NA,NA,NA,NA,13379.422066,0,2,103,14,14,3.86,4,4,2,0,0,2,37,2,5,1,NA +69835,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,35334.703093,40990.264786,1,101,2,2,0.63,1,1,0,0,1,2,80,1,1,2,NA +69836,7,2,1,1,21,3,3,1,NA,21,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,35290.29852,40086.22326,1,102,14,14,2.87,5,5,3,0,0,1,35,1,5,1,5 +69837,7,2,2,9,NA,1,1,1,9,114,NA,NA,1,1,NA,3,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,15962.145468,16535.37648,2,98,3,3,0.33,7,7,2,3,0,1,40,2,1,1,1 +69838,7,2,1,31,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,30626.581617,36447.669921,2,90,6,6,1.35,3,3,1,0,0,1,31,1,3,1,4 +69839,7,2,2,8,NA,1,1,1,8,97,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,2,2,2,1,2,2,NA,15841.451259,17367.937444,3,92,4,4,0.55,6,6,0,4,0,1,36,2,1,1,3 +69840,7,2,1,67,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,6910.118936,6964.172059,2,95,6,4,1.5,2,1,0,0,1,1,67,1,4,3,NA +69841,7,2,1,16,NA,1,1,2,16,199,NA,NA,2,2,3,10,NA,NA,NA,2,2,2,2,2,2,2,2,2,2,21633.039913,21721.097793,2,94,7,7,1.04,7,7,0,3,0,1,37,2,1,1,3 +69842,7,2,1,37,NA,1,1,2,NA,NA,2,NA,2,2,6,NA,4,1,NA,2,2,2,1,2,2,2,2,2,2,34887.439952,35849.951626,2,94,6,6,1.34,4,4,0,2,0,1,37,2,4,1,2 +69843,7,2,1,40,NA,5,6,2,NA,NA,2,NA,2,2,5,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,19184.316833,20543.822351,1,97,15,15,5,4,4,2,0,0,1,40,2,5,1,5 +69844,7,2,1,6,NA,1,1,1,6,76,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,11770.89642,11957.164501,2,96,5,5,0.68,6,6,0,3,2,1,60,2,1,1,1 +69845,7,2,2,15,NA,3,3,2,15,186,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,29885.567338,31265.78413,1,94,7,7,0.94,7,7,1,4,0,2,46,2,5,1,5 +69846,7,2,1,23,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,100807.076657,102674.431164,1,97,15,15,4.77,4,4,0,0,0,1,56,1,4,1,4 +69847,7,2,1,80,NA,5,6,2,NA,NA,2,NA,2,1,9,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,14603.225127,15344.674112,1,98,15,15,5,2,2,0,0,2,1,80,2,5,1,NA +69848,7,2,1,70,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,15417.485683,15656.172471,1,92,3,3,0.98,2,2,0,0,1,1,70,1,2,1,2 +69849,7,2,1,70,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,9257.537917,9255.717695,1,99,7,6,1.84,3,2,0,0,2,1,70,1,2,1,4 +69850,7,2,2,10,NA,1,1,2,10,123,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,15225.935813,16547.241996,2,94,7,7,1.57,4,4,0,2,0,1,30,2,3,1,4 +69851,7,2,2,31,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,18901.436377,19544.076782,3,91,14,14,5,2,2,0,0,0,1,35,2,5,1,5 +69852,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,35434.580514,39416.921733,1,95,4,4,1.47,1,1,0,0,1,2,80,1,3,1,NA +69853,7,2,1,10,NA,4,4,2,10,128,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8227.856305,9153.104022,3,91,1,1,0.07,6,6,2,3,0,2,30,1,2,3,NA +69854,7,2,1,65,NA,5,7,2,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,168185.448935,166468.676858,1,95,10,10,4.76,2,2,0,0,2,1,65,1,4,1,4 +69855,7,2,2,41,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,11762.034222,12708.069605,3,90,15,15,5,4,4,0,2,0,2,41,2,5,1,5 +69856,7,2,1,37,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,78240.016337,83257.203545,1,93,15,15,5,3,3,1,0,0,1,37,1,5,1,5 +69857,7,2,1,16,NA,5,7,2,16,203,NA,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,21852.102821,22875.024578,3,91,5,5,0.65,7,7,0,4,0,2,39,1,3,4,NA +69858,7,2,1,65,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,9655.271429,9541.978936,1,95,9,9,4.21,2,2,0,0,1,1,65,1,5,1,4 +69859,7,2,2,2,NA,4,4,2,2,32,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9503.429019,9925.429486,1,91,3,3,0.66,4,4,1,2,0,2,33,1,3,5,NA +69860,7,2,2,18,NA,4,4,1,18,222,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11224.041366,11682.365019,1,96,5,5,0.53,7,7,2,2,0,2,38,1,9,6,NA +69861,7,2,2,73,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,15852.523312,16085.826144,2,97,6,6,2.04,2,2,0,0,2,2,80,1,3,2,NA +69862,7,2,2,35,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,75772.894935,76005.871473,1,94,15,15,5,2,2,0,0,0,1,29,1,4,1,5 +69863,7,2,1,43,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,28337.446334,29138.677291,2,95,14,14,3.34,4,4,0,0,0,1,43,1,3,1,3 +69864,7,2,1,52,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,25583.266805,26390.249407,1,100,12,99,NA,2,1,0,0,0,2,50,1,3,6,NA +69865,7,2,2,4,NA,3,3,1,5,60,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,28877.220658,31871.522389,1,94,6,6,1.21,4,4,2,0,0,1,27,1,2,1,2 +69866,7,2,1,63,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,1,1,NA,1,2,1,1,2,1,1,2,1,3,12579.986433,13337.268472,1,92,1,1,0.26,2,2,0,0,2,1,63,2,1,1,1 +69867,7,2,2,50,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,17521.481386,17363.561951,2,97,15,12,NA,2,1,0,0,0,1,54,1,4,5,NA +69868,7,2,1,40,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,2,6,NA,2,2,2,2,2,2,1,2,2,2,31740.385214,32919.784432,2,96,5,5,0.89,4,4,1,1,0,2,36,2,4,6,NA +69869,7,2,2,36,NA,2,2,1,NA,NA,2,NA,2,2,3,NA,1,6,2,2,2,2,1,2,2,NA,NA,NA,NA,38218.668882,37878.487888,2,102,5,5,0.59,7,7,1,3,0,1,37,2,1,6,NA +69870,7,2,1,68,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,131818.641085,133509.443669,1,102,15,15,5,2,2,0,0,2,2,68,1,4,1,5 +69871,7,2,2,1,22,1,1,2,NA,23,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,12602.647442,12772.138116,1,91,99,99,NA,4,4,2,1,0,2,36,2,2,4,NA +69872,7,2,1,39,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,105412.227726,110446.221907,2,101,10,10,2.33,6,6,1,3,0,1,39,1,2,1,4 +69873,7,2,1,22,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,20135.920214,20700.031916,2,97,2,2,0.27,3,3,1,0,0,2,21,1,3,6,NA +69874,7,2,2,3,NA,3,3,2,3,40,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,78448.332626,86582.701959,2,91,15,15,5,4,4,2,0,0,2,33,1,5,1,5 +69875,7,2,2,45,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,2,1,NA,1,2,1,1,2,1,1,2,1,3,11762.034222,11824.231183,3,90,15,15,3.23,6,6,0,2,0,1,50,2,2,1,2 +69876,7,2,2,36,NA,1,1,2,NA,NA,2,NA,2,1,3,NA,3,1,2,2,2,2,2,2,2,2,2,2,2,35353.005268,34399.106917,2,94,7,7,1.04,7,7,0,3,0,1,37,2,1,1,3 +69877,7,2,2,38,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,2,3,2,1,2,2,1,2,2,NA,NA,NA,NA,19257.047323,21540.196698,1,102,5,5,1.27,3,3,0,2,0,2,38,1,2,3,NA +69878,7,2,2,15,NA,5,7,1,15,189,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15844.005605,16354.571478,1,100,7,7,1.83,3,3,0,1,0,2,40,1,4,6,NA +69879,7,2,1,22,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,104488.914565,106745.836574,1,98,4,2,0.56,4,1,0,0,0,1,22,1,5,5,NA +69880,7,2,2,34,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,NA,NA,NA,NA,102720.446375,103036.277703,2,102,14,14,3.44,5,5,1,2,0,2,34,1,4,6,NA +69881,7,2,1,12,NA,2,2,1,12,155,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18242.832494,18053.229058,1,102,77,77,NA,6,6,0,2,1,2,37,1,4,1,4 +69882,7,2,2,14,NA,4,4,1,14,179,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11791.755593,11850.248564,2,96,7,7,1.04,7,7,0,4,0,2,37,1,3,3,NA +69883,7,2,2,14,NA,1,1,2,14,172,NA,NA,1,1,NA,8,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,23979.296993,29080.570096,1,101,5,5,0.51,7,7,0,3,2,1,75,2,1,1,1 +69884,7,2,1,56,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,18916.732604,18903.754992,2,91,8,8,2.34,4,4,0,2,0,1,56,2,5,1,5 +69885,7,2,2,42,NA,4,4,2,NA,NA,2,NA,2,2,3,NA,5,3,2,1,2,2,1,2,2,1,2,2,1,19075.861607,19022.257361,1,96,9,9,2.78,4,4,0,2,0,1,54,2,5,4,NA +69886,7,2,2,5,NA,2,2,1,5,67,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,2,2,2,NA,NA,NA,NA,15979.952759,16987.381382,2,102,4,4,0.57,6,6,2,3,0,2,26,2,3,1,NA +69887,7,2,2,23,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,17260.508485,16474.419641,2,97,3,3,0.33,6,6,2,0,0,2,32,1,2,1,3 +69888,7,2,1,36,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,19384.896286,19940.089683,1,94,3,3,0.8,2,2,0,0,1,2,66,1,4,3,NA +69889,7,2,1,13,NA,4,4,2,13,163,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13975.179508,14076.961252,1,96,15,15,5,4,4,0,2,0,1,46,1,5,1,5 +69890,7,2,1,5,NA,3,3,1,5,71,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,76114.759421,89186.300704,1,98,15,15,4.34,4,4,1,1,0,1,41,1,5,1,5 +69891,7,2,1,79,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,8992.410435,11769.853451,2,90,10,10,4.76,2,2,0,0,1,1,79,1,2,2,NA +69892,7,2,2,63,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,1,8521.670488,9178.537312,2,95,4,4,1.34,1,1,0,0,1,2,63,1,3,2,NA +69893,7,2,1,22,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,32866.0119,33575.905633,1,98,12,4,1.52,3,1,0,0,0,2,22,NA,NA,5,NA +69894,7,2,2,3,NA,3,3,2,3,44,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,27257.164734,28966.726071,1,95,4,4,0.65,6,6,2,2,0,2,36,1,4,6,NA +69895,7,1,1,17,NA,3,3,NA,NA,NA,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,NA,NA,NA,NA,68701.580401,0,2,94,14,14,2.87,5,5,2,1,0,1,37,1,3,1,4 +69896,7,2,1,49,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,146181.198007,148606.927767,2,91,15,6,2.86,7,1,0,0,1,1,49,NA,NA,5,NA +69897,7,2,2,1,16,1,1,1,NA,17,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14326.094268,15816.39252,3,92,7,7,2.1,3,3,1,1,0,2,25,1,4,5,NA +69898,7,2,1,71,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,19473.412374,20212.213332,1,95,6,6,2.04,2,2,0,0,2,1,71,1,3,1,4 +69899,7,2,2,33,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,6,2,1,2,2,1,2,2,1,2,2,1,30664.033268,30444.919975,2,102,5,5,0.67,6,6,0,4,0,2,33,1,2,6,NA +69900,7,2,2,40,NA,1,1,1,NA,NA,2,NA,2,2,5,NA,2,1,2,1,2,2,1,2,2,1,2,2,NA,31334.47528,33406.965231,2,96,7,7,1.79,4,4,0,2,0,1,43,2,3,1,2 +69901,7,2,1,17,NA,1,1,1,17,214,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,20638.769105,20614.097145,2,92,15,15,3.37,7,7,0,4,0,1,42,2,3,1,1 +69902,7,2,2,48,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,19130.246369,18964.171442,2,95,8,8,1.61,6,6,1,3,0,2,48,1,3,5,NA +69903,7,2,1,3,NA,1,1,1,3,47,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,1,1,2,2,NA,NA,NA,NA,17865.135763,18076.339981,3,92,7,7,1.41,5,5,1,2,0,1,20,2,1,1,1 +69904,7,2,2,16,NA,2,2,2,16,198,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,14437.97544,15197.369043,2,90,7,7,1.66,4,4,0,3,0,2,34,1,5,3,NA +69905,7,2,1,65,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,1,1,2,1,1,2,1,3,9596.331248,10123.555774,2,92,8,8,2.43,3,3,0,1,1,2,58,NA,5,1,5 +69906,7,2,1,42,NA,1,1,2,NA,NA,2,NA,2,2,4,NA,1,1,NA,2,2,2,1,2,2,2,2,2,2,41410.39303,40802.759347,1,101,12,3,1.07,3,1,0,0,0,1,41,2,1,4,NA +69907,7,2,1,8,NA,1,1,2,8,100,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,11417.89405,11689.28796,2,97,4,4,0.6,6,6,2,2,0,1,35,2,2,6,NA +69908,7,1,2,0,9,4,4,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4090.43871,0,2,99,6,6,1.73,3,3,1,1,1,2,60,1,4,3,NA +69909,7,2,2,15,NA,5,6,1,15,185,NA,NA,2,1,2,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11626.310625,12128.832209,1,92,7,7,1.56,4,4,0,2,0,2,38,2,4,6,NA +69910,7,2,1,20,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,102928.893739,104528.537732,1,101,6,6,0.97,7,7,2,1,0,1,43,1,2,1,NA +69911,7,2,2,80,NA,2,2,2,NA,NA,2,NA,2,1,8,NA,3,2,NA,1,1,2,2,2,2,NA,NA,NA,NA,16490.79781,19016.592593,3,90,8,8,3.21,2,2,0,0,2,2,80,2,3,2,NA +69912,7,2,2,8,NA,4,4,2,8,103,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6388.247052,6617.403229,1,93,6,6,0.83,6,6,3,1,0,1,37,NA,NA,1,3 +69913,7,2,2,64,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,1,1,NA,1,2,1,1,2,1,1,2,1,NA,14102.354333,16246.228018,3,91,6,6,1.12,4,4,0,0,2,1,69,2,3,1,1 +69914,7,2,1,11,NA,3,3,2,11,138,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,46081.129115,51016.6207,2,95,9,9,2.6,4,4,0,2,0,1,42,1,4,1,4 +69915,7,2,1,6,NA,4,4,2,7,84,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,7970.311962,8205.827749,1,90,14,14,2.96,5,5,1,2,0,1,31,1,5,1,4 +69916,7,2,2,22,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,2,5,2,1,2,2,2,2,2,1,2,2,1,35710.33222,35554.798024,1,90,10,10,2.44,5,5,1,0,0,2,56,2,1,1,1 +69917,7,2,2,33,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,72686.111056,73189.163544,1,98,15,15,3.7,5,5,2,1,0,1,34,1,5,1,5 +69918,7,2,2,11,NA,4,4,2,11,140,NA,NA,2,2,3,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7659.302568,7901.193624,1,96,3,3,0.43,4,4,1,1,0,2,39,2,4,1,3 +69919,7,2,1,31,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,83819.702285,99717.125794,1,99,12,12,NA,1,1,0,0,0,1,31,1,4,5,NA +69920,7,2,2,9,NA,5,7,1,9,113,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,22308.590534,22137.463018,1,101,5,5,1.15,3,3,0,1,0,1,49,1,3,1,4 +69921,7,2,1,75,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,10980.245706,10978.086763,1,91,12,6,2.39,2,1,0,0,2,2,73,NA,NA,77,NA +69922,7,2,1,42,NA,1,1,2,NA,NA,2,NA,2,2,4,NA,1,1,NA,2,2,2,1,2,2,2,2,2,2,31640.296506,33247.715312,3,92,6,6,1,6,6,1,1,0,1,42,2,1,1,4 +69923,7,2,1,57,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,169546.363168,172535.263747,2,91,15,15,5,2,2,0,0,1,2,60,1,5,1,5 +69924,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,27426.222967,30692.896319,2,95,3,3,0.95,2,2,0,0,2,2,80,1,1,1,2 +69925,7,2,2,80,NA,1,1,2,NA,NA,2,NA,1,1,NA,NA,1,5,NA,1,2,2,1,2,2,1,2,2,NA,17563.671235,18809.520935,1,99,3,3,1.3,1,1,0,0,1,2,80,1,1,5,NA +69926,7,2,2,11,NA,2,2,1,11,132,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,16699.231378,17036.994683,1,98,3,3,0.4,7,7,2,3,0,2,31,2,5,1,2 +69927,7,2,2,2,NA,2,2,1,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,8645.395449,9311.129497,2,93,6,6,0.64,7,7,2,1,3,2,60,2,3,2,NA +69928,7,2,2,63,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,1,8308.628726,9015.10987,2,95,1,1,0.36,1,1,0,0,1,2,63,1,1,2,NA +69929,7,2,1,6,NA,5,6,2,6,83,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10810.913614,11461.625841,1,97,15,15,2.33,7,7,2,4,0,2,40,2,5,1,4 +69930,7,2,2,27,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,112992.533921,115858.21849,1,94,9,9,3.14,3,3,1,0,0,1,28,1,5,1,5 +69931,7,2,2,28,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,1,1,2,2,1,2,2,1,2,2,1,129336.409693,136474.939567,1,95,15,15,5,3,3,1,0,0,1,28,1,5,1,5 +69932,7,2,2,21,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,5,2,1,2,2,1,2,2,1,2,2,1,38177.662675,41078.639454,1,103,3,3,0.37,5,5,1,2,0,2,30,1,4,5,NA +69933,7,2,2,6,NA,3,3,1,6,79,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,20531.504977,20629.491172,1,98,7,7,1.03,7,7,0,4,0,2,20,1,3,5,NA +69934,7,2,2,56,NA,3,3,1,NA,NA,2,NA,2,2,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,153680.330235,152391.721814,1,103,15,15,5,2,2,0,0,1,1,61,1,4,1,5 +69935,7,2,1,80,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,8543.37447,9341.78969,3,90,9,9,3.65,2,2,0,0,2,1,80,1,2,1,3 +69936,7,2,2,54,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,15072.065618,15224.718219,1,99,15,15,5,2,2,0,0,1,2,54,2,5,1,5 +69937,7,2,1,19,NA,3,3,1,19,233,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,23403.89977,23518.866268,1,98,4,4,0.75,4,4,0,1,0,2,48,1,2,1,3 +69938,7,2,2,16,NA,4,4,1,16,203,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11791.755593,11850.248564,2,96,7,7,1.04,7,7,0,4,0,2,37,1,3,3,NA +69939,7,2,2,0,5,2,2,2,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7192.863376,7041.533956,1,90,3,3,0.52,3,3,2,0,0,2,20,1,4,5,NA +69940,7,2,1,61,NA,2,2,1,NA,NA,2,NA,2,1,8,NA,3,1,NA,1,2,2,1,2,2,1,2,2,2,6638.80908,6954.569749,2,93,15,15,5,2,2,0,0,2,1,61,2,3,1,3 +69941,7,2,2,52,NA,5,6,2,NA,NA,2,NA,2,2,2,NA,2,1,NA,1,2,2,NA,NA,NA,NA,NA,NA,NA,12098.219371,13033.848361,2,100,14,14,3.06,5,5,1,0,1,2,31,2,5,1,5 +69942,7,1,1,61,NA,2,2,NA,NA,NA,2,NA,2,1,7,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,9691.985299,0,1,93,6,6,1.55,3,3,0,0,3,1,61,2,4,1,1 +69943,7,2,1,40,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,105141.812429,109679.354704,1,98,15,15,5,4,4,2,0,0,1,40,1,5,1,NA +69944,7,2,2,18,NA,4,4,2,18,217,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,NA,11072.776368,11285.58755,3,90,5,5,0.87,4,4,0,0,0,2,43,2,3,5,NA +69945,7,2,1,2,NA,5,7,2,2,27,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8100.706553,8340.3972,1,98,15,15,5,4,4,2,0,0,2,35,1,5,1,4 +69946,7,2,1,6,NA,3,3,2,6,73,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,42986.51011,44926.997612,2,94,14,14,2.83,6,6,0,4,0,2,38,1,2,1,2 +69947,7,2,1,7,NA,2,2,2,7,88,NA,NA,2,2,1,0,NA,NA,NA,2,1,2,NA,NA,NA,NA,NA,NA,NA,8966.477743,10563.593323,2,99,12,3,0.52,5,3,0,1,0,1,30,2,2,4,NA +69948,7,2,1,45,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,27739.528889,28855.317795,1,90,4,3,1.07,2,1,0,0,0,2,25,1,5,6,NA +69949,7,2,2,12,NA,3,3,2,12,148,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,38400.791741,41869.717003,1,95,6,6,1.09,5,5,0,3,0,1,31,1,4,1,4 +69950,7,2,2,10,NA,4,4,2,10,124,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8115.309776,8285.322178,2,95,7,7,2.78,2,2,0,1,0,2,32,1,4,5,NA +69951,7,2,1,4,NA,5,6,2,4,51,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6185.185728,6767.562311,1,97,15,15,2.33,7,7,2,4,0,2,40,2,5,1,4 +69952,7,2,1,4,NA,3,3,2,4,50,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,77702.196479,91046.355703,1,95,15,15,5,3,3,1,0,0,1,28,1,5,1,5 +69953,7,2,1,8,NA,2,2,2,8,106,NA,NA,1,1,NA,2,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,13804.767816,14116.094161,2,91,9,9,2.6,4,4,1,1,0,2,31,2,4,1,5 +69954,7,2,2,43,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,5,1,1,1,2,2,1,2,2,NA,NA,NA,NA,15309.176013,16540.512525,1,90,14,14,3.33,5,5,1,2,0,1,41,1,5,1,5 +69955,7,2,1,10,NA,5,7,2,10,121,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7482.593572,7851.213843,1,101,4,4,0.78,4,4,1,2,0,2,31,1,4,3,NA +69956,7,2,1,3,NA,3,3,1,3,37,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,33334.752566,38103.457131,3,92,7,7,0.81,7,7,2,4,0,1,40,NA,NA,1,4 +69957,7,2,1,32,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,37658.482129,38663.56389,1,100,10,10,2.91,4,4,1,1,0,1,32,1,5,1,5 +69958,7,2,1,12,NA,3,3,2,13,157,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,71231.747774,75661.062324,2,95,9,9,2.6,4,4,0,2,0,1,42,1,4,1,4 +69959,7,2,2,51,NA,2,2,1,NA,NA,2,NA,2,2,6,NA,2,4,NA,2,2,2,2,2,2,2,2,2,2,29695.385784,34065.080879,2,91,1,1,0,1,1,0,0,0,2,51,2,2,4,NA +69960,7,1,2,14,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,116754.883807,0,1,94,5,5,1.04,4,4,1,1,0,1,18,1,2,NA,NA +69961,7,2,2,56,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,204553.029374,204712.584881,1,100,15,15,5,2,2,0,0,0,2,56,1,5,1,NA +69962,7,2,1,69,NA,1,1,1,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,11992.012141,12562.386395,2,102,4,4,1.09,2,2,0,0,2,2,68,1,3,1,3 +69963,7,2,2,20,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,30275.274308,29672.504425,2,101,12,4,1.79,4,1,0,0,0,2,20,1,4,5,NA +69964,7,2,2,75,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,70652.532816,72526.815349,1,98,6,6,1.65,2,2,0,0,2,1,80,1,3,1,3 +69965,7,2,2,27,NA,5,6,2,NA,NA,2,NA,2,1,4,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,16181.486766,17520.496205,1,90,4,4,0.78,4,4,0,0,1,1,69,2,4,1,3 +69966,7,2,1,3,NA,4,4,1,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13345.162299,13752.776418,2,102,4,4,0.81,3,3,2,0,0,2,23,1,4,5,NA +69967,7,2,1,8,NA,3,3,1,8,97,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,28126.350642,29877.890829,2,91,5,5,1.2,3,3,0,1,0,2,40,1,5,1,5 +69968,7,2,1,16,NA,3,3,1,16,193,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,113571.164423,112715.649169,2,101,10,10,2.33,6,6,1,3,0,1,39,1,2,1,4 +69969,7,2,1,11,NA,1,1,1,11,138,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13927.458372,14007.413517,2,98,1,1,0.18,4,4,0,2,0,1,29,1,4,6,NA +69970,7,2,2,13,NA,5,6,2,13,162,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9029.632215,9422.555256,1,90,77,77,NA,4,4,0,2,0,2,51,1,5,1,5 +69971,7,2,2,2,NA,3,3,2,2,30,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,22159.470641,22450.653549,1,95,3,3,0.7,3,3,1,0,0,1,25,1,4,1,4 +69972,7,2,1,79,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,53149.251154,56449.488341,1,100,15,15,5,2,2,0,0,2,1,79,1,5,1,4 +69973,7,2,2,55,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,26637.81974,28307.564263,1,98,7,7,1.03,7,7,0,4,0,2,20,1,3,5,NA +69974,7,2,1,22,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,15408.94893,15514.368855,1,99,13,13,NA,3,3,0,0,2,1,67,1,2,1,2 +69975,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,60071.993203,65791.533402,1,95,14,14,5,1,1,0,0,1,2,80,1,4,1,NA +69976,7,2,1,61,NA,2,2,2,NA,NA,2,NA,2,1,99,NA,4,1,NA,2,2,2,2,2,2,2,2,2,2,10585.549682,10952.862023,1,90,12,12,NA,3,3,0,0,1,1,35,2,4,5,NA +69977,7,2,2,12,NA,2,2,2,12,154,NA,NA,1,1,NA,7,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,13824.001771,15649.805677,2,90,3,3,0.54,4,4,1,2,0,2,33,2,1,4,NA +69978,7,2,2,13,NA,4,4,1,13,157,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18698.220599,19300.762251,2,101,6,6,1.54,3,3,0,1,0,2,34,1,4,1,3 +69979,7,2,2,36,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,3,1,2,2,1,2,2,NA,NA,NA,NA,26465.930618,28724.649216,2,100,5,5,1.07,4,4,0,1,0,2,36,1,3,5,NA +69980,7,2,2,0,2,2,2,2,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,4481.392842,4662.235074,2,90,6,6,0.66,7,7,2,2,0,2,24,2,4,6,NA +69981,7,2,1,62,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,15991.70237,16076.675652,1,99,3,3,1.29,1,1,0,0,1,1,62,1,3,5,NA +69982,7,2,2,8,NA,3,3,2,8,98,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,41790.228676,44382.642913,2,94,7,7,1.17,6,6,0,3,0,1,40,1,3,1,5 +69983,7,2,1,38,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,19384.896286,19940.089683,1,94,3,3,0.95,2,2,0,0,1,2,67,1,2,2,NA +69984,7,2,2,16,NA,1,1,1,16,200,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,27070.679378,29958.836982,1,92,4,4,0.74,4,4,1,1,0,1,51,2,1,1,1 +69985,7,2,2,73,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,19901.857177,20582.498016,3,92,3,3,1.29,1,1,0,0,1,2,73,1,4,2,NA +69986,7,2,1,14,NA,1,1,1,14,170,NA,NA,2,2,4,7,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,25525.43565,25915.600865,1,94,5,5,0.87,4,4,1,1,0,1,35,2,1,1,1 +69987,7,2,2,3,NA,1,1,1,3,38,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15457.736897,17065.756351,3,92,3,3,0.54,4,4,3,0,0,2,22,1,3,5,NA +69988,7,2,1,14,NA,1,1,1,14,175,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18242.832494,19431.180704,1,102,7,7,1.41,5,5,0,2,2,1,72,1,4,1,3 +69989,7,2,2,75,NA,2,2,2,NA,NA,2,NA,2,1,99,NA,1,6,NA,2,2,2,2,2,2,1,2,2,NA,17318.187297,19970.708273,2,90,4,4,1.02,2,2,0,0,2,2,75,2,1,6,NA +69990,7,2,2,23,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,18412.14266,22203.276692,2,90,2,2,0.67,2,2,0,0,1,2,64,1,5,5,NA +69991,7,2,2,56,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,27407.957254,27308.998449,2,90,3,3,1.29,1,1,0,0,0,2,56,1,3,3,NA +69992,7,2,2,23,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,150082.940829,151424.784638,1,98,8,8,2.97,2,2,0,0,0,1,23,1,3,1,5 +69993,7,2,2,40,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,2,5,2,1,2,2,1,2,2,1,2,2,1,29650.79971,37801.89955,2,90,4,4,1.29,2,2,0,0,0,2,40,1,2,5,NA +69994,7,2,2,21,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,71351.478679,74215.528244,2,100,10,10,3.13,4,4,0,0,1,2,53,1,2,1,2 +69995,7,2,1,18,NA,1,1,2,18,226,2,NA,1,1,NA,11,NA,NA,NA,2,2,2,2,2,2,1,2,2,1,18120.499457,19917.650851,1,90,1,1,0.02,5,5,0,1,0,2,39,2,1,1,2 +69996,7,2,2,40,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,18490.479848,21651.629766,2,100,6,6,0.99,5,5,0,3,0,2,40,1,3,1,3 +69997,7,2,1,46,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,25123.480232,25043.348036,1,92,15,15,4.44,5,5,0,3,0,2,43,1,5,6,NA +69998,7,1,1,17,NA,4,4,NA,NA,NA,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,NA,NA,NA,NA,NA,NA,NA,11125.932433,0,1,96,NA,NA,NA,4,4,1,1,0,2,37,NA,NA,1,4 +69999,7,2,2,29,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,20247.768461,20264.515513,2,93,5,5,1.05,3,3,1,0,0,2,29,1,3,5,NA +70000,7,2,2,59,NA,4,4,2,NA,NA,2,NA,2,2,6,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,19100.364335,18787.428747,1,96,4,4,1.34,1,1,0,0,0,2,59,2,3,3,NA +70001,7,1,2,61,NA,5,6,NA,NA,NA,2,NA,2,1,4,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,17243.546687,0,1,95,3,3,0.43,4,4,0,1,2,1,65,2,5,1,3 +70002,7,2,2,9,NA,2,2,1,9,116,NA,NA,1,1,NA,3,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,19084.197249,19808.05931,2,91,15,15,5,4,4,0,2,0,1,45,2,5,1,4 +70003,7,2,1,3,NA,5,6,2,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5953.107662,6677.061573,3,90,14,14,3.47,4,4,1,1,0,2,38,2,5,1,5 +70004,7,2,1,12,NA,3,3,2,12,151,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,99249.131685,98501.502244,1,101,15,15,5,4,4,0,2,0,1,43,1,4,1,5 +70005,7,2,1,80,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,1,2,1,2,2,NA,NA,NA,NA,33146.291352,36370.393263,1,90,5,5,1.05,3,3,0,0,3,2,60,1,5,77,NA +70006,7,2,1,29,NA,2,2,1,NA,NA,2,NA,2,1,4,NA,5,5,NA,1,2,2,NA,NA,NA,1,2,2,1,38474.772527,40200.135096,2,93,NA,NA,NA,4,2,0,0,0,1,28,NA,NA,4,NA +70007,7,2,2,4,NA,4,4,2,4,51,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10389.292229,10850.629517,2,95,1,1,0.25,3,3,1,1,0,2,26,1,2,5,NA +70008,7,2,2,55,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,160743.928829,165029.101567,1,95,8,6,2.04,4,2,0,1,0,2,57,1,5,5,NA +70009,7,2,1,26,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,74929.366953,78437.058525,1,93,15,9,5,3,1,0,0,0,1,26,1,5,5,NA +70010,7,2,2,58,NA,5,6,2,NA,NA,2,NA,2,1,3,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,12441.719186,13672.655562,1,96,7,7,1.83,3,3,0,0,1,1,66,2,5,1,3 +70011,7,2,1,14,NA,5,6,2,14,170,NA,NA,2,2,3,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8168.705487,9098.657657,1,93,7,7,1.64,5,5,0,2,0,1,47,2,5,1,1 +70012,7,2,1,0,5,4,4,2,NA,7,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5719.440362,6091.410026,1,96,15,15,5,6,6,1,1,1,2,44,1,3,1,3 +70013,7,2,1,70,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,7526.944058,7674.379869,1,96,15,15,5,2,2,0,0,2,1,70,1,5,1,4 +70014,7,2,1,32,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,85120.619542,87558.517853,1,93,15,15,5,1,1,0,0,0,1,32,1,4,5,NA +70015,7,2,1,57,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,16851.334496,19427.051933,2,95,4,4,1.66,1,1,0,0,0,1,57,1,4,3,NA +70016,7,2,2,72,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,62212.598767,64340.261278,1,94,15,15,5,2,2,0,0,2,1,73,NA,NA,1,5 +70017,7,2,2,14,NA,4,4,2,14,169,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12209.74498,13384.042162,2,90,4,4,0.57,5,5,1,2,0,2,33,2,2,77,NA +70018,7,2,1,28,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,27911.790319,31609.08818,3,91,7,7,1.57,4,4,2,0,0,2,29,2,3,1,3 +70019,7,2,1,38,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,18544.003944,18279.674065,2,100,5,5,1.08,3,3,0,0,0,1,38,1,2,5,NA +70020,7,2,2,21,NA,5,6,1,NA,NA,2,NA,2,2,3,NA,4,6,3,1,2,2,1,2,2,1,2,2,1,16929.836231,18556.498474,2,101,8,5,2.2,2,1,0,0,0,1,24,2,4,6,NA +70021,7,2,2,10,NA,3,3,1,10,128,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,45129.675368,44994.093254,1,98,10,10,2.2,6,6,1,3,0,2,31,1,4,6,NA +70022,7,2,2,2,NA,5,6,2,3,36,NA,NA,2,2,2,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8173.816615,8313.181418,1,97,15,15,4.34,4,4,2,0,0,1,35,2,5,1,5 +70023,7,2,2,9,NA,4,4,2,10,120,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7659.302568,7901.193624,1,96,77,77,NA,7,7,0,3,1,2,43,77,5,5,NA +70024,7,2,2,9,NA,4,4,2,9,109,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7268.721126,7826.51541,2,99,4,4,0.41,7,7,0,2,0,2,36,1,3,5,NA +70025,7,2,2,16,NA,2,2,2,16,196,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,14437.97544,15197.369043,2,90,7,7,1.66,4,4,0,3,0,2,34,1,5,3,NA +70026,7,2,1,31,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,17554.053699,17463.765652,2,100,7,7,2.72,2,2,0,0,0,2,59,1,4,3,NA +70027,7,2,1,7,NA,1,1,1,7,95,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10658.399025,10722.994279,1,102,8,8,1.33,7,7,1,4,0,2,32,1,3,1,2 +70028,7,2,2,2,NA,3,3,2,2,29,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,22159.470641,22857.583467,1,95,2,2,0.22,4,4,2,1,0,2,22,1,2,5,NA +70029,7,2,1,16,NA,4,4,1,16,198,NA,NA,1,1,NA,8,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,17606.165994,18413.211403,2,101,99,99,NA,3,3,0,1,1,2,78,1,1,2,NA +70030,7,1,2,61,NA,5,7,NA,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,10346.035773,0,1,99,9,1,0,2,1,0,0,2,2,61,1,4,6,NA +70031,7,2,2,63,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,10192.188896,10440.656902,1,99,7,7,3.31,1,1,0,0,1,2,63,1,4,3,NA +70032,7,2,1,80,NA,5,6,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,11550.158096,12419.035396,2,92,77,77,NA,2,2,0,0,2,2,80,1,3,1,4 +70033,7,2,2,53,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,160743.928829,166234.629208,1,95,12,12,NA,2,2,0,0,0,2,53,1,4,1,NA +70034,7,2,2,4,NA,4,4,2,4,56,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9689.370244,10119.627445,1,99,2,2,0.43,3,3,2,0,0,2,26,1,4,5,NA +70035,7,2,2,65,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,91836.529686,93336.987794,1,93,10,10,5,1,1,0,0,1,2,65,1,5,3,NA +70036,7,2,2,7,NA,2,2,1,7,86,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16765.041162,17104.135554,1,98,4,4,0.94,3,3,0,1,0,2,35,2,5,1,5 +70037,7,2,2,1,23,2,2,2,NA,24,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8563.768225,8593.010585,1,93,6,6,0.74,7,7,1,2,0,1,53,2,2,1,2 +70038,7,1,1,20,NA,2,2,NA,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,44074.735764,0,2,91,4,4,0.69,4,4,2,0,0,2,21,1,3,6,NA +70039,7,2,2,9,NA,3,3,2,9,109,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,NA,NA,NA,1,2,2,1,22933.149195,26924.921202,1,101,1,1,0.08,6,6,0,1,0,1,51,1,2,5,NA +70040,7,2,1,3,NA,5,7,2,3,41,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12996.965152,13393.943951,1,101,5,5,1.23,3,3,2,0,0,2,24,1,2,5,NA +70041,7,1,2,80,NA,5,6,NA,NA,NA,2,NA,2,1,7,NA,1,2,NA,1,2,1,1,2,1,NA,NA,NA,NA,13689.379977,0,2,92,2,2,0.64,1,1,0,0,1,2,80,2,1,2,NA +70042,7,2,2,2,NA,3,3,2,2,35,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16635.553691,18360.507343,1,91,4,4,0.81,4,4,1,1,0,1,32,1,4,6,NA +70043,7,2,2,12,NA,3,3,2,12,150,NA,NA,2,1,4,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,74165.041171,75130.242541,2,91,15,15,5,4,4,0,2,0,2,48,1,5,1,5 +70044,7,2,1,9,NA,4,4,2,9,117,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9023.469661,9333.449986,2,90,8,6,1.46,4,3,1,1,0,2,21,1,5,6,NA +70045,7,2,2,35,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,70772.230318,73438.772102,1,93,15,15,5,3,3,1,0,0,1,37,1,5,1,5 +70046,7,2,1,55,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,4,NA,1,2,2,1,2,2,1,2,2,1,19541.667675,19517.839388,2,95,3,3,1.16,1,1,0,0,0,1,55,1,4,4,NA +70047,7,2,2,19,NA,4,4,1,19,233,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11838.873374,11750.256617,2,100,14,14,3.06,5,5,1,0,0,1,50,1,5,1,5 +70048,7,2,2,11,NA,4,4,2,11,142,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7891.243393,8330.261165,2,100,4,4,0.69,5,5,0,3,0,1,38,1,3,6,NA +70049,7,2,1,41,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,2,1,NA,1,2,1,1,2,2,1,2,2,NA,20696.713928,21871.839567,2,102,9,9,2.68,4,4,1,1,0,2,38,2,5,1,2 +70050,7,2,2,49,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,29010.447112,29720.490657,1,100,9,9,3.64,2,2,0,0,0,2,49,1,4,5,NA +70051,7,2,1,10,NA,4,4,1,10,124,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11185.87189,11566.898318,1,92,7,7,2.25,3,3,0,2,0,2,35,1,4,77,NA +70052,7,2,2,28,NA,5,6,2,NA,NA,2,NA,2,2,2,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,11696.173591,12195.620792,1,93,15,5,1.84,6,1,0,0,0,1,34,2,5,5,NA +70053,7,2,1,20,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,32866.0119,33575.905633,1,98,99,99,NA,3,2,0,0,0,2,22,1,4,5,NA +70054,7,2,1,38,NA,1,1,1,NA,NA,2,NA,2,7,77,NA,1,6,NA,2,2,2,1,2,2,NA,NA,NA,NA,32856.012738,34774.888791,2,103,77,77,NA,7,7,0,4,0,1,38,2,1,6,NA +70055,7,2,2,47,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,115926.402585,120043.284447,1,98,10,10,3.04,4,4,0,2,0,2,47,1,4,1,3 +70056,7,2,1,3,NA,5,7,2,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11821.601823,13035.249088,1,95,4,4,0.97,3,3,2,0,0,2,22,1,4,5,NA +70057,7,2,2,7,NA,1,1,1,7,91,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,15352.601806,16028.326912,2,102,4,4,0.61,5,5,0,3,0,1,34,2,3,1,3 +70058,7,2,1,38,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,20071.705576,20986.552878,3,91,7,7,2.45,2,2,0,0,0,2,29,2,5,1,5 +70059,7,2,2,74,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,25812.913537,27633.237354,2,95,3,3,1.27,1,1,0,0,1,2,74,1,2,2,NA +70060,7,2,1,2,NA,4,4,2,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5447.377416,5513.820992,2,90,4,4,0.97,3,3,1,0,0,2,23,2,3,5,NA +70061,7,2,1,65,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,7101.739553,7433.956549,2,100,2,2,0.83,1,1,0,0,1,1,65,1,2,5,NA +70062,7,2,2,75,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,69726.261922,71865.394906,1,93,15,15,5,2,2,0,0,2,2,75,1,5,1,5 +70063,7,2,2,43,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,1,1,2,1,2,2,1,2,2,1,2,2,1,27585.470618,28524.896774,2,102,15,15,5,4,4,0,2,0,1,44,1,3,1,1 +70064,7,2,2,38,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,3,2,1,2,2,1,2,2,1,2,2,1,23725.035562,24103.855713,1,91,7,7,2.2,3,3,0,0,1,2,60,1,2,2,NA +70065,7,2,2,31,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,71034.153987,74518.988514,1,98,14,14,3.9,4,4,0,3,0,2,31,1,4,1,NA +70066,7,2,1,47,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,19260.892847,19199.459573,2,97,8,5,2.02,2,1,0,0,0,1,47,1,4,3,NA +70067,7,2,1,5,NA,3,3,1,5,64,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,21357.821814,24096.698658,2,96,3,3,0.53,5,5,3,0,0,2,26,1,4,1,4 +70068,7,2,2,8,NA,4,4,2,8,103,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8147.287486,8590.325322,2,90,2,2,0.38,4,4,1,2,0,2,32,1,4,5,NA +70069,7,2,2,50,NA,1,1,2,NA,NA,2,NA,2,2,4,NA,4,6,NA,2,2,2,1,2,2,2,2,2,2,24352.519425,24479.515743,1,97,3,3,0.5,5,5,0,2,0,1,56,2,2,6,NA +70070,7,2,2,2,NA,4,4,1,2,26,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9273.23044,9512.588252,2,96,NA,3,0.65,4,3,1,1,0,1,21,1,2,6,NA +70071,7,2,1,0,0,1,1,1,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,7757.493251,7980.837709,3,92,4,4,0.59,5,5,2,1,0,1,20,2,1,1,3 +70072,7,2,1,53,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,26135.885159,26659.265986,2,101,7,7,2.16,3,3,0,1,0,2,44,1,4,6,NA +70073,7,2,1,19,NA,3,3,2,19,239,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,30943.024697,36334.060093,1,101,1,1,0.08,6,6,0,1,0,1,51,1,2,5,NA +70074,7,2,1,16,NA,1,1,1,16,195,NA,NA,1,1,NA,9,NA,NA,NA,2,2,2,2,2,2,1,2,2,1,19996.544021,19901.195571,1,100,7,7,1.3,5,5,0,3,0,1,43,2,2,1,4 +70075,7,2,2,31,NA,5,6,2,NA,NA,2,NA,2,1,3,NA,3,1,2,1,2,1,1,2,1,NA,NA,NA,NA,11608.998717,13948.968232,3,90,5,5,0.93,4,4,1,0,0,1,48,2,4,1,NA +70076,7,2,1,14,NA,5,6,2,14,172,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6232.587755,6661.015771,1,91,15,15,3.25,7,7,1,2,0,2,31,1,5,1,5 +70077,7,2,2,58,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,1,1,NA,1,2,2,1,2,2,1,2,2,1,16119.136275,16768.999275,1,101,14,14,5,2,2,0,0,0,1,58,2,3,1,1 +70078,7,2,2,33,NA,1,1,2,NA,NA,2,NA,2,2,2,NA,2,1,2,2,2,2,2,2,2,2,2,2,2,32982.479382,35082.144563,2,99,99,3,0.66,4,2,0,0,0,1,35,2,4,1,2 +70079,7,2,2,1,21,2,2,1,NA,21,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9267.834226,9392.475614,2,93,15,15,4.51,4,4,1,1,0,1,40,1,4,1,5 +70080,7,2,2,32,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,16614.865368,17238.21833,3,91,15,15,4.47,4,4,2,0,0,1,33,1,5,1,5 +70081,7,2,2,19,NA,4,4,2,19,236,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,NA,NA,NA,1,2,2,1,10154.02528,10568.655787,2,99,2,2,0.19,7,7,3,1,0,2,43,1,2,4,NA +70082,7,2,2,29,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,21398.47235,20994.797177,1,103,14,8,4.39,2,1,0,0,0,2,29,1,5,5,NA +70083,7,1,2,24,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,4,3,3,1,2,2,1,2,2,NA,NA,NA,NA,129336.409693,0,1,92,4,4,1.29,2,2,1,0,0,2,24,1,4,3,NA +70084,7,2,1,66,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,7117.971973,7450.948316,2,100,3,3,0.68,2,2,0,0,2,1,66,1,2,1,2 +70085,7,2,2,6,NA,3,3,2,7,84,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,18732.936406,19089.39853,1,94,7,7,0.94,7,7,1,4,0,2,46,2,5,1,5 +70086,7,2,1,18,NA,1,1,1,18,223,2,NA,2,2,4,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,23389.620035,23484.828122,3,91,3,3,0.39,6,6,1,1,0,1,39,2,1,6,NA +70087,7,2,2,7,NA,4,4,1,7,95,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7899.813226,8111.155436,2,100,15,15,4.47,4,4,0,2,0,1,39,NA,NA,1,5 +70088,7,2,1,47,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,17452.049284,17389.002535,1,93,7,7,1.64,5,5,0,2,0,1,47,2,5,1,1 +70089,7,2,1,0,11,1,1,1,NA,12,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7222.23638,7150.860834,1,94,4,4,0.32,7,7,3,2,0,2,28,2,2,1,9 +70090,7,2,2,7,NA,3,3,2,7,92,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,39810.933651,39282.261038,2,95,15,15,4.77,4,4,0,2,0,2,36,1,4,1,5 +70091,7,2,2,4,NA,3,3,2,4,56,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,78813.208592,86985.412201,2,91,6,6,1.34,4,4,1,2,0,2,33,1,4,3,NA +70092,7,2,1,24,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,120604.496044,126250.391527,2,92,10,10,3.51,3,3,0,0,0,1,24,1,4,5,NA +70093,7,2,1,14,NA,4,4,2,14,177,NA,NA,2,2,3,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14853.30651,14966.239185,1,93,14,14,5,2,2,0,1,0,2,52,2,3,1,NA +70094,7,2,2,36,NA,3,3,2,NA,NA,2,NA,2,1,6,NA,4,1,1,1,2,2,1,2,2,1,2,2,1,60859.550805,63845.233776,2,100,15,15,5,3,3,0,1,0,1,38,1,4,1,4 +70095,7,2,2,59,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,3,1,NA,1,2,1,1,2,1,1,2,1,3,10420.55184,10475.655119,2,92,5,5,0.64,7,7,1,2,1,1,66,2,1,1,3 +70096,7,2,2,77,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,66567.821082,68844.431611,3,91,7,7,1.97,4,4,0,0,1,2,77,1,5,2,NA +70097,7,2,2,7,NA,3,3,2,7,87,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,67046.323141,68322.122844,1,90,8,8,1.67,5,5,2,1,0,2,28,1,4,1,5 +70098,7,2,2,0,9,2,2,2,NA,10,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5234.186769,5411.317673,2,90,14,14,3.08,6,6,1,1,1,2,60,2,5,2,NA +70099,7,2,1,17,NA,3,3,2,17,213,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,100370.520459,102294.664852,1,90,15,15,5,4,4,0,1,0,2,53,1,5,1,5 +70100,7,2,2,11,NA,4,4,1,11,143,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9399.281543,9696.12347,2,96,6,6,1.32,5,5,1,3,0,2,30,1,4,3,NA +70101,7,2,2,45,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,22109.546782,29180.501371,1,93,7,7,2.72,2,2,0,1,0,2,45,1,3,3,NA +70102,7,2,1,68,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,92308.775062,93174.50633,1,100,6,6,2.24,1,1,0,0,1,1,68,1,4,2,NA +70103,7,2,2,56,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,125443.355152,127362.409324,2,103,10,10,5,1,1,0,0,0,2,56,1,4,3,NA +70104,7,2,2,34,NA,5,6,1,NA,NA,2,NA,2,2,3,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,16614.865368,17238.21833,3,91,15,15,5,4,4,2,0,0,1,36,2,5,1,5 +70105,7,2,1,25,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,NA,52698.05363,53416.368765,3,92,5,5,0.81,5,5,3,0,0,2,23,1,4,5,NA +70106,7,2,1,18,NA,3,3,2,19,228,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,30100.326038,29873.584609,1,101,6,6,1.17,4,4,0,1,0,1,41,1,3,6,NA +70107,7,2,2,0,10,4,4,1,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,NA,NA,NA,NA,NA,NA,NA,4358.100179,4799.448128,2,93,NA,NA,NA,4,4,1,0,1,1,63,NA,NA,6,NA +70108,7,2,2,11,NA,3,3,2,11,138,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,49164.586897,48511.701666,2,95,15,15,4.63,5,5,1,2,0,2,36,1,5,1,3 +70109,7,2,1,57,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,27595.50738,28151.492876,1,98,15,15,5,5,5,0,1,1,2,55,1,5,1,5 +70110,7,2,2,0,11,4,4,1,NA,12,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5576.185193,5739.245437,2,96,5,5,1.24,3,3,2,0,0,1,29,1,3,5,NA +70111,7,2,1,56,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,12517.592486,15021.976783,1,96,77,77,NA,7,7,1,3,0,1,56,1,3,1,4 +70112,7,2,2,9,NA,3,3,2,9,110,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,55626.447796,54887.751745,1,95,14,14,3.8,4,4,0,2,0,2,37,1,5,1,5 +70113,7,1,1,28,NA,1,1,NA,NA,NA,2,NA,2,1,77,NA,1,3,NA,2,2,2,2,2,2,NA,NA,NA,NA,35669.2076,0,2,94,77,77,NA,4,4,0,0,0,1,28,2,1,3,NA +70114,7,2,1,39,NA,5,6,2,NA,NA,2,NA,2,2,2,NA,3,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,14221.330587,18275.989104,3,90,12,12,NA,2,2,0,0,0,1,39,2,3,1,NA +70115,7,2,2,36,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,3,4,2,2,2,2,2,2,2,NA,NA,NA,NA,36453.846815,39554.044508,1,102,2,2,0.52,3,3,0,2,0,2,36,2,3,4,NA +70116,7,2,1,0,4,3,3,1,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,23841.007913,24575.370543,2,101,10,10,2.33,6,6,1,3,0,1,39,1,2,1,4 +70117,7,2,1,46,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,79677.823556,79777.881901,1,99,15,15,5,5,5,0,3,0,2,43,1,5,1,5 +70118,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,54095.581484,61529.339683,2,91,5,5,1.84,1,1,0,0,1,2,80,1,4,2,NA +70119,7,2,1,19,NA,3,3,1,19,229,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,110478.18082,109645.964567,2,101,1,1,0.11,2,1,0,0,0,1,19,1,4,NA,NA +70120,7,2,2,70,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,53541.401974,54113.194007,1,99,8,8,3.4,2,2,0,0,2,1,74,1,5,1,4 +70121,7,2,2,33,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,2,1,2,2,1,2,2,1,2,2,1,22758.541444,23956.866949,1,101,2,2,0.47,3,3,1,0,0,1,35,1,2,6,NA +70122,7,2,2,37,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,86578.861495,87453.974807,2,101,10,10,2.33,6,6,1,3,0,1,39,1,2,1,4 +70123,7,2,2,45,NA,5,6,2,NA,NA,2,NA,2,2,5,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,11762.034222,11824.231183,3,90,77,77,NA,5,5,0,2,0,1,46,2,3,1,3 +70124,7,2,2,16,NA,4,4,1,17,205,NA,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,NA,NA,NA,NA,12531.903464,13043.632492,2,100,4,4,0.85,4,4,0,2,0,2,39,1,3,6,NA +70125,7,2,1,30,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,28996.250643,29563.919546,2,101,4,4,1.52,1,1,0,0,0,1,30,1,3,5,NA +70126,7,2,1,2,NA,4,4,2,2,32,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6992.24593,7077.532809,2,97,1,1,0.33,2,2,1,0,0,2,29,1,3,5,NA +70127,7,2,2,26,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,112960.559471,154652.396986,1,91,4,4,1.29,2,2,1,0,0,2,26,1,4,5,NA +70128,7,1,1,24,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,41383.258526,0,1,97,1,1,0.22,2,1,0,0,0,1,24,1,3,6,NA +70129,7,2,1,35,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,19384.896286,19940.089683,1,94,3,3,0.39,6,6,2,2,0,2,25,1,4,1,2 +70130,7,2,1,42,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,21600.805431,23858.641894,2,96,7,7,1.79,4,4,2,0,0,2,49,1,3,1,3 +70131,7,2,2,53,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,12449.932013,12144.773422,3,90,15,15,4.34,4,4,0,0,1,1,65,1,3,1,4 +70132,7,2,1,62,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,11761.359913,11893.852645,1,92,9,9,4.23,2,2,0,0,1,1,62,1,3,1,4 +70133,7,2,1,30,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,20891.980831,21490.337905,2,97,3,1,0.09,2,1,0,0,0,1,30,1,4,5,NA +70134,7,2,2,47,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,138322.767578,139738.299504,1,101,10,10,4.63,2,2,0,0,1,1,64,2,3,1,4 +70135,7,2,1,2,NA,1,1,1,3,36,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,8481.734412,8582.006703,1,103,8,8,1.85,5,5,2,1,0,2,25,2,2,1,2 +70136,7,2,1,39,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,17643.563124,18168.544198,3,91,15,15,5,4,4,2,0,0,2,33,2,5,1,5 +70137,7,2,1,17,NA,2,2,2,17,210,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,14081.782012,14391.713696,2,90,2,2,0.25,5,5,0,1,0,2,41,2,4,1,NA +70138,7,2,1,6,NA,5,7,2,6,80,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,21147.476454,21752.181979,1,95,5,5,0.89,4,4,0,1,0,2,42,1,4,6,NA +70139,7,2,2,10,NA,4,4,1,10,127,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9453.111053,10178.533204,1,100,6,6,1.13,4,4,0,3,0,2,32,1,3,5,NA +70140,7,2,1,3,NA,3,3,1,3,37,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,60239.023202,67963.933877,1,98,7,7,1.66,5,5,2,1,0,2,37,1,5,1,3 +70141,7,2,1,0,11,2,2,1,NA,12,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,4854.394074,5092.044151,2,93,15,15,4.84,6,6,1,1,2,1,66,2,4,1,3 +70142,7,2,2,69,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,105434.067206,107522.739372,2,103,9,9,4.92,1,1,0,0,1,2,69,1,4,2,NA +70143,7,2,2,40,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,13510.18419,14596.8255,2,90,14,14,4.32,3,3,0,1,0,1,48,2,4,1,5 +70144,7,2,1,12,NA,1,1,1,12,149,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18987.489596,19405.392998,3,91,6,6,2.04,2,2,0,1,0,2,51,1,4,4,NA +70145,7,2,2,49,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,29010.447112,28216.500124,1,100,6,6,2.51,1,1,0,0,0,2,49,1,4,3,NA +70146,7,2,2,12,NA,5,7,2,12,152,NA,NA,2,1,4,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10767.566937,11183.935292,2,91,15,15,3.7,5,5,1,2,0,1,50,NA,NA,1,5 +70147,7,2,1,14,NA,5,6,1,15,180,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8915.81491,9312.338117,1,92,14,14,3.69,4,4,0,2,0,1,47,2,4,4,NA +70148,7,2,1,30,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,22188.836739,24460.137584,1,92,3,3,0.46,5,5,2,1,0,1,30,1,3,1,2 +70149,7,2,1,13,NA,5,6,2,13,160,NA,NA,2,1,4,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8965.57404,9581.867503,1,90,15,15,5,5,5,0,3,0,2,46,2,4,1,5 +70150,7,2,1,39,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,76374.321112,79950.814336,2,99,14,14,5,1,1,0,0,0,1,39,1,5,5,NA +70151,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,64679.499599,80402.538623,3,92,6,6,2.69,1,1,0,0,1,2,80,1,3,2,NA +70152,7,2,2,50,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,161992.272945,167997.905035,1,91,14,14,3.8,4,4,0,2,0,1,50,NA,NA,1,5 +70153,7,2,1,57,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,24930.322327,25181.116543,2,94,3,3,0.92,1,1,0,0,0,1,57,1,2,3,NA +70154,7,2,1,0,1,5,6,1,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5941.765349,6071.648885,2,102,3,3,0.38,5,5,3,0,0,2,30,2,2,1,4 +70155,7,2,1,18,NA,5,7,1,18,219,2,NA,1,1,NA,66,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13276.485807,15665.287637,2,100,99,99,NA,3,3,0,0,0,1,46,1,9,3,NA +70156,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,34853.379657,39642.894617,3,90,10,10,4.3,2,2,0,0,2,2,80,1,4,1,5 +70157,7,2,2,1,22,4,4,1,NA,22,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9273.23044,9685.008923,2,96,5,5,1.24,3,3,2,0,0,1,29,1,3,5,NA +70158,7,2,2,53,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,24905.670199,24973.138542,2,101,8,8,2.7,3,3,0,1,0,1,53,1,4,1,2 +70159,7,2,1,13,NA,4,4,2,13,162,NA,NA,2,1,4,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11125.932433,11147.929312,1,96,7,7,1.52,4,4,0,2,0,2,30,2,4,1,5 +70160,7,2,2,61,NA,2,2,2,NA,NA,2,NA,2,1,8,NA,2,1,NA,2,2,2,2,2,2,1,2,2,2,10288.382343,13758.61994,2,90,6,6,1.7,2,2,0,0,2,1,61,2,1,1,2 +70161,7,2,1,34,NA,1,1,1,NA,NA,2,NA,2,2,2,NA,2,1,NA,2,2,2,2,2,2,1,2,2,2,37715.365512,38149.83984,2,102,7,7,1.33,6,6,1,3,0,1,34,2,2,1,1 +70162,7,2,1,34,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,21288.18311,21326.274673,1,102,7,7,1.57,4,4,0,2,0,2,33,1,4,1,4 +70163,7,2,2,53,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,163605.682975,162710.354378,1,90,15,15,5,4,4,0,1,0,2,53,1,5,1,5 +70164,7,2,2,46,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,23884.62129,24647.381072,2,98,5,5,1.24,3,3,0,0,1,2,58,1,2,5,NA +70165,7,2,2,18,NA,2,2,2,19,228,2,NA,1,1,NA,13,NA,NA,NA,2,2,2,2,2,2,2,2,2,2,15442.648697,16179.397194,3,90,77,77,NA,4,3,0,0,0,1,45,2,3,3,NA +70166,7,2,1,20,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,137038.746155,146586.432966,2,101,4,2,0.66,2,1,0,0,0,1,21,1,4,5,NA +70167,7,2,2,47,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,153972.608815,154123.803084,2,101,5,5,1.36,2,2,0,0,0,2,47,1,2,1,4 +70168,7,2,1,73,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,64901.456576,67363.75016,1,101,15,15,5,2,2,0,0,2,2,73,1,4,1,4 +70169,7,2,2,23,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,3,6,2,1,2,2,1,2,2,1,2,2,1,60324.348827,60863.689632,1,95,6,6,0.96,5,5,1,0,1,2,69,1,1,2,NA +70170,7,2,2,59,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,15497.844354,15073.705188,1,99,4,2,0.74,2,1,0,0,1,2,59,1,3,3,NA +70171,7,2,2,30,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,27532.825087,28260.668065,1,101,6,6,1.3,4,4,2,0,0,2,30,1,4,6,NA +70172,7,2,2,11,NA,5,7,1,12,144,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,5147.116597,5520.448595,2,92,15,15,4.59,4,4,0,2,0,2,45,2,5,1,5 +70173,7,2,2,2,NA,2,2,2,2,30,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9653.164181,10331.416262,1,90,15,15,4.44,5,5,2,1,0,1,36,1,3,1,4 +70174,7,1,1,54,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,24930.322327,0,1,100,1,1,0.01,1,1,0,0,0,1,54,1,2,3,NA +70175,7,2,2,62,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,11699.431733,12221.798846,1,96,7,7,2.31,2,2,0,0,1,2,62,1,3,3,NA +70176,7,2,2,23,NA,1,1,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,41953.42893,43056.968872,2,99,4,1,0.22,4,1,0,0,0,2,21,NA,NA,5,NA +70177,7,2,2,20,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,45403.540522,46903.566528,2,92,9,6,2.75,2,1,0,0,0,1,26,99,9,6,NA +70178,7,1,2,6,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,62595.719575,0,1,95,14,14,3.8,4,4,1,1,0,1,36,1,4,1,5 +70179,7,2,1,4,NA,4,4,1,4,57,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10690.995725,11017.541084,2,98,2,2,0.31,4,4,2,1,0,2,27,1,2,4,NA +70180,7,2,1,4,NA,4,4,1,4,56,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10510.490567,10944.785425,2,98,6,6,1,5,5,2,1,0,2,31,1,4,6,NA +70181,7,2,1,6,NA,1,1,2,6,72,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,2,2,2,NA,NA,NA,NA,13285.093011,13365.60735,2,94,77,77,NA,6,6,0,3,0,2,58,1,3,1,9 +70182,7,1,1,14,NA,5,6,NA,NA,NA,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10346.302718,0,2,91,4,4,0.65,5,5,1,3,0,1,43,2,3,5,NA +70183,7,2,2,37,NA,1,1,1,NA,NA,2,NA,2,1,7,NA,2,1,2,2,2,2,1,2,2,1,2,2,2,41791.57979,40663.955172,2,102,6,6,1.03,5,5,1,1,0,1,37,1,2,1,2 +70184,7,2,1,16,NA,4,4,1,16,194,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,16147.713323,16532.569027,1,92,15,15,4.44,5,5,0,3,0,2,43,1,5,6,NA +70185,7,2,2,4,NA,2,2,1,4,52,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13647.772496,15067.50708,2,93,7,7,1.83,3,3,1,0,0,1,40,2,5,1,4 +70186,7,2,1,48,NA,4,4,2,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,18533.049642,19320.837782,1,99,14,14,3.8,4,4,1,1,0,1,48,2,5,1,5 +70187,7,2,1,15,NA,5,6,2,15,180,NA,NA,2,1,99,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10567.840237,11294.273462,1,91,15,15,5,4,4,0,2,0,2,55,1,5,1,5 +70188,7,1,1,34,NA,5,6,NA,NA,NA,2,NA,2,2,4,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,15057.879445,0,3,90,12,12,NA,3,3,0,0,0,2,29,2,5,1,5 +70189,7,2,2,20,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,5,3,2,1,2,2,2,2,NA,NA,NA,NA,32455.694722,32314.335903,1,103,5,5,0.74,5,5,1,1,0,2,40,99,3,1,1 +70190,7,2,1,9,NA,1,1,1,9,116,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13927.458372,14042.313177,3,92,4,4,0.6,6,6,2,2,0,2,24,1,3,6,NA +70191,7,2,2,52,NA,2,2,2,NA,NA,2,NA,2,2,6,NA,1,3,NA,2,2,2,1,2,2,NA,NA,NA,NA,30346.899457,30505.155956,1,93,5,5,0.84,5,5,1,2,0,2,52,2,1,3,NA +70192,7,2,2,22,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,NA,NA,NA,NA,17397.027021,18573.153951,3,91,7,7,3.21,1,1,0,0,0,2,22,1,5,5,NA +70193,7,2,2,17,NA,2,2,2,17,208,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,17277.331962,18186.067085,1,90,6,6,0.81,6,6,0,3,0,2,45,1,4,1,2 +70194,7,2,2,29,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,5,6,2,1,2,2,1,2,2,1,2,2,1,13440.945024,14349.620822,1,103,15,8,4.03,2,1,0,0,0,2,29,2,5,6,NA +70195,7,2,1,79,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,NA,16888.31509,17277.940364,1,92,14,5,2.15,3,1,0,0,2,1,51,1,4,5,NA +70196,7,2,1,37,NA,1,1,1,NA,NA,2,NA,2,2,5,NA,1,5,NA,2,2,2,1,2,2,2,2,2,2,34997.800447,35379.102239,2,96,5,5,0.78,5,5,0,2,0,1,37,2,1,5,NA +70197,7,2,1,0,6,2,2,2,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5385.874932,5867.351136,2,90,8,8,2.24,4,4,1,1,0,2,29,1,4,6,NA +70198,7,2,2,62,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,11355.3308,11862.334174,1,96,15,15,5,2,2,0,0,2,2,62,1,4,1,2 +70199,7,2,1,7,NA,3,3,2,7,92,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,60593.636684,64068.123183,1,91,10,10,2.77,5,5,0,3,0,1,43,1,5,1,5 +70200,7,2,1,52,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,27551.752692,27682.321328,1,98,3,3,0.73,3,3,0,0,0,1,52,1,4,1,3 +70201,7,1,2,26,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,5,5,3,1,2,2,1,2,2,NA,NA,NA,NA,130601.953362,0,2,91,15,9,5,2,1,0,0,0,2,26,1,5,5,NA +70202,7,2,1,22,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,9956.598907,10266.888978,1,95,5,5,0.73,6,6,1,0,1,1,62,2,3,1,NA +70203,7,2,1,46,NA,5,6,2,NA,NA,2,NA,2,1,4,NA,2,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,12262.33683,12218.03828,2,100,4,4,0.44,7,7,1,2,2,1,71,2,1,1,1 +70204,7,2,2,20,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,18097.801029,17328.248994,2,100,7,7,1.38,5,5,1,0,0,2,45,1,2,3,NA +70205,7,2,2,7,NA,3,3,1,7,90,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,25527.806244,26565.240294,2,101,3,3,0.3,7,7,1,2,0,2,50,1,2,4,NA +70206,7,2,2,34,NA,5,6,2,NA,NA,2,NA,2,2,4,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,12808.938247,13423.491647,2,100,15,15,5,4,4,1,1,0,1,36,2,5,1,5 +70207,7,2,2,8,NA,3,3,1,8,101,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,63195.899182,62711.128206,1,100,15,15,5,4,4,1,1,0,1,40,1,5,1,5 +70208,7,2,1,2,NA,3,3,2,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,29706.069213,32871.212026,1,99,10,10,2.48,5,5,2,1,0,1,33,1,5,1,5 +70209,7,2,2,31,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,2,1,2,2,1,2,2,1,2,2,1,27945.726298,28031.650144,1,94,7,7,1.29,6,6,1,3,0,1,38,1,3,1,2 +70210,7,2,1,47,NA,1,1,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,41527.444056,55523.849773,1,95,5,5,1.5,2,2,0,1,0,1,47,1,4,2,NA +70211,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,38758.039282,44961.529423,1,98,6,6,1.9,2,2,0,0,2,1,80,1,1,1,2 +70212,7,2,2,40,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,2,1,2,2,1,2,2,1,2,2,1,20048.680628,21335.7055,2,95,5,5,1.05,3,3,0,1,0,1,43,1,3,1,2 +70213,7,2,1,35,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,94698.084211,97410.286035,1,101,14,14,3.15,5,5,2,1,0,1,35,1,4,1,5 +70214,7,2,1,21,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,25815.880139,25212.845431,2,101,1,1,0.42,1,1,0,0,0,1,21,1,4,5,NA +70215,7,2,2,80,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,1,2,NA,44484.790948,49854.064081,1,103,15,15,5,3,2,0,0,3,2,63,1,5,77,NA +70216,7,2,2,0,8,4,4,2,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,3941.796129,4340.984667,1,99,14,14,3.67,4,4,1,0,0,2,49,1,3,1,3 +70217,7,2,1,40,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,19158.860679,19089.647955,1,100,15,15,5,2,2,0,0,0,1,40,2,5,1,5 +70218,7,2,1,0,11,1,1,2,NA,12,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,6298.658963,6412.943673,2,94,5,5,1.07,4,4,2,0,0,1,37,2,1,1,1 +70219,7,2,2,69,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,42101.975168,42617.525207,1,95,6,6,0.96,5,5,1,0,1,2,69,1,1,2,NA +70220,7,2,2,31,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,2,1,2,2,2,2,2,2,2,2,2,2,2,41791.57979,43231.925575,2,102,10,10,3.04,4,4,2,0,0,2,31,2,2,1,NA +70221,7,2,2,11,NA,4,4,2,11,139,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9122.654131,9281.792212,1,96,9,9,3.14,3,3,0,2,0,2,39,NA,NA,3,NA +70222,7,2,1,60,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,88617.795432,87713.219218,1,91,15,15,5,1,1,0,0,1,1,60,1,5,1,NA +70223,7,2,1,47,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,146181.198007,145805.68861,2,91,15,2,0.79,7,1,0,0,1,1,49,NA,NA,5,NA +70224,7,2,2,19,NA,3,3,1,19,234,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,39616.634313,40360.331753,2,101,5,3,1.1,2,1,0,0,0,1,19,1,4,NA,NA +70225,7,2,1,25,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,105262.341027,112370.874556,2,98,10,10,4.42,2,2,0,0,0,1,25,1,5,1,5 +70226,7,2,2,70,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,1,5,NA,1,2,2,1,2,2,1,2,2,NA,12849.335508,13810.42202,1,96,4,4,1.18,2,2,0,0,1,2,70,1,1,5,NA +70227,7,2,2,46,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,15819.48188,17091.862943,1,90,15,15,5,5,5,0,3,0,2,46,2,4,1,5 +70228,7,2,1,67,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,7410.50521,7700.344649,2,96,3,3,0.82,2,2,0,1,1,1,67,1,3,3,NA +70229,7,2,2,30,NA,1,1,1,NA,NA,2,NA,2,2,6,NA,3,1,2,2,2,2,1,2,2,1,2,2,1,41791.57979,41445.196731,2,102,4,4,0.61,5,5,0,3,0,1,34,2,3,1,3 +70230,7,2,1,24,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,15976.466658,17286.192057,2,96,7,7,2.45,2,2,0,0,0,1,24,2,5,5,NA +70231,7,2,2,37,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,21619.283038,22210.398171,2,102,15,15,5,4,4,0,2,0,1,39,1,4,1,5 +70232,7,2,2,18,NA,5,6,2,18,217,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12224.9472,12547.183925,1,97,14,14,2.72,7,7,0,2,0,1,40,1,5,1,5 +70233,7,2,2,12,NA,1,1,2,12,148,NA,NA,1,1,NA,5,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,15591.526146,16856.688627,1,90,6,6,1.11,5,5,1,2,0,1,30,2,1,6,NA +70234,7,2,1,63,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,1,5,NA,1,1,2,1,1,2,1,1,2,NA,28559.076421,28710.827523,1,95,2,2,0.87,1,1,0,0,1,1,63,1,1,5,NA +70235,7,2,1,61,NA,2,2,2,NA,NA,2,NA,2,1,8,NA,1,2,NA,2,2,2,1,2,2,1,2,2,2,8609.250304,11228.904188,2,90,3,3,1.01,1,1,0,0,1,1,61,2,1,2,NA +70236,7,2,2,63,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,11355.3308,11862.334174,1,96,15,15,5,2,2,0,0,2,1,68,1,3,1,4 +70237,7,2,1,13,NA,3,3,2,14,168,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,68701.580401,72973.564721,2,94,15,15,5,5,5,0,3,0,1,44,1,5,1,4 +70238,7,2,2,25,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,3,2,1,2,2,1,2,2,1,2,2,1,32455.694722,32314.335903,1,103,7,7,0.51,7,7,3,4,0,1,54,2,1,1,1 +70239,7,2,2,43,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,19075.861607,19022.257361,1,96,10,10,3.04,4,4,0,1,0,2,43,1,5,1,4 +70240,7,2,2,4,NA,4,4,1,4,55,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10437.988787,11015.482909,2,100,99,99,NA,6,6,2,1,0,2,44,1,3,1,4 +70241,7,2,1,13,NA,4,4,2,13,157,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11800.231369,11823.561392,1,96,7,7,1,7,7,2,1,1,2,53,1,4,1,3 +70242,7,2,1,1,22,4,4,2,NA,22,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5799.129348,6038.750138,1,90,4,4,0.67,5,5,3,0,0,2,32,2,3,3,NA +70243,7,1,2,51,NA,5,6,NA,NA,NA,2,NA,2,1,6,NA,1,3,NA,1,2,1,1,2,1,NA,NA,NA,NA,21018.496735,0,1,91,9,9,2.68,4,4,0,0,1,1,20,NA,NA,5,NA +70244,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,9772.038079,10486.56257,1,95,77,77,NA,3,3,0,0,2,1,80,1,1,1,3 +70245,7,2,2,1,16,4,4,2,NA,16,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6398.740074,6885.115697,1,93,6,6,0.83,6,6,3,1,0,1,37,NA,NA,1,3 +70246,7,2,2,72,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,NA,14971.827573,15430.401607,2,97,8,8,2.7,3,3,0,0,1,2,72,1,2,3,NA +70247,7,2,2,54,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,17852.668137,17947.072019,3,91,9,9,4.08,2,2,0,1,0,2,54,2,5,1,NA +70248,7,2,2,67,NA,2,2,1,NA,NA,2,NA,2,1,6,NA,1,1,NA,2,2,2,1,2,2,2,2,2,2,7278.790659,7875.678599,2,93,3,3,0.66,2,2,0,0,1,1,54,2,1,1,1 +70249,7,2,1,7,NA,3,3,2,8,96,NA,NA,2,1,3,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,38712.032122,41122.784973,3,91,15,15,5,4,4,1,1,0,2,41,1,5,1,5 +70250,7,2,2,0,5,2,2,1,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10218.497734,10897.586635,2,101,15,15,5,3,3,1,0,0,1,37,1,5,1,5 +70251,7,2,2,43,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,43535.993088,45116.30779,2,102,77,77,NA,4,4,0,1,0,1,47,1,2,1,3 +70252,7,2,1,40,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,2,4,NA,1,2,2,1,2,2,1,2,2,1,14227.821648,16178.124803,3,90,2,2,0.45,1,1,0,0,0,1,40,2,2,4,NA +70253,7,2,1,0,8,5,7,2,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6246.568228,6909.306675,2,95,1,1,0.03,3,3,1,0,0,1,23,1,3,6,NA +70254,7,2,2,42,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,2,1,2,2,1,2,2,1,2,2,1,115926.402585,128579.517653,1,101,14,14,3.25,4,4,0,1,0,1,48,1,4,1,2 +70255,7,2,2,38,NA,1,1,1,NA,NA,2,NA,2,2,99,NA,1,6,2,2,2,2,1,2,2,2,2,2,2,53370.792448,51930.736348,1,100,NA,13,NA,2,1,0,0,0,1,32,2,1,6,NA +70256,7,2,2,16,NA,5,6,1,16,198,NA,NA,2,1,4,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,9098.177005,9288.806625,1,98,14,14,3.9,4,4,0,1,0,2,52,1,5,1,5 +70257,7,2,2,1,20,4,4,2,NA,21,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5687.793894,6002.477845,2,90,8,6,1.67,5,3,2,0,0,2,25,2,3,5,NA +70258,7,2,2,24,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,61710.107686,72008.199278,1,98,3,3,0.9,1,1,0,0,0,2,24,1,5,5,NA +70259,7,2,1,65,NA,4,4,2,NA,NA,2,NA,2,1,6,NA,3,1,NA,1,2,2,1,2,2,1,2,1,1,7514.993062,8122.478925,2,90,2,2,0.48,2,2,0,0,1,2,53,2,3,1,3 +70260,7,2,2,0,11,2,2,1,NA,12,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,NA,NA,NA,NA,NA,NA,NA,6235.764746,6104.57156,2,92,NA,NA,NA,4,4,2,0,0,1,40,NA,NA,1,NA +70261,7,2,1,24,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,37814.382501,38402.065392,1,98,6,4,1.34,2,1,0,0,0,2,22,1,4,6,NA +70262,7,2,1,7,NA,2,2,1,7,90,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10738.959181,11444.574702,2,93,10,10,2.26,6,6,0,4,0,1,34,1,4,1,3 +70263,7,2,2,49,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,18522.193415,19195.925691,1,90,9,9,2.6,4,4,0,1,0,2,49,2,2,1,5 +70264,7,2,2,23,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,NA,NA,NA,1,2,2,1,11475.373333,11965.391974,2,92,12,NA,NA,7,1,0,0,2,1,53,2,3,1,3 +70265,7,2,2,46,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,1,19378.199212,21493.287569,2,100,5,5,1.3,3,3,0,1,0,2,46,1,3,2,NA +70266,7,2,2,62,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,16420.864787,17154.038836,2,102,14,14,5,2,2,0,0,2,1,64,1,4,1,3 +70267,7,2,1,32,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,20891.980831,21490.337905,2,97,12,14,5,2,1,0,0,0,1,53,NA,NA,5,NA +70268,7,2,1,46,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,30549.358294,31009.655884,2,101,5,5,1.93,1,1,0,0,0,1,46,1,4,5,NA +70269,7,2,1,0,9,3,3,2,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8212.233655,8522.67606,2,91,2,2,0.33,5,5,1,1,0,2,48,1,4,3,NA +70270,7,2,2,2,NA,4,4,2,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6084.391121,6799.274602,2,99,3,3,0.56,4,4,1,0,0,2,38,1,3,5,NA +70271,7,1,1,34,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,17879.023129,0,2,90,7,7,3.49,1,1,0,0,0,1,34,1,3,5,NA +70272,7,2,2,1,16,4,4,2,NA,17,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6811.556363,7329.310628,1,96,12,12,NA,5,5,1,2,0,2,35,1,5,1,4 +70273,7,2,2,8,NA,1,1,1,8,105,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15962.145468,16371.237244,2,98,1,1,0.18,4,4,0,2,0,1,29,1,4,6,NA +70274,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,30212.098573,33743.401779,2,98,3,3,1.24,1,1,0,0,1,2,80,1,4,2,NA +70275,7,2,2,20,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,26999.643202,25671.572746,2,102,6,6,1.22,5,5,0,2,0,2,42,1,4,1,4 +70276,7,2,2,51,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,164908.075108,169304.25724,1,98,15,15,5,3,3,0,0,0,1,56,1,5,1,5 +70277,7,2,2,0,9,1,1,1,NA,10,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,6021.973783,5836.909368,1,102,2,2,0.19,7,7,2,2,0,1,48,2,9,1,9 +70278,7,2,2,36,NA,4,4,2,NA,NA,2,NA,2,2,4,NA,2,1,3,1,2,2,1,2,2,NA,NA,NA,NA,21765.629914,21610.101161,2,90,6,6,1.03,6,6,3,1,0,1,45,2,2,1,2 +70279,7,2,2,53,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,17521.481386,17626.852628,2,97,99,99,NA,1,1,0,0,0,2,53,1,3,3,NA +70280,7,2,1,18,NA,2,2,1,18,221,2,NA,2,2,3,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,20606.470013,20581.836663,1,103,6,6,0.93,5,5,0,1,0,1,39,2,3,1,3 +70281,7,2,2,30,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,20012.879008,20053.743639,1,100,7,7,3.13,1,1,0,0,0,2,30,1,4,5,NA +70282,7,2,1,24,NA,1,1,2,NA,NA,2,NA,2,2,6,NA,2,5,NA,2,2,2,2,2,2,1,2,2,1,35669.2076,36155.406423,2,94,7,7,1.23,6,6,2,1,0,1,33,2,1,6,NA +70283,7,2,1,11,NA,1,1,2,11,141,NA,NA,1,1,NA,5,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,13484.595524,13595.798197,1,97,8,8,1.45,6,6,2,2,0,2,36,2,2,1,1 +70284,7,2,2,4,NA,5,6,2,4,52,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,3864.413878,3822.111022,1,99,14,14,2.66,7,7,3,1,0,1,35,1,5,1,5 +70285,7,2,2,37,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,NA,NA,NA,NA,28958.579549,29304.033516,1,96,13,13,NA,5,5,1,1,0,1,42,1,3,5,NA +70286,7,2,1,18,NA,3,3,2,18,221,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,71231.747774,75661.062324,2,95,9,9,2.22,5,5,1,0,0,1,55,1,4,1,5 +70287,7,2,2,46,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,18844.090639,18943.737107,2,96,15,15,5,2,2,0,0,0,1,45,1,5,1,4 +70288,7,2,2,37,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,1,2,1,2,2,1,2,2,1,2,2,1,71034.153987,76359.172033,1,98,6,6,1.11,5,5,0,2,1,2,37,1,1,1,1 +70289,7,2,1,8,NA,3,3,2,8,99,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,46228.073505,47549.950918,2,94,10,10,2.91,4,4,0,2,0,2,38,1,4,1,4 +70290,7,2,1,60,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,10880.024478,11166.738171,2,91,9,9,3.14,3,3,0,1,2,1,60,1,4,1,3 +70291,7,2,2,25,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,35313.648114,35629.376203,2,95,6,6,0.9,6,6,1,1,0,1,49,1,1,1,1 +70292,7,2,2,48,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,19130.246369,22400.771377,2,95,15,10,3.67,5,3,0,0,0,1,47,1,5,1,3 +70293,7,2,2,51,NA,5,6,2,NA,NA,2,NA,2,2,4,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,17149.727778,17902.578105,1,90,4,4,0.78,4,4,0,0,1,1,69,2,4,1,3 +70294,7,2,1,60,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,8219.195224,8283.488354,2,99,15,15,5,2,2,0,0,2,1,60,1,5,1,5 +70295,7,2,1,47,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,21158.364877,21743.069946,1,96,15,15,4.9,4,4,0,1,0,1,47,1,3,1,5 +70296,7,2,2,0,4,3,3,2,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,17674.326293,18731.006164,3,90,15,15,5,3,3,1,0,0,1,31,1,5,1,5 +70297,7,2,1,73,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,60942.568495,64726.722108,1,94,7,7,2.51,2,2,0,0,2,2,72,1,4,1,1 +70298,7,2,2,42,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,22707.329726,23560.698233,2,97,2,2,0.3,4,4,0,2,0,1,42,1,2,6,NA +70299,7,2,1,62,NA,5,6,2,NA,NA,2,NA,2,1,4,NA,3,2,NA,1,2,2,1,2,2,1,2,2,1,7192.368251,7796.453586,1,93,4,4,1.74,1,1,0,0,1,1,62,2,3,2,NA +70300,7,2,1,46,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,27466.648066,27396.091902,1,99,2,2,0.61,2,2,0,0,0,1,46,1,5,5,NA +70301,7,2,2,51,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,21143.964074,21647.100945,1,100,1,1,0.04,4,4,1,1,0,2,51,1,3,3,NA +70302,7,2,1,23,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,42894.724338,43561.362107,1,98,6,4,1.34,2,1,0,0,0,1,24,1,5,5,NA +70303,7,2,1,56,NA,2,2,2,NA,NA,1,1,2,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,34813.426994,34467.752983,1,97,15,15,5,1,1,0,0,0,1,56,2,4,3,NA +70304,7,2,2,65,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,1,122483.259869,138551.168646,3,91,7,7,3.49,1,1,0,0,1,2,65,1,3,2,NA +70305,7,2,1,0,2,3,3,1,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,23912.171644,23498.78217,1,91,15,15,5,3,3,1,0,0,1,33,1,5,1,5 +70306,7,2,1,20,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,25645.251384,25514.298117,1,92,6,6,1.31,3,3,0,0,1,2,80,1,3,4,NA +70307,7,2,1,22,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,47487.549895,49034.44781,1,102,6,6,1.48,3,3,0,0,1,2,57,2,1,1,4 +70308,7,2,1,5,NA,1,1,1,6,72,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,20874.345556,20902.551716,3,92,2,2,0.47,3,3,1,1,0,2,33,1,4,5,NA +70309,7,2,1,2,NA,1,1,1,2,26,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12413.685227,12209.161559,1,102,6,6,1.46,3,3,1,1,0,2,28,2,4,3,NA +70310,7,1,2,11,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,1,2,NA,NA,NA,NA,9139.784234,0,2,100,6,6,1.18,5,5,0,2,1,2,70,1,2,77,NA +70311,7,2,1,7,NA,1,1,1,8,96,NA,NA,2,2,2,1,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,13581.60325,14182.420159,1,100,99,99,NA,7,7,2,3,0,2,35,2,1,1,NA +70312,7,2,2,73,NA,2,2,2,NA,NA,2,NA,2,1,9,NA,1,4,NA,2,2,2,1,2,2,1,2,2,NA,17318.187297,23904.945555,2,90,2,2,0.73,1,1,0,0,1,2,73,2,1,4,NA +70313,7,2,2,37,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,26465.930618,27183.288271,2,100,15,15,4.47,4,4,0,2,0,1,39,NA,NA,1,5 +70314,7,2,1,5,NA,3,3,2,5,62,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,58618.419318,66135.507563,2,94,12,12,NA,5,5,1,1,0,1,37,1,4,1,3 +70315,7,2,2,5,NA,5,6,2,5,61,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4938.043177,5373.703942,1,91,5,5,0.89,4,4,2,0,0,1,39,1,4,1,5 +70316,7,2,1,2,NA,4,4,2,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4667.634102,4955.769831,3,90,15,15,5,5,5,1,0,1,1,38,2,3,1,4 +70317,7,2,1,51,NA,5,6,1,NA,NA,2,NA,2,2,5,NA,3,1,NA,1,2,1,1,2,1,1,2,1,3,12813.519628,13398.278814,2,92,7,7,1.61,4,4,0,2,0,1,51,2,3,1,3 +70318,7,2,2,23,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,6,2,1,2,2,1,2,2,1,2,2,1,85402.868381,86166.428247,2,94,77,77,NA,2,2,0,0,0,2,23,1,3,6,NA +70319,7,2,1,55,NA,5,6,1,NA,NA,2,NA,2,2,7,NA,1,4,NA,1,2,2,1,2,2,1,2,2,1,16499.662173,17012.89406,3,91,6,6,1.77,2,2,0,0,0,2,57,2,1,1,1 +70320,7,2,1,4,NA,2,2,1,4,54,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16288.754504,16020.386509,2,92,15,15,5,3,3,1,0,0,2,48,2,5,1,5 +70321,7,2,1,63,NA,2,2,2,NA,NA,2,NA,2,1,8,NA,4,3,NA,2,2,2,1,2,2,1,2,2,2,9115.676792,9431.98541,2,90,5,5,1.84,1,1,0,0,1,1,63,2,4,3,NA +70322,7,2,1,16,NA,1,1,2,16,200,NA,NA,2,2,3,10,NA,NA,NA,2,2,2,2,2,2,1,2,2,1,21633.039913,21721.097793,2,94,7,7,1.04,7,7,0,3,0,1,37,2,1,1,3 +70323,7,2,2,7,NA,4,4,2,7,89,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8757.841043,8910.615224,2,97,2,2,0.38,3,3,1,1,0,2,27,1,2,5,NA +70324,7,2,2,14,NA,3,3,2,15,180,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,109773.944307,112955.590462,1,98,15,15,4.34,4,4,0,2,0,1,51,1,5,1,5 +70325,7,2,2,6,NA,1,1,2,6,83,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14679.337943,15307.210901,1,90,15,15,4.77,4,4,1,1,0,2,41,1,5,1,2 +70326,7,2,1,35,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,22188.836739,23952.480361,1,95,5,5,0.89,4,4,0,1,0,2,42,1,4,6,NA +70327,7,2,2,62,NA,2,2,2,NA,NA,2,NA,2,1,5,NA,4,1,NA,1,2,2,1,2,2,1,2,2,2,12121.359422,12627.249955,2,99,15,15,5,2,2,0,0,2,1,64,2,5,1,4 +70328,7,2,1,27,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,3,1,NA,2,2,2,1,2,2,1,2,2,2,35782.041084,36966.59793,2,96,1,1,0.06,5,5,2,1,0,1,27,2,3,1,4 +70329,7,2,2,60,NA,2,2,2,NA,NA,2,NA,2,2,5,NA,2,1,NA,2,2,2,2,2,2,2,2,2,2,9716.805546,12994.252166,2,90,3,3,0.46,5,5,0,2,2,1,75,2,1,1,2 +70330,7,2,1,77,NA,5,6,2,NA,NA,2,NA,2,1,5,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,8286.514589,8909.879599,3,91,7,7,1.33,6,6,0,0,2,2,51,2,5,1,5 +70331,7,2,1,52,NA,1,1,1,NA,NA,2,NA,2,2,7,NA,1,1,NA,2,2,1,2,2,1,NA,NA,NA,NA,33162.406014,36437.864606,3,92,4,4,0.66,4,4,0,1,0,1,52,2,1,1,1 +70332,7,2,1,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,NA,10676.164039,11456.797578,2,97,4,4,1.29,2,2,0,0,2,1,74,1,3,3,NA +70333,7,2,2,20,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,48470.428632,49964.788237,1,98,15,15,5,5,5,0,1,1,2,55,1,5,1,5 +70334,7,2,1,11,NA,4,4,2,11,139,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10229.206765,10406.656985,1,96,15,15,4.52,6,6,0,4,0,1,46,1,4,1,4 +70335,7,2,2,53,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,38954.135779,44674.189003,1,91,3,3,1.15,1,1,0,0,0,2,53,1,4,3,NA +70336,7,2,2,74,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,2,2,2,NA,15730.58404,17568.357111,2,98,6,6,1.62,3,3,0,0,1,2,74,1,1,2,NA +70337,7,2,1,38,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,19788.748292,24506.181083,1,94,7,7,1.29,6,6,1,3,0,1,38,1,3,1,2 +70338,7,2,2,36,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,4,2,1,2,2,1,2,2,1,2,2,1,42468.064168,42915.721814,2,101,6,6,1.16,4,4,0,3,0,2,36,1,4,4,NA +70339,7,2,2,55,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,33248.548181,34134.900613,1,98,4,4,0.89,3,3,0,0,1,2,55,1,5,1,NA +70340,7,2,2,16,NA,5,6,2,16,197,NA,NA,1,1,NA,8,NA,NA,NA,1,2,1,1,2,1,1,2,2,1,10767.566937,11540.84845,2,91,12,12,NA,7,6,0,4,2,2,72,2,1,2,NA +70341,7,2,1,62,NA,5,6,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,12579.986433,13271.133625,1,92,14,14,5,2,2,0,0,2,1,62,1,4,1,4 +70342,7,2,2,61,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,2,2,NA,1,2,1,1,2,1,1,2,1,3,11838.431472,12295.352662,2,92,7,7,1.89,3,3,0,0,1,1,36,2,3,5,NA +70343,7,2,1,11,NA,5,6,1,11,133,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7179.084455,7651.500738,2,98,9,9,2.29,5,5,0,2,0,1,36,1,4,1,4 +70344,7,2,1,1,18,4,4,1,NA,20,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6376.965739,6390.839385,2,100,3,3,0.31,7,7,3,2,0,2,28,1,3,1,3 +70345,7,2,1,5,NA,1,1,1,5,66,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,14321.363328,13945.949794,2,96,77,77,NA,7,7,3,2,0,2,33,2,2,6,NA +70346,7,2,2,11,NA,1,1,1,11,142,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15962.145468,16412.026403,2,98,14,14,2.87,5,5,0,3,0,2,34,1,2,1,2 +70347,7,2,1,70,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,10025.317761,10256.608873,2,103,15,15,5,3,3,0,0,1,2,55,1,4,1,5 +70348,7,2,2,9,NA,3,3,1,9,118,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,22933.149195,23865.138008,1,101,4,4,0.58,6,6,0,4,0,2,41,1,3,5,NA +70349,7,2,2,80,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,12535.973802,12972.182488,2,100,4,4,0.97,3,3,0,0,3,2,80,1,5,2,NA +70350,7,2,2,18,NA,3,3,1,18,221,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,71832.578284,79011.982474,1,92,14,14,3.16,6,6,1,1,0,1,49,1,1,1,3 +70351,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,38799.676345,43482.761402,1,94,6,6,2.24,1,1,0,0,1,2,80,1,4,2,NA +70352,7,2,2,55,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,4,NA,1,2,2,1,2,2,1,2,2,1,29167.119125,29652.805867,1,101,2,2,0.22,4,4,1,0,0,2,25,1,4,6,NA +70353,7,2,1,6,NA,4,4,2,6,83,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8227.856305,9153.104022,3,91,1,1,0.07,6,6,2,3,0,2,30,1,2,3,NA +70354,7,2,1,17,NA,4,4,2,17,207,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11125.932433,11147.929312,1,96,8,8,2,4,4,1,2,0,2,40,1,4,5,NA +70355,7,2,1,65,NA,5,6,2,NA,NA,2,NA,2,1,4,NA,4,1,NA,1,2,1,1,2,1,1,2,1,3,9963.081107,10271.419526,1,91,4,4,1.33,2,2,0,0,2,1,65,2,4,1,3 +70356,7,2,2,25,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,1,5,2,1,2,2,1,2,2,1,2,2,1,67534.233567,86418.733625,1,97,3,3,0.83,2,2,0,0,0,2,25,1,1,5,NA +70357,7,2,2,43,NA,5,6,2,NA,NA,2,NA,2,2,5,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,12601.697316,12716.910215,1,91,15,15,5,6,6,0,2,2,1,50,2,5,1,5 +70358,7,2,2,44,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,2,1,2,2,1,2,2,1,2,2,1,154825.466557,155723.680504,1,91,8,8,4.41,1,1,0,0,0,2,44,1,4,3,NA +70359,7,2,1,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,46965.818538,50603.721684,1,95,14,14,5,2,2,0,0,2,1,80,1,4,1,NA +70360,7,2,2,8,NA,4,4,2,8,104,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8147.287486,8823.301862,2,90,5,5,1.63,2,2,0,1,0,2,38,2,3,5,NA +70361,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,1,2,1,2,2,1,1,2,NA,50879.818001,58591.132961,1,101,6,6,1.31,3,3,0,0,1,2,80,1,1,2,NA +70362,7,2,2,61,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,8308.628726,8679.600111,2,95,5,5,1.96,1,1,0,0,1,2,61,1,4,2,NA +70363,7,2,2,62,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,122483.259869,124909.680309,3,91,15,15,5,2,2,0,0,2,2,62,1,5,1,5 +70364,7,2,1,73,NA,5,7,1,NA,NA,2,NA,2,1,9,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,11532.082424,12399.599956,2,103,12,12,NA,2,2,0,0,2,1,73,2,5,1,4 +70365,7,2,2,7,NA,5,6,1,7,95,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8290.163782,8692.019106,1,92,2,2,0.24,5,5,0,2,0,1,35,2,4,1,3 +70366,7,2,2,49,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,19693.606802,19976.427063,1,99,12,12,NA,2,2,0,0,0,1,28,1,5,5,NA +70367,7,2,2,36,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,56938.907307,57514.428801,2,95,15,15,4.63,5,5,1,2,0,2,36,1,5,1,3 +70368,7,2,1,55,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,19779.547388,20214.272069,2,96,15,15,5,3,3,0,1,0,1,55,1,5,1,4 +70369,7,2,2,22,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,NA,NA,NA,NA,60324.348827,64927.943097,1,95,4,4,0.97,3,3,2,0,0,2,22,1,4,5,NA +70370,7,2,1,6,NA,4,4,2,6,83,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8439.71412,8914.772112,2,99,7,7,1.19,6,6,1,3,0,2,38,1,3,5,NA +70371,7,2,2,2,NA,1,1,1,2,35,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,11582.174418,12474.053558,2,102,7,7,1.04,7,7,1,2,0,2,37,2,1,1,2 +70372,7,2,1,61,NA,1,1,1,NA,NA,2,NA,2,7,77,NA,4,1,NA,2,2,2,1,2,2,1,2,2,1,11568.876339,11794.347884,1,102,77,77,NA,3,3,0,0,1,1,61,2,4,1,1 +70373,7,2,1,5,NA,1,1,2,5,67,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,14505.510202,14676.996441,2,94,77,77,NA,5,5,1,1,0,1,41,2,2,1,2 +70374,7,2,1,4,NA,3,3,1,4,51,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,33334.752566,38103.457131,3,92,6,6,0.74,7,7,2,1,0,2,46,1,2,1,4 +70375,7,2,2,19,NA,1,1,1,19,231,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,21062.314667,23105.758741,1,94,6,6,1.3,4,4,2,0,0,1,24,2,1,1,4 +70376,7,2,1,17,NA,1,1,1,17,215,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,14432.845547,14415.592261,1,103,7,7,0.51,7,7,3,4,0,1,54,2,1,1,1 +70377,7,2,1,3,NA,2,2,2,3,42,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12403.412256,12420.172189,2,90,2,2,0.49,3,3,2,0,0,2,26,1,4,1,NA +70378,7,2,1,53,NA,4,4,2,NA,NA,2,NA,2,1,6,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,18681.278463,18953.419735,1,93,7,7,1.79,4,4,0,2,0,1,53,2,4,1,4 +70379,7,2,2,2,NA,2,2,1,2,35,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11443.671453,12634.120381,1,100,15,15,4.34,4,4,2,0,0,2,35,1,5,1,5 +70380,7,2,1,9,NA,4,4,2,9,117,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7730.47951,9212.541007,1,99,6,6,1.3,5,5,1,2,0,1,34,1,2,1,3 +70381,7,2,1,24,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,39031.957066,39638.562591,1,95,6,6,0.96,5,5,1,0,1,2,69,1,1,2,NA +70382,7,2,1,1,22,1,1,1,NA,23,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,2,2,2,NA,NA,NA,NA,10960.671575,11090.250219,2,96,4,4,0.69,5,5,2,0,0,2,57,2,1,4,NA +70383,7,2,2,4,NA,3,3,2,4,53,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,67177.961189,74143.696839,1,98,9,9,2.6,4,4,1,1,0,2,35,1,2,1,NA +70384,7,2,1,25,NA,4,4,1,NA,NA,2,NA,2,1,4,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,23484.626749,24110.252242,2,96,6,6,1.7,2,2,0,1,0,1,25,2,4,5,NA +70385,7,2,2,57,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,15002.194143,18506.393496,3,90,7,2,0.77,2,1,0,0,0,1,44,1,2,6,NA +70386,7,2,1,38,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,17554.053699,17499.245836,1,96,2,2,0.73,1,1,0,0,0,1,38,1,3,5,NA +70387,7,2,2,60,NA,1,1,1,NA,NA,2,NA,2,1,6,NA,3,6,NA,2,2,2,2,2,2,2,2,2,2,15876.871857,17052.998921,2,102,14,7,3.67,2,1,0,0,2,1,65,2,3,6,NA +70388,7,2,1,12,NA,3,3,2,12,155,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,56223.281913,55799.760014,1,99,14,14,4.86,3,3,0,1,0,1,56,1,5,1,5 +70389,7,2,2,56,NA,2,2,2,NA,NA,2,NA,2,2,5,NA,3,4,NA,2,2,2,2,2,2,2,2,1,2,20734.495277,22784.232134,2,99,99,99,NA,4,1,0,0,0,2,42,2,4,5,NA +70390,7,2,2,8,NA,1,1,1,8,105,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10118.363218,10311.586628,1,103,7,7,0.51,7,7,3,4,0,1,54,2,1,1,1 +70391,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,NA,27681.279,30792.259764,1,91,3,3,1.29,1,1,0,0,1,2,80,1,3,5,NA +70392,7,2,1,0,10,2,2,2,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5610.286388,5712.081065,2,90,6,6,1.34,4,4,1,2,0,2,36,2,3,77,NA +70393,7,2,1,9,NA,4,4,1,9,111,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9418.975084,9571.535533,2,93,5,5,1.04,4,4,1,1,0,1,29,1,3,6,NA +70394,7,2,1,47,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,13883.119445,13832.965705,1,103,15,15,5,1,1,0,0,0,1,47,1,5,5,NA +70395,7,1,1,36,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,114168.79702,0,1,95,14,14,3.8,4,4,1,1,0,1,36,1,4,1,5 +70396,7,2,1,6,NA,5,7,1,6,77,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8930.369586,9194.254241,3,91,14,14,3.8,4,4,0,2,0,1,47,1,5,1,5 +70397,7,2,1,19,NA,1,1,1,19,234,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,21898.969807,22012.999264,2,102,15,15,3.92,5,5,0,0,0,1,19,1,4,NA,NA +70398,7,2,2,57,NA,2,2,2,NA,NA,2,NA,2,1,6,NA,2,4,NA,2,2,2,1,2,2,1,2,2,NA,21097.069797,24201.517172,2,90,6,6,1.7,2,2,0,0,0,2,57,2,2,4,NA +70399,7,2,1,24,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,14379.41014,15757.242021,1,94,7,3,0.9,4,1,0,0,0,1,24,NA,NA,5,NA +70400,7,2,2,21,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,1,1,2,2,1,2,2,1,2,2,1,18723.98095,17927.802584,2,101,7,7,1.3,5,5,2,0,1,2,50,1,4,1,3 +70401,7,2,1,47,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,14879.667962,15815.934168,3,91,15,15,5,3,3,0,1,0,1,47,2,5,1,5 +70402,7,2,1,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,8796.577101,9772.20689,2,95,5,5,1.32,2,2,0,0,2,1,80,1,3,1,3 +70403,7,2,1,13,NA,1,1,1,13,159,NA,NA,1,1,NA,5,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,19242.904841,19537.039374,2,96,5,5,0.68,6,6,0,3,2,1,60,2,1,1,1 +70404,7,2,2,7,NA,2,2,2,7,92,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,20753.369981,21666.802981,1,97,5,5,1.04,4,4,1,1,0,1,32,1,3,6,NA +70405,7,2,2,61,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,118611.064701,118209.809508,1,91,15,15,5,2,2,0,0,2,1,63,1,4,1,5 +70406,7,2,2,41,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,31454.59168,33587.963223,1,94,4,4,1,3,3,0,1,0,2,41,1,4,5,NA +70407,7,1,2,3,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9492.170663,0,1,90,4,4,0.67,5,5,3,0,0,2,32,2,3,3,NA +70408,7,2,1,33,NA,4,4,2,NA,NA,2,NA,2,1,5,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,20803.970543,21557.298406,1,93,14,14,5,2,2,0,0,1,1,33,2,5,5,NA +70409,7,2,1,44,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,126789.52929,130374.456976,1,101,6,6,1.31,3,3,0,0,1,2,80,1,1,2,NA +70410,7,2,1,6,NA,2,2,1,6,80,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9741.585979,9800.624884,2,103,12,2,0.59,5,2,0,1,0,2,47,NA,NA,3,NA +70411,7,2,2,23,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,50915.06085,50693.303376,3,92,5,5,0.81,5,5,3,0,0,2,23,1,4,5,NA +70412,7,2,1,14,NA,1,1,2,15,180,NA,NA,1,1,NA,10,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,20398.562455,21727.336109,2,94,6,6,1.34,4,4,0,2,0,1,37,2,4,1,2 +70413,7,2,1,51,NA,5,6,2,NA,NA,2,NA,2,1,5,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,9889.944368,10305.962662,1,99,10,10,3.51,3,3,0,1,0,2,44,1,3,1,5 +70414,7,2,2,25,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,6,2,1,2,2,1,2,2,1,2,2,1,128171.594518,136210.394705,1,93,15,15,5,2,2,0,0,0,1,28,1,5,6,NA +70415,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,52752.276869,57774.89643,1,98,12,12,NA,1,1,0,0,1,2,80,1,5,2,NA +70416,7,2,1,25,NA,2,2,1,NA,NA,2,NA,2,2,2,NA,4,5,NA,1,2,2,1,2,2,1,2,1,2,38474.772527,40200.135096,2,93,7,2,0.81,3,1,0,0,0,1,25,2,4,5,NA +70417,7,2,1,80,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,1,3,NA,2,2,2,1,2,2,1,2,2,NA,14200.083364,15006.095575,3,92,4,4,1.65,1,1,0,0,1,1,80,1,1,3,NA +70418,7,1,2,80,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,47566.45715,0,1,90,6,6,2.86,1,1,0,0,1,2,80,1,4,5,NA +70419,7,2,1,2,NA,2,2,2,2,25,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,1,2,2,1,NA,NA,NA,NA,10244.841997,10258.685193,1,96,5,5,0.94,4,4,2,0,0,1,32,2,3,1,4 +70420,7,2,2,55,NA,2,2,2,NA,NA,2,NA,2,2,3,NA,1,2,NA,2,2,2,2,2,2,NA,NA,NA,NA,24004.6026,24129.784561,2,91,4,4,0.43,7,7,0,1,1,1,41,2,1,4,NA +70421,7,2,2,51,NA,2,2,2,NA,NA,2,NA,2,2,7,NA,2,3,NA,1,2,2,1,2,2,1,2,2,2,17054.056149,20556.446647,2,90,8,8,2.7,3,3,0,1,0,2,31,1,5,4,NA +70422,7,2,2,9,NA,2,2,2,9,114,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15148.721588,16989.423356,2,91,2,2,0.22,4,4,1,1,0,2,48,2,9,5,NA +70423,7,2,1,52,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,32461.799549,39033.401297,1,101,5,5,0.89,5,5,1,0,0,1,25,1,2,77,NA +70424,7,2,1,28,NA,2,2,2,NA,NA,2,NA,2,2,3,NA,2,6,NA,2,2,2,1,2,2,1,2,2,1,41271.869706,41834.437137,1,96,9,9,3.97,2,2,0,0,0,1,28,2,2,6,NA +70425,7,2,1,77,NA,3,3,2,NA,NA,1,2,2,1,9,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,63054.867183,67969.319596,1,90,8,8,3.3,2,2,0,0,2,1,77,2,2,1,5 +70426,7,2,1,66,NA,1,1,1,NA,NA,2,NA,2,1,8,NA,1,1,NA,2,2,2,1,2,2,2,2,2,2,14488.953694,14844.946966,3,92,8,8,1.85,5,5,1,0,2,1,66,2,1,1,1 +70427,7,2,2,36,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,75152.05379,75383.121447,2,92,15,15,5,2,2,0,0,0,1,37,1,5,1,5 +70428,7,2,2,0,4,3,3,1,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10025.884543,10365.226844,3,92,6,6,0.74,7,7,2,1,0,2,46,1,2,1,4 +70429,7,2,2,44,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,2,1,2,2,1,2,2,1,2,2,1,134587.275919,139488.984678,1,92,8,8,2.17,4,4,0,1,2,2,80,1,3,2,NA +70430,7,2,2,37,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,97705.030285,101386.34066,2,94,14,14,4.71,3,3,1,0,0,1,35,1,5,1,5 +70431,7,2,2,20,NA,2,2,1,NA,NA,2,NA,2,2,3,NA,2,5,2,1,2,2,2,2,2,1,2,2,1,32455.694722,32314.335903,2,103,5,5,0.65,6,6,1,0,1,2,61,2,1,2,NA +70432,7,2,2,42,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,145772.192378,152604.524555,1,95,15,15,5,4,4,0,2,0,2,42,1,5,1,5 +70433,7,2,1,16,NA,1,1,1,16,199,NA,NA,1,1,NA,8,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,22768.423624,22944.003607,2,98,14,14,2.87,5,5,0,3,0,2,34,1,2,1,2 +70434,7,2,2,0,2,3,3,1,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,18869.566209,19997.704869,2,92,15,15,5,3,3,1,0,0,1,48,1,5,1,5 +70435,7,2,2,17,NA,2,2,1,17,214,2,NA,2,1,4,14,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,14984.257718,15414.270546,2,92,10,7,2.38,3,2,0,1,0,1,29,2,4,6,NA +70436,7,2,2,8,NA,4,4,1,8,103,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11116.391625,11717.604707,2,98,6,6,1,5,5,2,1,0,2,31,1,4,6,NA +70437,7,2,1,43,NA,1,1,1,NA,NA,2,NA,2,1,6,NA,2,1,NA,2,2,2,2,2,2,2,2,2,2,34153.424332,40514.279864,1,100,7,7,1.3,5,5,0,3,0,1,43,2,2,1,4 +70438,7,2,1,42,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,138834.18124,143254.613293,1,100,15,15,5,4,4,0,2,0,2,47,1,5,1,5 +70439,7,2,2,24,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,76027.409363,76707.146234,2,103,15,15,3.44,7,7,0,1,2,2,79,1,3,2,NA +70440,7,2,1,14,NA,4,4,2,14,178,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10081.970102,10544.115448,2,99,4,4,0.78,4,4,0,2,0,2,45,1,3,5,NA +70441,7,2,2,2,NA,2,2,2,2,27,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,8134.473424,8243.872451,2,99,5,5,1.26,3,3,1,0,0,1,24,2,2,1,1 +70442,7,2,2,57,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,41309.21018,41341.432201,1,100,4,4,1.19,2,2,0,0,1,1,62,1,5,1,5 +70443,7,2,2,52,NA,2,2,1,NA,NA,2,NA,2,1,8,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,33018.025291,33777.066037,1,92,8,8,3.3,2,2,0,0,0,1,40,2,5,1,5 +70444,7,2,1,13,NA,1,1,1,13,160,NA,NA,2,2,3,6,NA,NA,NA,2,1,1,1,2,1,1,2,2,1,27378.670648,27589.802811,2,96,3,3,0.95,2,2,0,1,0,2,38,2,3,3,NA +70445,7,2,2,71,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,52814.190351,53378.216173,1,98,12,12,NA,2,2,0,0,2,1,65,1,4,1,3 +70446,7,2,2,45,NA,1,1,2,NA,NA,2,NA,2,2,4,NA,4,1,NA,2,2,2,1,2,2,NA,NA,NA,NA,31235.666551,31398.557894,3,92,6,6,1,6,6,1,1,0,1,42,2,1,1,4 +70447,7,2,1,29,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,23484.626749,23642.328802,2,96,14,14,4.26,3,3,0,0,0,1,20,1,4,5,NA +70448,7,2,1,29,NA,1,1,2,NA,NA,2,NA,2,2,3,NA,3,4,NA,2,2,2,1,2,2,2,2,2,2,40078.999044,48909.175469,3,91,6,6,0.89,7,7,1,1,0,1,59,2,1,1,1 +70449,7,2,2,12,NA,2,2,1,12,146,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,20128.183753,21457.209224,2,100,14,14,3.58,4,4,0,2,0,2,40,NA,NA,1,4 +70450,7,2,1,15,NA,3,3,1,15,190,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,63633.689496,63154.346062,2,100,10,10,3.13,4,4,0,2,0,1,45,1,4,1,4 +70451,7,2,2,35,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,17286.767396,17743.751095,2,100,2,2,0.38,3,3,0,2,0,2,35,1,4,5,NA +70452,7,2,1,17,NA,5,6,2,17,213,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,6232.587755,6841.667882,1,91,7,7,1.57,4,4,0,3,0,2,38,2,2,3,NA +70453,7,2,2,1,22,4,4,1,NA,23,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8221.160724,9187.103228,1,100,8,8,2.36,3,3,1,0,1,2,60,1,3,3,NA +70454,7,2,2,2,NA,2,2,2,2,25,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,8200.025088,8716.981559,1,93,14,8,2.01,5,4,1,0,0,2,22,2,1,6,NA +70455,7,2,1,69,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,4526.005699,5855.572964,2,90,6,6,0.84,6,6,1,3,1,2,43,1,2,5,NA +70456,7,2,1,0,4,1,1,2,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7594.427215,7594.567194,1,98,15,15,5,3,3,1,0,0,1,38,1,4,1,5 +70457,7,2,2,40,NA,5,6,2,NA,NA,2,NA,2,2,4,NA,5,1,2,1,2,1,1,2,1,1,2,2,3,16797.688743,17484.356971,3,91,15,15,5,3,3,0,1,0,2,40,2,5,1,5 +70458,7,2,2,35,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,2,1,2,2,1,2,2,1,2,2,1,26465.930618,26765.106529,2,100,10,10,2.33,6,6,0,2,2,2,35,1,2,5,NA +70459,7,2,2,4,NA,4,4,2,4,52,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9727.363166,10466.751274,2,97,6,6,1.02,6,6,1,2,0,1,37,1,3,1,3 +70460,7,2,2,5,NA,4,4,2,5,60,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9156.613403,9392.96113,2,99,7,5,1.59,3,2,1,0,0,2,23,1,4,5,NA +70461,7,1,2,5,NA,1,1,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13196.707564,0,2,96,3,3,0.24,7,7,2,3,1,2,40,1,3,3,NA +70462,7,2,1,8,NA,2,2,2,8,107,NA,NA,1,1,NA,3,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,13232.943476,13442.347662,2,94,1,1,0.01,7,7,1,3,0,1,41,2,1,1,1 +70463,7,2,2,7,NA,3,3,2,8,96,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,35359.674949,35088.43355,1,99,10,10,2.48,5,5,2,1,0,1,33,1,5,1,5 +70464,7,2,2,60,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,11523.037911,11803.949722,2,97,4,4,1.65,1,1,0,0,1,2,60,1,4,5,NA +70465,7,2,1,4,NA,5,6,2,5,61,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9239.758777,10363.400393,2,91,14,14,3.47,4,4,1,1,0,2,40,2,5,1,NA +70466,7,2,2,25,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,6,1,1,2,2,1,2,2,NA,NA,NA,NA,43813.24867,46530.283453,1,98,1,1,0.16,3,3,1,0,0,1,28,1,2,6,NA +70467,7,2,1,12,NA,2,2,2,12,146,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,21399.234084,21768.65302,1,91,15,15,5,4,4,0,2,0,1,49,1,5,1,5 +70468,7,2,2,0,8,5,7,2,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5820.770257,5884.32621,1,95,2,2,0.47,3,3,2,0,0,2,24,1,4,5,NA +70469,7,2,2,0,4,2,2,1,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4807.611315,4659.866106,1,103,4,4,0.54,7,7,2,2,0,2,35,2,1,6,NA +70470,7,2,2,43,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,NA,NA,NA,NA,15552.65085,16188.423507,2,92,15,15,5,3,3,0,1,0,1,45,2,4,1,4 +70471,7,2,2,16,NA,5,7,2,16,198,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11711.384457,12440.215685,2,95,6,6,1.31,3,3,0,1,0,1,39,1,3,1,4 +70472,7,2,1,12,NA,3,3,2,13,157,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,20152.417898,19887.568869,2,94,7,7,1.18,7,7,1,4,0,2,31,1,4,6,NA +70473,7,2,2,50,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,126117.5094,130777.186989,2,98,10,10,3.78,3,3,0,0,0,1,53,1,3,1,4 +70474,7,2,1,44,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,18116.816149,22904.074887,2,90,8,8,3.4,2,2,0,0,0,1,44,1,3,6,NA +70475,7,2,1,16,NA,5,6,2,16,200,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,NA,NA,NA,NA,NA,NA,NA,6269.080236,6655.935643,1,93,NA,NA,NA,3,3,0,1,0,1,53,NA,NA,1,NA +70476,7,2,1,30,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,16905.961576,20936.167849,2,94,7,7,1.62,5,5,0,3,0,1,30,1,2,1,9 +70477,7,2,1,9,NA,2,2,2,9,117,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15353.368573,15360.170072,1,97,7,7,1.74,4,4,0,3,0,2,32,1,4,5,NA +70478,7,2,2,34,NA,5,6,2,NA,NA,2,NA,2,2,2,NA,5,1,3,1,2,2,1,2,2,NA,NA,NA,NA,17430.913214,17550.603029,1,90,15,15,5,2,2,0,0,0,2,34,2,5,1,5 +70479,7,2,2,25,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,17397.027021,18573.153951,3,91,2,2,0.73,1,1,0,0,0,2,25,2,4,5,NA +70480,7,2,2,60,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,136832.42119,141624.96623,2,91,15,15,5,2,2,0,0,1,2,60,1,5,1,5 +70481,7,2,1,24,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,32946.178621,33458.203523,2,96,3,3,0.53,5,5,3,0,0,2,26,1,4,1,4 +70482,7,2,1,17,NA,5,7,2,17,207,2,NA,1,1,NA,12,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11712.675291,11995.185902,3,91,15,15,4.47,4,4,0,1,2,2,79,1,4,3,NA +70483,7,2,1,20,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,15740.336751,16168.874324,2,91,10,10,2.59,5,5,0,1,0,1,48,NA,NA,6,NA +70484,7,2,2,19,NA,1,1,2,19,236,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,19557.287652,19933.266032,2,94,5,5,1.08,3,3,0,1,0,2,37,2,2,4,NA +70485,7,2,1,34,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,14790.183811,15030.369455,3,90,14,14,4.71,3,3,0,0,2,1,64,NA,NA,1,NA +70486,7,2,1,10,NA,2,2,2,10,130,NA,NA,1,1,NA,4,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,13285.093011,13365.60735,2,94,2,2,0.41,2,2,0,1,1,2,66,2,3,5,NA +70487,7,2,2,53,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,12935.870815,12581.846775,2,99,5,5,0.65,6,6,2,1,0,2,53,1,4,3,NA +70488,7,2,2,6,NA,4,4,2,6,83,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,1,2,NA,NA,NA,NA,7814.742747,7984.793423,2,95,2,2,0.26,4,4,0,2,0,2,44,NA,NA,5,NA +70489,7,2,1,40,NA,2,2,1,NA,NA,2,NA,2,2,3,NA,5,1,NA,2,2,2,1,2,2,2,2,1,2,36225.654087,36329.951191,2,93,7,7,1.83,3,3,1,0,0,1,40,2,5,1,4 +70490,7,1,1,43,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,140932.152825,0,1,97,15,15,5,5,5,2,0,1,1,43,1,5,1,5 +70491,7,2,2,5,NA,4,4,2,5,66,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8833.042831,8971.325329,1,99,4,4,0.53,7,7,3,1,0,2,26,1,1,5,NA +70492,7,2,2,0,0,4,4,2,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,3516.231705,3777.543312,2,99,2,2,0.19,7,7,3,1,0,2,43,1,2,4,NA +70493,7,2,1,52,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,19541.667675,20187.705923,2,95,2,2,0.67,1,1,0,0,0,1,52,1,2,5,NA +70494,7,2,1,25,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,39915.513053,44831.646235,2,98,7,7,1.97,4,4,0,1,0,1,40,1,3,1,3 +70495,7,2,1,68,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,26026.192556,26360.023593,1,94,3,3,0.86,2,2,0,0,2,1,68,1,4,1,2 +70496,7,1,2,30,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,5,1,3,1,2,2,1,2,2,NA,NA,NA,NA,39483.840194,0,2,102,14,14,4.86,3,3,1,0,0,1,30,1,5,1,5 +70497,7,2,2,3,NA,4,4,1,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,NA,NA,NA,NA,NA,NA,NA,10437.988787,11664.396755,2,100,NA,NA,NA,4,4,1,0,0,2,38,NA,NA,77,NA +70498,7,2,2,63,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,98514.948291,98181.677236,1,99,10,10,4.89,2,2,0,0,2,2,63,1,5,5,NA +70499,7,2,2,47,NA,1,1,2,NA,NA,2,NA,2,2,6,NA,1,1,NA,2,2,2,2,2,2,1,2,2,2,23968.560941,24093.554947,2,90,6,6,1.15,5,5,0,2,0,2,47,2,1,1,5 +70500,7,2,1,15,NA,1,1,1,15,183,NA,NA,1,1,NA,9,NA,NA,NA,1,1,1,1,2,1,1,2,2,1,24902.864049,25283.513039,1,94,8,8,1.85,5,5,0,2,0,1,44,2,1,6,NA +70501,7,2,2,49,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,105873.555835,106383.882408,1,98,15,15,5,5,5,0,1,0,1,53,1,5,1,5 +70502,7,2,1,71,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,NA,48254.793439,51076.634961,2,100,14,10,5,2,1,0,0,2,1,71,1,2,6,NA +70503,7,2,2,18,NA,4,4,1,18,224,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,18163.985724,18749.311901,2,101,99,1,0.09,4,1,0,0,0,2,18,1,4,NA,NA +70504,7,2,1,59,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,19671.580166,20292.088214,2,99,7,7,2.31,2,2,0,0,1,1,62,1,3,5,NA +70505,7,2,2,40,NA,2,2,2,NA,NA,2,NA,2,2,2,NA,3,1,2,2,2,2,2,2,2,1,2,2,2,23968.560941,24556.443674,2,90,99,99,NA,5,5,1,1,0,2,40,2,3,1,1 +70506,7,2,2,9,NA,4,4,1,9,116,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9153.600624,9398.485171,1,100,8,8,1.61,6,6,1,3,0,1,29,1,5,6,NA +70507,7,2,2,80,NA,2,2,2,NA,NA,2,NA,2,1,9,NA,3,5,NA,1,2,2,1,2,2,1,2,2,NA,19066.820866,21138.377975,2,99,6,6,2.69,1,1,0,0,1,2,80,2,3,5,NA +70508,7,1,1,0,3,4,4,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6246.568228,0,2,95,9,9,1.81,6,6,1,1,0,2,56,1,4,3,NA +70509,7,2,1,8,NA,2,2,1,8,98,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13395.612951,13472.514863,2,102,15,12,NA,5,4,0,3,0,1,42,2,4,6,NA +70510,7,2,1,6,NA,5,6,2,6,74,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6905.911299,7686.337387,2,90,4,4,0.81,3,3,0,1,0,2,41,2,2,6,NA +70511,7,2,1,36,NA,5,6,1,NA,NA,2,NA,2,2,3,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,17643.563124,18510.507534,3,91,15,15,5,4,4,2,0,0,1,36,2,5,1,5 +70512,7,2,2,25,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,5,2,1,2,2,1,2,2,1,2,2,3,16929.836231,20416.10433,2,101,5,3,0.92,2,1,0,0,0,2,20,NA,NA,5,NA +70513,7,1,1,80,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,15682.233511,0,1,101,6,6,1.78,2,2,0,0,2,1,80,1,2,1,1 +70514,7,2,2,22,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,52160.006964,54246.901852,1,100,4,1,0,3,1,0,0,0,1,22,1,4,6,NA +70515,7,1,1,5,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7843.21745,0,1,96,12,12,NA,5,5,2,0,1,2,63,2,5,3,NA +70516,7,2,1,11,NA,4,4,2,11,135,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12176.538896,12609.8265,2,97,3,3,0.46,5,5,0,3,0,1,40,1,2,1,3 +70517,7,2,1,47,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,19440.793325,20264.695737,2,95,14,14,3.47,4,4,0,0,0,2,45,1,4,1,4 +70518,7,2,2,2,NA,4,4,2,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,NA,NA,NA,NA,NA,NA,NA,7032.269464,7566.800387,2,99,3,3,0.44,5,5,1,1,0,2,53,1,4,1,3 +70519,7,2,1,5,NA,5,6,1,5,70,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8981.553859,10073.795326,3,91,15,15,5,4,4,2,0,0,1,36,2,5,1,5 +70520,7,2,1,67,NA,1,1,1,NA,NA,1,1,2,1,8,NA,3,1,NA,1,2,2,1,2,2,2,2,2,2,11992.012141,12562.386395,2,102,5,5,1.36,2,2,0,0,2,2,66,2,2,1,3 +70521,7,2,1,53,NA,5,6,2,NA,NA,2,NA,2,1,8,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,19084.761772,19687.829911,1,91,15,15,5,4,4,0,2,0,2,52,1,5,1,5 +70522,7,2,2,21,NA,1,1,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,41953.42893,43056.968872,2,99,4,1,0.08,4,1,0,0,0,2,21,NA,NA,5,NA +70523,7,2,1,31,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,86986.68246,93900.677523,2,94,14,14,3.36,4,4,2,0,0,1,31,1,3,1,5 +70524,7,2,1,0,6,3,3,2,NA,7,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,17113.022485,16817.175522,1,91,15,15,5,3,3,1,0,0,1,41,1,5,1,5 +70525,7,2,1,63,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,7410.50521,7700.344649,2,96,2,2,0.71,1,1,0,0,1,1,63,1,3,3,NA +70526,7,2,2,10,NA,5,7,1,10,131,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8063.227462,8462.212273,3,91,14,14,3.8,4,4,0,2,0,1,47,1,5,1,5 +70527,7,2,1,63,NA,1,1,1,NA,NA,2,NA,2,1,6,NA,2,1,NA,2,2,1,2,2,1,1,2,2,2,9235.951997,9462.879133,2,103,7,7,1.89,3,3,0,0,1,1,63,2,2,1,9 +70528,7,2,1,15,NA,4,4,1,16,192,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,19163.050164,19302.61536,2,102,8,8,3.1,2,2,0,1,0,1,40,1,4,3,NA +70529,7,2,1,49,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,36244.629058,37702.525304,1,98,3,3,0.73,2,2,0,0,0,1,49,1,2,1,2 +70530,7,2,2,1,17,4,4,1,NA,18,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6765.566493,7560.484444,2,103,6,6,1.3,4,4,1,1,0,2,26,1,4,1,3 +70531,7,2,1,49,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,30152.053647,30985.296608,2,101,10,10,3.89,3,3,0,1,0,2,49,1,4,1,3 +70532,7,2,2,9,NA,1,1,1,9,113,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,20495.125801,21365.773499,3,92,8,8,1.55,6,6,1,3,0,2,38,1,5,1,4 +70533,7,2,2,51,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,196995.351093,196284.082305,1,91,7,7,3.31,1,1,0,0,0,2,51,1,5,3,NA +70534,7,2,2,48,NA,1,1,2,NA,NA,2,NA,2,2,4,NA,2,6,NA,2,2,2,NA,NA,NA,2,2,2,2,46417.079566,59177.283457,1,97,NA,NA,NA,2,1,0,0,0,1,30,NA,NA,6,NA +70535,7,2,1,40,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,28813.038041,29206.765831,1,94,5,5,0.87,4,4,0,1,0,1,40,1,5,1,5 +70536,7,2,1,30,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,18838.303827,25198.281368,2,93,6,6,1.95,2,2,0,1,0,1,30,1,4,5,NA +70537,7,2,1,26,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,37326.925742,39362.952436,2,91,6,77,NA,4,1,0,0,0,1,25,NA,NA,5,NA +70538,7,2,2,11,NA,1,1,1,11,134,NA,NA,1,1,NA,4,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,19059.339877,19554.022514,1,95,4,4,0.68,5,5,0,1,0,2,38,2,3,4,NA +70539,7,1,1,22,NA,5,6,NA,NA,NA,2,NA,2,1,6,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,13205.475858,0,1,102,1,1,0,2,1,0,0,0,1,18,NA,NA,NA,NA +70540,7,2,1,18,NA,3,3,1,18,227,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,105662.708061,105798.100528,1,94,12,12,NA,2,2,0,0,0,1,18,1,3,NA,NA +70541,7,2,2,13,NA,2,2,1,13,156,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,19836.724169,20587.964512,1,98,4,4,0.75,4,4,0,1,0,2,48,1,2,1,3 +70542,7,2,2,14,NA,4,4,2,14,177,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11956.705842,11923.015236,1,96,15,15,5,5,5,0,3,0,2,47,1,5,1,5 +70543,7,2,2,78,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,1,2,NA,11684.182359,12558.119387,2,98,6,6,1.35,3,3,0,0,2,1,79,NA,NA,1,2 +70544,7,2,1,77,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,7608.031426,7606.53553,1,99,6,6,1.34,4,4,0,1,1,1,77,1,3,1,5 +70545,7,2,1,31,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,32856.012738,39257.112915,1,103,7,7,0.51,7,7,3,4,0,1,54,2,1,1,1 +70546,7,2,2,0,8,4,4,2,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4418.651245,4866.131244,2,95,3,3,0.43,4,4,2,0,0,2,23,1,2,5,NA +70547,7,2,2,39,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,5,2,1,2,2,1,2,2,1,2,2,1,23204.787354,24686.898455,1,98,3,3,0.43,4,4,0,1,0,2,39,1,2,5,NA +70548,7,2,1,34,NA,1,1,1,NA,NA,2,NA,2,2,5,NA,3,4,NA,2,2,2,1,2,2,2,2,2,2,54095.173154,53686.899782,1,92,7,7,1.48,5,5,0,1,0,1,42,1,5,1,4 +70549,7,2,2,4,NA,1,1,2,4,53,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,12468.876716,13254.955592,2,97,4,4,0.6,6,6,2,2,0,1,35,2,2,6,NA +70550,7,2,1,76,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,14073.595908,14398.283636,1,92,14,14,5,3,3,0,0,2,1,76,1,4,1,4 +70551,7,2,1,37,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,13209.159597,13903.918018,2,95,3,3,0.52,3,3,1,0,0,1,37,1,4,1,4 +70552,7,2,1,3,NA,4,4,2,3,41,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9969.040341,10992.497123,2,97,4,4,0.84,3,3,1,0,1,2,68,1,4,2,NA +70553,7,1,1,2,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6347.215153,0,2,95,1,1,0.09,7,7,2,4,1,2,60,1,3,5,NA +70554,7,2,2,37,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,71034.153987,74518.988514,1,98,15,15,5,4,4,1,1,0,1,40,1,4,1,5 +70555,7,2,2,22,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,NA,NA,NA,NA,16239.242782,17706.77205,2,101,12,12,NA,4,4,0,0,0,1,57,NA,NA,1,NA +70556,7,2,1,2,NA,4,4,2,2,32,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5125.369941,5513.229844,1,96,77,77,NA,7,7,1,3,0,1,56,1,3,1,4 +70557,7,2,1,1,22,4,4,2,NA,23,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5547.430651,5776.651218,1,96,8,8,1.61,6,6,3,0,0,1,33,2,5,1,4 +70558,7,2,1,14,NA,4,4,2,14,172,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11125.932433,11147.929312,1,96,6,6,1.21,4,4,0,2,0,2,41,1,4,4,NA +70559,7,2,2,1,22,4,4,1,NA,23,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8221.160724,8586.221973,1,100,1,1,0,4,4,1,2,0,2,35,1,2,5,NA +70560,7,1,1,3,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7843.21745,0,1,96,12,12,NA,5,5,2,0,1,2,63,2,5,3,NA +70561,7,2,1,42,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,18533.049642,19320.837782,1,99,14,14,4.21,4,4,0,2,0,2,44,1,5,1,5 +70562,7,2,1,52,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,1,2,2,1,20958.247774,21169.083688,2,103,3,1,0.36,2,1,0,0,1,1,52,1,2,6,NA +70563,7,2,1,0,6,5,7,2,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6395.296043,7073.813977,2,95,4,4,0.79,3,3,1,0,0,1,50,1,4,6,NA +70564,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,8796.577101,9772.20689,2,95,3,3,1.03,1,1,0,0,1,1,80,1,3,2,NA +70565,7,2,2,76,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,NA,18693.365067,19341.691824,1,92,7,7,3.58,1,1,0,0,1,2,76,1,4,3,NA +70566,7,2,2,31,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,28033.589927,29297.386717,2,95,2,2,0.26,3,3,0,2,0,2,31,1,3,5,NA +70567,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,28280.669788,30348.532296,1,99,13,13,NA,2,2,0,0,2,1,80,1,2,1,3 +70568,7,2,1,67,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,8561.661692,8628.633702,2,99,99,99,NA,3,3,0,1,1,1,67,1,4,2,NA +70569,7,2,1,0,0,3,3,2,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,22570.662508,23265.895325,1,95,12,12,NA,6,6,2,0,0,2,42,1,2,1,5 +70570,7,2,1,62,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,8621.533452,8958.738589,2,99,7,7,2.31,2,2,0,0,1,1,62,1,3,5,NA +70571,7,2,1,0,11,4,4,2,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5707.173345,6119.621796,1,90,2,2,0.22,5,5,1,1,2,1,44,2,4,5,NA +70572,7,2,2,2,NA,2,2,2,2,25,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,10806.348349,11487.615985,2,91,99,99,NA,6,6,1,3,0,2,20,2,2,5,NA +70573,7,2,1,24,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,59473.789098,60284.462735,3,92,7,7,2.78,2,2,0,0,0,1,24,1,3,5,NA +70574,7,2,2,36,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,42468.064168,44382.588967,2,101,1,1,0.27,3,3,0,2,0,2,36,1,3,5,NA +70575,7,2,2,69,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,149804.257477,155051.140087,1,97,9,9,4.92,1,1,0,0,1,2,69,1,4,3,NA +70576,7,1,1,31,NA,5,6,NA,NA,NA,2,NA,2,2,2,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,19091.246741,0,1,91,9,9,2.97,3,3,1,0,0,1,31,2,5,1,5 +70577,7,2,2,80,NA,5,6,1,NA,NA,2,NA,2,1,8,NA,4,77,NA,1,2,1,1,2,1,1,2,1,NA,14314.616082,14811.078253,2,92,77,77,NA,1,1,0,0,1,2,80,2,4,77,NA +70578,7,2,1,16,NA,4,4,2,16,194,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12721.673656,12746.825446,2,97,7,7,2.65,2,2,0,1,1,2,61,1,4,3,NA +70579,7,2,2,4,NA,3,3,2,4,53,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,85219.527381,94056.007225,1,97,15,15,5,4,4,1,1,0,2,33,1,5,1,3 +70580,7,2,1,58,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,19581.573846,19613.097963,1,90,6,6,2.12,2,2,0,0,0,2,55,1,3,1,3 +70581,7,2,2,63,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,128226.88751,129797.060324,1,95,7,7,2.86,2,2,0,0,1,1,59,1,2,1,2 +70582,7,2,2,36,NA,1,1,1,NA,NA,2,NA,2,2,3,NA,4,6,2,2,2,2,2,2,2,2,2,2,2,35464.8385,35311.584148,2,96,5,5,0.89,4,4,1,1,0,2,36,2,4,6,NA +70583,7,2,1,14,NA,2,2,1,14,170,NA,NA,2,2,4,8,NA,NA,NA,2,1,2,2,2,2,2,2,2,2,22721.243258,22896.459408,2,102,8,8,1.09,7,7,1,3,0,2,33,2,1,6,NA +70584,7,2,2,36,NA,5,6,2,NA,NA,2,NA,2,2,4,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,20039.469886,21581.359058,1,97,15,15,5,4,4,2,0,0,1,40,2,5,1,5 +70585,7,2,1,5,NA,5,7,2,5,62,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6138.820061,6435.022409,1,99,14,14,3.94,4,4,1,1,0,1,43,1,4,1,5 +70586,7,2,2,51,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,24905.670199,25753.835465,2,101,10,10,2.91,4,4,0,1,0,2,51,1,2,5,NA +70587,7,2,2,50,NA,2,2,2,NA,NA,2,NA,2,2,2,NA,2,5,NA,2,2,2,2,2,2,NA,NA,NA,NA,17054.056149,17142.991601,2,90,6,6,0.66,7,7,2,2,0,2,24,2,4,6,NA +70588,7,2,1,0,8,4,4,1,NA,10,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5836.706781,6455.960401,2,93,12,12,NA,4,4,1,1,0,2,27,2,4,1,4 +70589,7,2,2,10,NA,4,4,2,10,122,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7889.400564,8100.464206,2,99,99,99,NA,3,3,0,1,1,1,67,1,4,2,NA +70590,7,2,2,51,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,27551.607232,31605.843936,1,90,12,9,5,2,1,0,0,0,2,51,1,3,3,NA +70591,7,1,2,65,NA,2,2,NA,NA,NA,2,NA,2,1,8,NA,1,3,NA,2,2,2,2,2,2,NA,NA,NA,NA,9716.805546,0,2,90,4,4,1.65,1,1,0,0,1,2,65,2,1,3,NA +70592,7,2,1,2,NA,4,4,1,2,35,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7561.636249,7792.598574,2,98,2,2,0.31,4,4,2,1,0,2,27,1,2,4,NA +70593,7,2,1,80,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,7608.031426,7725.81565,1,99,5,5,1.84,1,1,0,0,1,1,80,1,3,2,NA +70594,7,2,2,3,NA,4,4,1,3,42,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11729.417673,12620.984256,2,96,7,7,1.49,5,5,2,1,0,1,51,1,5,1,3 +70595,7,2,2,60,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,13057.178942,13648.591881,1,102,77,77,NA,6,6,0,2,1,2,37,1,4,1,4 +70596,7,2,2,33,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,85420.170155,89610.762168,1,91,15,15,5,3,3,1,0,0,1,36,1,4,1,5 +70597,7,2,2,49,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,35126.205635,35814.074718,1,95,6,6,0.96,5,5,1,0,1,2,69,1,1,2,NA +70598,7,2,2,28,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,6,2,1,2,2,1,2,2,1,2,2,1,12426.473257,13266.565637,2,92,15,14,5,2,1,0,0,0,1,27,1,5,6,NA +70599,7,2,1,54,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,36134.528328,36424.033955,2,101,6,6,2.04,2,2,0,0,0,2,51,1,5,1,4 +70600,7,2,2,80,NA,2,2,1,NA,NA,2,NA,2,2,7,NA,1,2,NA,2,2,2,1,2,2,2,2,2,NA,18142.687884,20262.262283,2,93,5,5,1.07,3,3,0,0,1,2,44,2,1,1,1 +70601,7,2,1,0,2,1,1,1,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,1,1,2,1,NA,NA,NA,NA,9064.168162,9064.335231,3,92,3,3,0.48,4,4,2,0,0,1,21,2,1,1,2 +70602,7,2,2,10,NA,3,3,2,10,128,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,60197.256541,63931.531988,2,91,15,15,5,4,4,0,2,0,1,53,1,5,1,4 +70603,7,2,1,55,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,127000.852889,130891.431194,2,92,15,15,5,2,1,0,0,0,1,57,1,5,6,NA +70604,7,2,1,39,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,13855.593765,14267.864487,2,92,15,15,5,3,3,1,0,0,1,39,2,5,1,5 +70605,7,2,1,56,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,20020.224623,20868.683381,1,96,15,15,5,4,4,0,1,0,1,56,1,4,1,5 +70606,7,2,1,80,NA,2,2,1,NA,NA,2,NA,2,1,9,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,16325.758272,16610.353254,2,93,8,8,2.17,4,4,0,0,3,1,80,2,2,1,2 +70607,7,2,2,45,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,19870.689174,19814.851418,1,96,15,15,5,4,4,0,2,0,1,46,1,5,1,5 +70608,7,1,2,68,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,54217.266426,0,1,101,4,4,0.99,2,2,0,0,2,1,77,1,3,1,3 +70609,7,2,2,1,23,1,1,1,NA,23,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8832.868731,9513.039058,1,102,13,13,NA,7,7,3,1,2,2,62,2,1,1,2 +70610,7,2,2,1,21,1,1,1,NA,21,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11414.885224,11453.86318,1,94,4,4,0.5,7,7,2,3,0,2,32,1,4,6,NA +70611,7,2,2,12,NA,3,3,2,12,150,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,101168.631125,108085.531312,1,99,6,6,1.52,4,4,0,2,0,2,43,1,3,5,NA +70612,7,2,2,5,NA,2,2,1,5,60,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13647.772496,14082.018801,2,93,7,7,1.99,3,3,1,1,0,2,38,1,3,4,NA +70613,7,2,2,54,NA,5,6,2,NA,NA,2,NA,2,2,4,NA,1,1,NA,1,2,1,1,2,2,1,2,1,3,12649.084278,13204.362319,3,90,8,3,1.25,3,1,0,0,1,2,68,2,2,4,NA +70614,7,2,2,20,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,1,1,2,2,1,2,2,1,2,2,1,22225.098465,28674.927734,2,97,2,2,0.34,2,2,1,0,0,2,20,1,3,5,NA +70615,7,2,1,8,NA,1,1,2,8,106,NA,NA,1,1,NA,2,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,10591.186197,11123.758959,1,90,6,6,1.11,5,5,1,2,0,1,30,2,1,6,NA +70616,7,2,1,17,NA,5,6,2,17,214,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,8869.170018,9434.816848,1,90,99,99,NA,3,3,0,1,1,1,60,1,5,1,5 +70617,7,2,2,45,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,21857.756498,23340.233721,2,97,5,5,1.08,3,3,0,1,0,2,45,1,4,6,NA +70618,7,2,1,13,NA,1,1,1,13,161,NA,NA,2,2,3,6,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,22768.423624,23297.239555,2,98,5,5,1.07,4,4,0,1,0,1,53,2,1,1,1 +70619,7,2,2,4,NA,1,1,1,4,56,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,16462.187772,17163.602129,3,92,12,12,NA,6,6,1,3,0,2,33,1,5,1,4 +70620,7,2,1,9,NA,1,1,2,9,113,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12477.812875,12364.493687,2,94,14,14,4.03,4,4,0,2,0,2,33,2,2,1,NA +70621,7,2,1,10,NA,5,7,1,10,122,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9375.648038,9390.261055,1,102,6,6,2.11,2,2,0,1,0,2,32,1,4,99,NA +70622,7,2,1,50,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,1,32274.162059,31800.588482,1,102,14,14,4.59,3,3,0,0,1,2,46,1,4,1,1 +70623,7,2,1,54,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,32720.69734,33691.382998,1,101,5,5,1.24,3,3,0,0,1,2,61,1,4,1,3 +70624,7,2,1,42,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,44926.921381,45636.571752,2,96,10,10,3.78,3,3,0,1,0,1,42,1,3,1,3 +70625,7,2,2,0,7,1,1,2,NA,8,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5289.715679,5503.176989,1,90,3,3,0.23,7,7,3,1,1,2,35,2,2,5,NA +70626,7,2,1,33,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,13076.210481,13450.719873,2,97,5,5,0.84,5,5,0,2,0,2,33,1,4,1,3 +70627,7,2,2,52,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,4,NA,1,2,2,1,2,2,1,2,2,1,15497.844354,15606.405341,1,99,14,14,4.05,3,3,0,1,0,2,52,1,4,4,NA +70628,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,47566.45715,54102.989916,1,90,7,7,3.22,1,1,0,0,1,2,80,1,4,2,NA +70629,7,2,2,28,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,16131.725974,16820.579069,1,99,14,7,3.4,2,1,0,0,0,2,28,2,5,1,NA +70630,7,2,1,11,NA,5,7,2,11,142,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,28060.491868,29807.930767,1,91,4,4,0.76,4,4,0,2,0,2,44,1,4,6,NA +70631,7,1,1,80,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,46965.818538,0,1,101,10,10,4.3,2,2,0,0,2,1,80,1,2,1,4 +70632,7,2,2,0,0,3,3,2,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,22123.758463,21522.828051,1,95,7,7,1.57,4,4,1,1,0,1,37,1,3,1,5 +70633,7,2,1,56,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,123771.419917,127885.04228,2,98,15,15,5,3,3,0,1,0,1,56,1,5,1,5 +70634,7,2,2,9,NA,1,1,1,9,119,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15962.145468,16664.698857,2,98,7,7,1.33,6,6,0,3,0,1,31,1,3,6,NA +70635,7,2,2,68,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,129999.035519,131590.908764,1,98,12,12,NA,2,2,0,0,2,1,70,1,2,1,3 +70636,7,2,1,12,NA,3,3,2,12,147,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,93665.036597,95017.313859,1,91,10,10,2.77,5,5,0,3,0,1,43,1,5,1,5 +70637,7,2,1,8,NA,4,4,2,8,105,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8483.005475,8584.70346,1,96,7,7,1.52,4,4,0,2,0,2,30,2,4,1,5 +70638,7,2,1,53,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,32720.69734,34178.98356,1,95,5,5,1.08,3,3,0,1,0,1,53,1,4,1,4 +70639,7,2,2,34,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,1,6,2,2,2,2,1,2,2,1,2,2,2,40536.844796,42064.124353,3,91,7,7,1.42,6,6,1,3,0,1,37,2,1,1,1 +70640,7,2,1,6,NA,5,7,2,7,84,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10810.913614,11522.32071,1,97,15,15,4.77,4,4,1,1,0,1,41,2,4,1,5 +70641,7,2,1,63,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,1,5,NA,1,2,2,1,2,2,1,2,2,1,6910.118936,7233.371983,2,95,2,2,0.75,1,1,0,0,1,1,63,1,1,5,NA +70642,7,2,1,12,NA,3,3,2,12,146,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,30943.024697,30709.935341,1,95,6,6,0.81,6,6,2,2,0,1,30,1,3,1,4 +70643,7,2,1,7,NA,3,3,1,7,91,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,39769.597728,42234.385729,2,92,15,15,5,5,5,0,3,0,2,46,1,5,1,5 +70644,7,2,1,41,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,126789.52929,130826.463813,1,101,9,9,2.6,4,4,0,2,0,2,38,1,4,1,4 +70645,7,2,1,6,NA,4,4,1,6,73,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11543.27965,11681.665542,1,98,1,1,0.03,3,3,0,2,0,2,38,1,4,5,NA +70646,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,54095.581484,61529.339683,2,94,14,14,5,1,1,0,0,1,2,80,1,4,2,NA +70647,7,2,2,38,NA,5,7,1,NA,NA,1,2,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,58826.425292,59007.297053,1,102,8,8,1.91,5,5,1,2,0,2,38,1,5,1,4 +70648,7,2,1,9,NA,1,1,1,9,113,NA,NA,1,1,NA,2,NA,NA,NA,2,NA,2,1,2,2,1,2,2,1,13395.612951,13714.015605,2,102,4,4,0.61,5,5,0,3,0,1,34,2,3,1,3 +70649,7,2,1,63,NA,2,2,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,9745.303498,9901.410815,2,98,15,15,4.56,4,4,0,0,3,1,80,1,1,1,NA +70650,7,2,1,2,NA,3,3,2,2,33,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,43818.485,49437.664471,2,91,15,15,4.2,6,6,2,0,2,1,63,1,1,1,3 +70651,7,2,2,3,NA,5,7,1,3,40,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10292.958129,10862.428258,3,91,10,10,2.48,5,5,2,1,0,2,27,1,2,1,4 +70652,7,2,2,16,NA,3,3,2,16,199,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,NA,NA,NA,1,2,2,1,31716.869763,32155.152073,1,95,NA,NA,NA,2,2,0,1,0,2,51,NA,NA,3,NA +70653,7,2,1,43,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,137286.989143,140204.788291,3,91,14,14,5,1,1,0,0,0,1,43,1,5,5,NA +70654,7,2,2,28,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,6,2,1,2,2,1,2,2,1,2,2,1,52280.406546,52747.829022,1,95,6,4,1.47,2,1,0,0,0,2,28,1,2,6,NA +70655,7,2,2,17,NA,3,3,2,17,206,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,103298.858809,106172.653059,1,95,9,9,2.66,4,4,0,2,0,1,45,1,3,1,3 +70656,7,2,2,2,NA,1,1,1,2,29,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12260.86913,13033.834526,3,92,8,8,1.85,5,5,1,0,2,1,66,2,1,1,1 +70657,7,2,1,0,8,3,3,2,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,22595.741117,22205.109866,1,93,15,15,5,3,2,1,0,0,2,35,1,5,6,NA +70658,7,2,1,16,NA,1,1,1,16,200,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,27186.265479,27776.842846,1,92,14,9,3.77,3,2,0,1,0,2,39,2,4,6,NA +70659,7,2,2,0,5,1,1,2,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,6787.112205,7238.162123,2,94,99,99,NA,3,3,1,0,0,2,18,2,2,NA,NA +70660,7,2,2,19,NA,1,1,1,19,230,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12996.753859,13369.730018,2,103,10,10,1.63,7,7,1,4,0,1,31,NA,NA,1,4 +70661,7,2,2,65,NA,2,2,1,NA,NA,2,NA,2,1,2,NA,4,1,NA,2,2,2,1,2,2,2,2,2,2,15876.871857,16539.500436,2,102,15,15,5,3,3,0,0,2,1,36,2,5,5,NA +70662,7,2,1,11,NA,3,3,2,11,134,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,42986.51011,47590.55439,2,94,7,7,1.17,6,6,0,3,0,1,40,1,3,1,5 +70663,7,2,2,29,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,3,3,1,2,2,1,2,2,1,2,2,1,23740.353448,26106.078779,2,99,6,6,2.6,1,1,0,0,0,2,29,1,5,3,NA +70664,7,2,2,70,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,39561.827371,40611.330327,1,92,4,4,1.16,2,2,0,0,1,1,56,1,2,1,3 +70665,7,2,2,13,NA,4,4,2,13,164,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14241.099758,14200.972378,1,96,15,15,5,3,3,0,1,0,2,37,1,4,1,4 +70666,7,2,2,3,NA,1,1,1,3,38,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,16462.187772,17500.018071,3,92,3,3,0.52,5,5,2,1,0,2,29,2,1,1,3 +70667,7,2,1,5,NA,3,3,1,5,61,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,73403.03993,82816.073154,1,92,8,8,1.45,6,6,1,3,0,1,36,1,3,1,4 +70668,7,2,2,41,NA,2,2,1,NA,NA,2,NA,2,1,5,NA,1,1,2,2,2,2,2,2,2,NA,NA,NA,NA,37512.060155,37707.682357,1,92,6,6,0.93,5,5,0,2,0,1,47,2,1,1,1 +70669,7,2,2,3,NA,1,1,2,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13366.393396,14756.857003,2,94,8,8,2.33,4,4,2,0,0,1,24,1,2,6,NA +70670,7,2,2,56,NA,2,2,2,NA,NA,2,NA,2,1,6,NA,1,1,NA,2,2,2,2,2,2,2,2,2,2,20130.149569,20235.126587,1,90,10,10,2.44,5,5,1,0,0,2,56,2,1,1,1 +70671,7,2,2,5,NA,4,4,2,5,71,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10683.855206,11939.151167,1,96,15,15,5,4,4,1,1,0,1,50,1,3,1,4 +70672,7,2,2,1,19,2,2,2,NA,19,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,9534.013652,9566.569071,2,97,12,6,0.89,7,7,3,0,0,2,26,2,1,6,NA +70673,7,2,2,14,NA,5,7,2,14,173,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13124.737024,13189.842246,2,97,5,5,1.19,3,3,0,1,0,2,41,1,3,1,2 +70674,7,2,1,67,NA,3,3,2,NA,NA,2,NA,2,2,6,NA,5,2,NA,1,2,2,1,2,1,1,2,2,NA,21313.15842,21908.589414,2,90,2,2,0.87,1,1,0,0,1,1,67,2,5,2,NA +70675,7,2,1,65,NA,5,6,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,12579.986433,13271.133625,1,92,14,14,5,2,2,0,0,2,2,62,1,4,1,4 +70676,7,2,2,75,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,NA,44856.466004,46390.551109,2,94,10,10,4.69,2,2,0,0,1,2,59,1,3,3,NA +70677,7,2,1,29,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,11977.649578,12533.694613,2,92,15,14,5,3,1,0,0,0,1,29,1,5,5,NA +70678,7,2,1,21,NA,2,2,1,NA,NA,2,NA,2,1,5,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,37235.048974,39044.599947,2,93,6,6,1.48,4,4,0,1,0,1,53,2,2,1,3 +70679,7,2,1,4,NA,3,3,2,4,51,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,97310.423154,111231.170223,1,95,8,8,1.28,7,7,1,4,0,1,32,1,3,1,3 +70680,7,2,2,2,NA,4,4,1,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,NA,NA,NA,NA,NA,NA,NA,6543.852411,7133.732612,1,102,12,12,NA,7,7,3,2,0,2,52,1,4,5,NA +70681,7,2,1,61,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,125558.167126,127168.668278,3,91,15,15,5,2,2,0,0,2,2,62,1,5,1,5 +70682,7,2,2,22,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,24654.107413,23441.410215,1,100,10,10,2.59,5,5,0,1,0,2,40,1,5,1,NA +70683,7,2,2,0,1,1,1,1,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9767.083234,9561.595244,3,92,8,8,2.51,3,3,1,0,0,2,25,1,4,5,NA +70684,7,2,1,58,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,13189.987508,14124.702096,1,90,77,77,NA,4,4,0,2,0,2,51,1,5,1,5 +70685,7,2,2,5,NA,2,2,2,5,61,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13474.744062,14324.236113,1,93,5,5,0.84,5,5,1,2,0,2,52,2,1,3,NA +70686,7,2,2,48,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,29010.447112,28477.291441,1,100,15,15,5,2,2,0,0,1,2,48,1,5,5,NA +70687,7,2,1,59,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,1,169076.731628,169683.640829,1,98,14,14,5,1,1,0,0,0,1,59,1,5,2,NA +70688,7,2,2,13,NA,4,4,1,13,163,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,16598.888685,16325.283055,2,102,4,4,0.53,6,6,2,2,0,2,27,1,2,1,2 +70689,7,2,1,56,NA,5,6,2,NA,NA,2,NA,2,2,99,NA,5,5,NA,1,2,1,1,2,1,1,2,1,3,11690.444016,11682.423918,3,90,77,77,NA,4,4,0,0,2,1,69,2,5,2,NA +70690,7,2,2,13,NA,5,6,1,13,160,NA,NA,2,1,3,6,NA,NA,NA,1,1,2,1,2,1,1,2,2,NA,8878.081187,9740.503961,3,92,77,77,NA,7,7,2,4,1,1,62,NA,NA,1,NA +70691,7,2,2,14,NA,4,4,1,14,172,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15114.677795,15072.08892,2,102,6,6,1.22,5,5,0,2,0,2,42,1,4,1,4 +70692,7,2,1,3,NA,4,4,2,3,39,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9304.437652,10259.663981,2,97,4,4,0.81,4,4,1,0,0,2,51,1,2,4,NA +70693,7,2,1,5,NA,3,3,2,5,71,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,31190.854587,36547.404966,1,95,3,3,0.65,3,3,1,0,0,1,58,1,3,3,NA +70694,7,2,1,8,NA,5,6,2,8,106,NA,NA,2,2,2,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,7923.925927,8546.646915,1,91,10,10,3.22,4,4,1,1,0,1,38,2,5,1,5 +70695,7,2,2,39,NA,5,6,2,NA,NA,2,NA,2,2,4,NA,4,2,2,1,2,2,1,2,2,NA,NA,NA,NA,20039.469886,21176.851739,1,97,8,8,2.51,3,3,0,2,0,2,39,2,4,2,NA +70696,7,2,2,47,NA,2,2,1,NA,NA,2,NA,2,2,2,NA,3,1,NA,2,2,2,2,2,2,2,2,1,2,29105.053716,31982.273564,2,93,4,4,0.82,4,4,0,0,0,1,51,2,3,1,3 +70697,7,2,1,32,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,1,82917.179795,86800.065133,2,95,7,7,2.91,2,2,1,0,0,1,32,1,5,2,NA +70698,7,2,1,1,16,5,6,1,NA,17,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8674.760516,9729.693026,3,91,10,10,3.67,3,3,1,0,0,2,30,2,4,1,4 +70699,7,2,1,0,7,2,2,1,NA,8,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,4724.065742,4677.378988,2,93,77,77,NA,7,7,3,0,1,2,40,2,4,1,NA +70700,7,2,1,0,2,2,2,1,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,4854.394074,4994.155976,2,93,3,3,0.37,5,5,3,0,0,1,28,2,1,6,NA +70701,7,2,1,24,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,14782.636003,15547.771991,3,91,10,9,5,2,1,0,0,0,1,24,1,4,5,NA +70702,7,2,1,26,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,27681.749998,28652.049948,2,98,8,8,1.48,7,7,3,0,0,1,26,1,3,1,3 +70703,7,2,2,57,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,160743.928829,166234.629208,1,95,8,8,3.47,2,2,0,0,0,1,58,1,2,1,4 +70704,7,2,2,35,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,NA,NA,NA,NA,36453.846815,42702.950408,1,102,14,14,2.83,6,6,1,2,0,1,36,1,2,1,3 +70705,7,2,2,0,3,5,7,2,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5820.770257,5884.32621,1,95,1,1,0.13,3,3,1,0,0,1,31,1,4,1,4 +70706,7,2,2,48,NA,1,1,1,NA,NA,2,NA,2,7,77,NA,1,1,NA,2,2,2,1,2,2,1,2,2,2,34639.996543,34820.641178,1,102,77,77,NA,3,3,0,0,1,1,61,2,4,1,1 +70707,7,2,2,10,NA,5,7,2,11,132,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8746.306586,9472.024073,1,91,3,3,0.66,4,4,1,2,0,2,33,1,3,5,NA +70708,7,2,1,57,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,173139.914798,178954.334223,1,101,7,7,2.64,2,2,0,0,0,1,57,1,2,1,2 +70709,7,2,1,9,NA,4,4,2,9,111,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8988.052978,9133.633722,2,95,8,8,1.85,5,5,1,2,0,1,55,1,2,1,3 +70710,7,2,2,57,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,29087.427528,30575.794656,1,101,3,3,1.07,3,1,0,1,0,2,57,1,4,3,NA +70711,7,2,2,12,NA,5,7,2,12,151,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,47404.963472,48778.930863,1,97,8,8,2.51,3,3,0,1,0,1,35,1,3,1,4 +70712,7,2,1,2,NA,5,6,1,2,30,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10123.286306,10611.741928,1,100,10,10,3.04,4,4,2,0,0,1,30,2,5,1,5 +70713,7,2,2,30,NA,5,6,2,NA,NA,2,NA,2,2,4,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,15109.988743,16272.590756,1,90,6,6,0.92,6,6,2,0,2,2,30,2,5,1,5 +70714,7,2,2,1,21,5,6,1,NA,22,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4576.510691,4795.397917,1,102,15,15,3.82,5,5,1,1,0,1,29,1,4,1,4 +70715,7,2,2,79,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,53541.401974,54113.194007,1,99,14,14,5,2,2,0,0,2,2,79,1,3,1,5 +70716,7,2,2,43,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,99538.625493,103163.851943,1,103,15,15,5,3,3,0,1,0,1,46,1,5,1,5 +70717,7,2,2,70,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,24480.331443,26311.37682,2,101,6,6,2.04,2,2,0,0,2,1,77,1,1,1,2 +70718,7,2,1,75,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,NA,13555.672819,14397.395601,1,94,4,4,1.43,1,1,0,0,1,1,75,1,4,3,NA +70719,7,1,1,12,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,58479.782556,0,1,99,77,77,NA,4,4,0,2,0,2,45,1,3,1,NA +70720,7,2,2,7,NA,5,6,2,7,86,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8371.948513,8981.698617,1,90,15,15,5,3,3,0,1,0,2,34,2,5,1,5 +70721,7,2,2,79,NA,2,2,1,NA,NA,2,NA,2,1,6,NA,2,1,NA,2,2,2,2,2,2,2,2,1,NA,18241.877822,19614.829564,2,93,9,9,3.64,2,2,0,0,2,2,79,2,2,1,4 +70722,7,2,2,5,NA,4,4,1,5,70,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10936.097083,11421.715282,2,95,1,1,0.18,4,4,2,1,0,2,38,1,2,5,NA +70723,7,2,1,32,NA,3,3,1,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,86204.990126,88673.945369,2,103,14,14,5,2,2,0,0,0,1,32,2,5,1,NA +70724,7,2,1,5,NA,2,2,2,5,70,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,15527.966893,15272.133376,1,90,9,9,2.6,4,4,1,1,0,1,41,1,5,1,4 +70725,7,2,2,60,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,11173.849134,11672.749546,2,93,10,10,3.93,3,3,0,0,2,1,54,1,5,1,5 +70726,7,2,1,5,NA,4,4,2,5,62,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9310.029529,9330.284312,1,97,4,4,0.46,7,7,3,3,0,2,31,1,3,1,NA +70727,7,2,2,44,NA,4,4,2,NA,NA,2,NA,2,1,5,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,18488.34481,18123.036332,2,99,15,15,4.34,4,4,0,0,0,1,59,2,4,1,5 +70728,7,2,2,42,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,2,1,2,2,1,2,2,NA,NA,NA,NA,24056.374863,24201.045855,2,99,1,1,0,1,1,0,0,0,2,42,1,3,5,NA +70729,7,2,1,80,NA,5,7,2,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,26344.362464,28384.957988,2,95,7,7,2.55,2,2,0,0,2,1,80,1,4,1,2 +70730,7,2,1,55,NA,1,1,1,NA,NA,2,NA,2,1,7,NA,1,1,NA,2,2,1,1,2,1,1,2,2,2,33162.406014,36437.864606,2,98,7,7,2.25,3,3,0,1,0,2,51,2,1,1,1 +70731,7,2,1,6,NA,5,6,1,6,73,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8580.826574,9087.233306,1,92,14,14,2.42,6,6,1,3,0,1,30,1,4,6,NA +70732,7,2,2,52,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,157061.455656,156201.940202,1,90,7,7,1.89,3,3,0,0,1,2,75,1,4,3,NA +70733,7,2,2,80,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,10634.832821,11430.282078,2,95,3,3,0.92,1,1,0,0,1,2,80,1,1,2,NA +70734,7,2,1,7,NA,3,3,1,7,92,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,50961.223155,56419.394274,1,94,15,15,5,6,6,0,4,0,1,38,1,5,1,4 +70735,7,2,2,80,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,10072.885959,10826.303506,2,100,3,3,1.1,1,1,0,0,1,2,80,1,2,2,NA +70736,7,2,2,32,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,5,4,2,1,2,2,1,2,2,1,2,2,1,31816.953817,32705.969127,1,91,15,15,5,3,3,0,0,1,1,63,2,5,1,5 +70737,7,2,1,28,NA,2,2,1,NA,NA,2,NA,2,1,5,NA,4,5,NA,2,2,2,2,2,2,2,2,1,2,38474.772527,40200.135096,2,93,NA,1,0.22,4,1,0,0,0,1,28,NA,NA,4,NA +70738,7,2,2,39,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,1,1,2,1,2,1,1,2,2,1,2,1,NA,18229.985416,18267.209527,1,93,7,7,1.64,5,5,0,2,0,1,47,2,5,1,1 +70739,7,2,1,63,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,22641.791224,22854.140555,1,101,5,5,0.71,6,6,1,1,1,1,63,1,2,1,5 +70740,7,2,2,7,NA,4,4,2,7,91,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9795.701448,10340.670956,1,96,13,13,NA,5,5,1,1,0,1,42,1,3,5,NA +70741,7,2,2,21,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,NA,NA,NA,NA,18723.98095,18120.118724,2,95,7,7,1.74,4,4,0,2,0,2,47,1,5,4,NA +70742,7,2,1,10,NA,2,2,2,10,124,NA,NA,1,1,NA,4,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,11316.846999,12445.832216,3,91,13,4,0.81,4,3,0,2,0,1,57,NA,NA,1,NA +70743,7,2,1,46,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,105141.812429,105376.658808,1,98,5,5,1.39,2,2,0,1,0,1,46,1,4,3,NA +70744,7,1,2,65,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,10135.841003,0,2,99,2,2,0.67,1,1,0,0,1,2,65,1,2,5,NA +70745,7,2,1,51,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,17206.320427,18234.571296,2,100,4,4,0.91,3,3,0,0,0,2,49,1,2,1,2 +70746,7,2,1,51,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,NA,NA,NA,NA,NA,NA,NA,16589.308426,20972.932517,2,90,8,NA,NA,2,1,0,0,0,1,51,1,2,5,NA +70747,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,14359.447628,16592.595881,1,97,3,3,1.16,1,1,0,0,1,1,80,1,3,2,NA +70748,7,2,2,32,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,31335.13799,31552.004994,1,95,7,7,1.66,5,5,0,3,0,1,34,1,2,1,4 +70749,7,2,1,2,NA,2,2,1,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8571.222647,8842.539637,2,93,14,14,3.52,5,5,1,2,0,1,44,1,5,1,5 +70750,7,2,2,26,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,16844.740449,17564.040518,3,91,1,1,0.11,1,1,0,0,0,2,26,1,5,5,NA +70751,7,2,1,27,NA,1,1,1,NA,NA,2,NA,2,7,3,NA,3,4,NA,2,2,2,2,2,2,1,2,2,2,35210.641637,36376.282426,1,100,8,3,0.9,6,1,1,0,0,1,33,2,3,6,NA +70752,7,1,1,40,NA,3,3,NA,NA,NA,1,2,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,18872.772727,0,1,91,6,6,1.13,6,6,1,3,0,1,40,1,4,6,NA +70753,7,2,1,30,NA,1,1,2,NA,NA,2,NA,2,2,4,NA,1,6,NA,2,2,2,1,2,2,2,2,2,2,37657.076964,37372.8671,1,90,6,6,1.11,5,5,1,2,0,1,30,2,1,6,NA +70754,7,2,2,15,NA,3,3,1,15,184,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,77001.138762,80653.195108,1,98,9,9,2.88,6,3,1,3,0,1,51,1,2,1,3 +70755,7,2,1,56,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,141736.66089,144209.560558,1,92,10,10,3.4,3,3,0,0,0,1,56,1,4,1,5 +70756,7,2,1,78,NA,3,3,2,NA,NA,2,NA,2,2,3,NA,1,1,NA,1,2,1,1,2,1,1,2,1,NA,12786.51051,14057.405205,1,93,2,2,0.41,2,2,0,0,2,2,68,2,1,1,1 +70757,7,2,1,36,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,74874.432638,77018.874888,2,99,15,15,5,2,2,0,0,0,2,35,2,5,1,5 +70758,7,2,1,21,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,41120.308343,45563.612914,1,93,5,5,1.36,2,2,0,0,0,2,41,2,1,4,NA +70759,7,2,1,41,NA,1,1,1,NA,NA,2,NA,2,1,6,NA,1,4,NA,2,2,2,1,2,2,2,2,2,2,41410.39303,40802.759347,1,101,12,7,3.58,3,1,0,0,0,1,41,2,1,4,NA +70760,7,2,1,7,NA,5,6,2,7,87,NA,NA,2,1,2,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6681.315407,7240.00549,3,91,15,15,4.33,7,6,1,3,0,2,40,1,5,1,5 +70761,7,2,1,46,NA,1,1,1,NA,NA,2,NA,2,2,77,NA,4,1,NA,2,2,2,1,2,2,2,2,1,2,33629.261806,33135.804229,2,103,12,8,4.48,2,1,0,0,0,1,46,2,4,1,NA +70762,7,2,2,34,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,23408.914544,24510.72255,2,90,7,7,1.61,4,4,1,1,0,2,34,1,5,1,5 +70763,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,54095.581484,61529.339683,2,91,6,6,1.88,2,2,0,0,1,2,80,1,5,2,NA +70764,7,1,2,2,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,34597.213785,0,1,98,7,7,1,7,7,2,2,0,2,34,1,4,3,NA +70765,7,2,2,67,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,1,44238.530111,44780.242841,1,95,6,6,2.04,2,2,0,0,2,2,67,1,1,2,NA +70766,7,2,2,45,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,16354.688935,16518.054061,2,90,9,9,3.02,3,3,0,0,2,2,70,1,4,1,2 +70767,7,2,2,18,NA,1,1,2,19,228,2,NA,2,2,4,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,19850.979841,20551.555585,1,97,3,3,0.5,5,5,0,2,0,1,56,2,2,6,NA +70768,7,2,2,9,NA,3,3,2,9,113,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,73410.202745,74807.098361,2,91,15,15,5,5,5,2,1,0,2,40,1,5,1,5 +70769,7,2,2,21,NA,1,1,1,NA,NA,2,NA,2,2,6,NA,2,5,2,1,2,2,1,2,2,1,2,2,1,40653.73216,40476.667284,1,102,5,5,0.86,5,5,2,0,0,2,21,2,2,5,NA +70770,7,2,1,7,NA,1,1,2,7,93,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,18107.947773,18211.90239,1,97,10,10,2.32,6,6,0,4,0,1,42,1,4,1,4 +70771,7,2,1,17,NA,5,6,2,17,213,2,NA,2,1,5,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,8434.080857,8971.979116,1,91,77,77,NA,4,4,0,2,0,1,50,2,5,1,5 +70772,7,2,1,71,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,50383.817476,53512.338469,1,94,15,15,5,2,2,0,0,1,2,56,1,3,1,4 +70773,7,2,2,33,NA,2,2,1,NA,NA,2,NA,2,1,5,NA,5,1,1,1,2,2,1,2,2,1,2,2,1,38161.026403,38068.87516,1,100,10,10,2.91,4,4,1,1,0,1,32,1,5,1,5 +70774,7,2,2,49,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,18811.641937,19081.796284,2,90,3,3,0.95,2,2,0,1,0,2,49,1,3,5,NA +70775,7,2,1,60,NA,2,2,2,NA,NA,2,NA,2,1,4,NA,5,1,NA,1,2,2,1,2,2,1,2,2,2,7807.558918,8078.476616,3,90,77,77,NA,2,2,0,0,1,1,60,2,5,1,5 +70776,7,2,1,60,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,2,1,NA,1,2,1,1,2,1,1,2,1,NA,13133.86792,13808.275718,2,102,15,15,3.82,5,5,0,1,2,1,60,2,2,1,1 +70777,7,2,2,0,10,5,7,2,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8582.213422,8500.433306,2,94,77,77,NA,4,4,2,0,0,2,23,1,2,6,NA +70778,7,2,2,3,NA,3,3,2,4,48,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,54402.653374,57814.771756,1,98,15,15,3.7,5,5,2,1,0,1,34,1,5,1,5 +70779,7,2,1,80,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,32785.873783,35446.092694,1,94,6,6,1.82,2,2,0,0,2,1,80,1,4,1,3 +70780,7,2,2,11,NA,3,3,1,11,133,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,49777.284509,49627.739683,1,98,15,15,5,5,5,0,3,0,2,44,1,5,1,5 +70781,7,2,1,19,NA,1,1,1,19,229,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,20638.769105,20614.097145,2,92,15,15,3.37,7,7,0,4,0,1,42,2,3,1,1 +70782,7,2,1,64,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,138075.879417,141933.339512,2,94,15,15,5,2,2,0,0,2,1,64,1,5,1,5 +70783,7,2,2,37,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,13027.332011,13925.626381,2,103,15,15,5,3,3,0,1,0,2,37,2,5,1,5 +70784,7,2,2,54,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,196995.351093,203724.329642,1,91,15,15,5,2,2,0,0,0,1,53,1,5,1,5 +70785,7,2,2,41,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,20434.221508,19874.985431,1,102,1,1,0,5,5,0,3,0,2,41,1,4,1,4 +70786,7,2,1,60,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,153565.050575,157855.235487,1,97,15,15,5,4,4,0,0,1,1,60,1,5,1,5 +70787,7,2,2,64,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,164066.603708,163511.57474,1,95,7,7,2.86,2,2,0,0,1,1,58,1,4,1,3 +70788,7,2,1,34,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,11793.151047,11949.568707,3,91,14,14,2.5,6,6,1,1,1,2,37,2,2,1,5 +70789,7,2,1,5,NA,3,3,2,5,68,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,27873.065855,31447.442273,1,91,6,6,1.07,6,6,3,1,0,2,27,1,4,6,NA +70790,7,2,1,49,NA,3,3,2,NA,NA,2,NA,2,2,8,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,116464.874823,120278.381994,2,91,15,15,5,4,4,0,2,0,2,48,1,5,1,5 +70791,7,2,2,45,NA,5,6,2,NA,NA,2,NA,2,1,8,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,20303.639991,21936.687597,1,97,15,15,5,3,3,0,1,0,2,45,2,5,1,5 +70792,7,2,1,30,NA,2,2,2,NA,NA,2,NA,2,2,3,NA,1,6,NA,2,2,2,2,2,2,NA,NA,NA,NA,27605.196104,27396.850962,2,99,12,3,0.52,5,3,0,1,0,1,30,2,2,4,NA +70793,7,2,1,66,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,100988.137931,101524.74706,1,99,9,9,4.35,2,2,0,0,1,1,66,1,2,1,3 +70794,7,2,2,66,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,9518.80186,10328.183799,2,100,3,3,0.68,2,2,0,0,2,1,66,1,2,1,2 +70795,7,2,1,12,NA,4,4,1,12,144,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11429.628358,11541.555232,2,96,7,7,1.04,7,7,0,4,0,2,37,1,3,3,NA +70796,7,2,2,10,NA,5,6,1,10,125,NA,NA,2,2,2,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8281.624869,8692.694009,2,102,9,9,2.68,4,4,1,1,0,2,38,2,5,1,2 +70797,7,2,2,33,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,16614.865368,17760.536638,3,91,15,15,5,4,4,2,0,0,2,33,2,5,1,5 +70798,7,2,2,53,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,15693.813435,15736.327271,2,100,5,5,0.95,4,4,0,0,1,2,53,1,3,5,NA +70799,7,2,2,4,NA,5,7,2,4,57,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7143.995395,7774.277146,3,91,15,15,4.47,4,4,2,0,0,1,33,1,5,1,5 +70800,7,2,1,21,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,NA,NA,NA,1,2,2,1,23484.626749,23642.328802,2,96,NA,NA,NA,3,3,0,0,0,2,50,NA,NA,1,NA +70801,7,2,2,28,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,103632.167909,110131.87866,2,99,14,14,5,2,2,0,0,0,2,28,1,5,1,5 +70802,7,2,2,5,NA,3,3,1,5,67,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,21760.206232,23124.999952,1,98,2,2,0.36,5,5,3,0,0,1,25,1,3,1,3 +70803,7,2,1,7,NA,3,3,1,7,95,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15279.821652,15716.743409,1,102,5,1,0.21,5,4,1,1,0,2,24,1,4,5,NA +70804,7,2,2,53,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,12037.168211,11707.739526,2,99,15,15,4.9,7,7,1,4,0,2,53,1,5,1,5 +70805,7,2,2,55,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,2,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,12649.084278,13109.186175,3,90,77,77,NA,4,4,0,0,0,1,59,2,2,1,2 +70806,7,2,2,42,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,2,1,2,2,1,2,2,1,2,2,1,126334.218747,127212.680922,1,95,9,9,3.24,3,3,0,0,0,2,42,1,4,3,NA +70807,7,2,2,22,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,46606.430863,46728.795934,2,102,14,14,3.25,5,5,2,0,0,1,27,1,5,1,5 +70808,7,2,1,77,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,7225.866295,7367.404674,1,96,15,15,5,4,4,0,0,2,1,77,1,5,1,3 +70809,7,2,1,0,1,5,7,1,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9289.230808,9431.807424,2,102,6,6,1.65,3,3,1,0,0,2,21,1,4,1,5 +70810,7,2,2,3,NA,5,6,2,3,37,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,4735.146545,5152.906676,3,90,5,5,0.93,4,4,1,0,0,1,48,2,4,1,NA +70811,7,2,2,30,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,4,1,2,1,2,2,1,2,2,NA,NA,NA,NA,14138.631841,14167.501749,3,92,8,8,0.91,7,7,3,3,1,1,61,NA,NA,1,4 +70812,7,2,1,25,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,25645.251384,25046.202404,1,92,14,14,4.96,2,2,0,0,0,1,25,1,4,5,NA +70813,7,2,2,7,NA,2,2,1,7,94,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15992.05837,16407.130123,2,93,7,7,1.99,3,3,1,1,0,2,38,1,3,4,NA +70814,7,2,2,7,NA,3,3,1,7,93,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,48532.852397,48387.04619,1,98,14,14,4.12,4,4,0,2,0,2,36,1,5,1,3 +70815,7,1,2,9,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6758.20346,0,2,103,1,1,0.04,2,2,0,1,0,2,28,1,4,5,NA +70816,7,2,2,30,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,NA,NA,NA,NA,26465.930618,26276.815338,2,100,5,5,0.88,5,5,2,1,0,2,30,1,4,6,NA +70817,7,2,2,21,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,32537.532358,33640.063825,2,90,8,8,2.01,4,4,0,0,1,2,67,2,4,2,NA +70818,7,2,1,0,1,2,2,1,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4997.17037,5277.406032,2,93,15,15,4.84,6,6,1,0,0,1,50,1,4,1,2 +70819,7,2,2,0,2,5,6,2,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9150.459338,9253.718962,1,97,15,15,4.34,4,4,2,0,0,1,35,2,5,1,5 +70820,7,2,2,13,NA,2,2,2,13,160,NA,NA,1,1,NA,6,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,20099.773776,21058.707597,1,90,15,15,5,3,3,0,1,0,1,55,2,3,1,5 +70821,7,2,1,63,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,112072.982256,113124.075015,2,98,14,14,5,2,2,0,0,1,1,63,1,4,1,4 +70822,7,2,2,0,3,4,4,2,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,3484.44779,3522.493854,2,99,1,1,0.03,3,3,1,0,0,2,19,1,3,NA,NA +70823,7,2,1,9,NA,4,4,2,9,112,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10103.729975,10224.857915,1,96,15,15,5,4,4,0,2,0,2,39,1,4,6,NA +70824,7,2,1,10,NA,1,1,1,10,123,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8828.580268,8822.70874,1,103,7,7,0.51,7,7,3,4,0,1,54,2,1,1,1 +70825,7,2,1,47,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,129971.22201,129637.352703,1,93,15,15,5,1,1,0,0,0,1,47,1,5,3,NA +70826,7,2,1,60,NA,1,1,1,NA,NA,2,NA,2,1,9,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,14488.953694,14771.336069,3,92,8,8,2.97,2,2,0,0,2,2,62,1,4,1,4 +70827,7,2,1,7,NA,3,3,2,8,96,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,23729.905536,29042.69522,1,101,3,3,0.61,4,4,1,2,0,1,38,1,2,4,NA +70828,7,2,1,26,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,94547.245282,96016.627954,2,94,77,77,NA,2,2,0,0,0,2,23,1,3,6,NA +70829,7,2,2,13,NA,4,4,1,13,159,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18163.985724,21329.621847,2,101,9,9,2.46,4,4,0,2,0,1,42,1,3,1,3 +70830,7,2,2,0,10,4,4,2,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4484.450821,4755.264461,1,91,6,6,0.99,5,5,3,0,0,2,33,2,3,1,4 +70831,7,2,2,30,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,4,1,2,1,2,1,1,2,1,1,2,2,1,19005.010125,19718.036027,1,92,12,12,NA,4,4,1,1,0,1,33,2,4,1,4 +70832,7,2,2,31,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,3,1,2,2,1,2,2,1,2,2,1,53830.599426,56471.452044,1,99,5,5,0.89,4,4,2,0,0,2,31,1,4,1,5 +70833,7,2,2,35,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,36053.766709,36629.803511,1,100,5,5,1.05,3,3,1,0,0,2,35,1,4,6,NA +70834,7,2,1,9,NA,3,3,2,9,115,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,53956.99815,55499.881764,1,93,15,15,5,4,4,0,2,0,2,42,1,5,1,NA +70835,7,2,1,62,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,20439.261207,20630.95379,2,95,4,2,0.81,2,1,0,0,1,1,62,1,5,3,NA +70836,7,2,1,6,NA,1,1,1,6,74,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,19735.224235,20204.314213,2,102,6,6,1.35,3,3,0,1,0,1,37,2,1,1,3 +70837,7,2,1,60,NA,1,1,1,NA,NA,2,NA,2,2,5,NA,2,1,NA,2,2,2,1,2,2,2,2,2,2,8489.547987,8893.33507,2,96,5,5,0.89,5,4,0,0,1,1,22,2,3,6,NA +70838,7,2,2,25,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,29040.300396,28462.118402,2,101,6,6,1.67,3,3,0,0,0,2,22,1,4,5,NA +70839,7,2,2,13,NA,3,3,2,13,167,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,132630.209478,133894.993306,1,97,8,8,2.72,3,3,0,2,0,2,43,1,1,3,NA +70840,7,2,2,10,NA,4,4,1,10,122,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12474.59761,12808.328162,1,100,3,3,0.43,4,4,0,2,0,1,35,1,4,1,3 +70841,7,2,1,11,NA,3,3,2,11,142,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,21147.476454,21752.181979,1,95,1,1,0.12,3,3,0,2,0,2,40,1,5,3,NA +70842,7,2,1,32,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,16945.481829,17170.237079,1,99,77,77,NA,1,1,0,0,0,1,32,2,5,5,NA +70843,7,2,2,0,11,3,3,2,NA,13,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8383.207272,8554.601009,1,91,12,1,0.07,6,1,1,1,0,2,29,1,4,6,NA +70844,7,2,1,19,NA,4,4,2,19,235,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,10817.360862,11313.215634,2,99,99,99,NA,5,5,0,2,0,2,20,1,3,6,NA +70845,7,2,2,21,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,1,1,2,2,1,2,2,1,2,2,1,20000.263815,19016.481945,1,102,12,12,NA,7,7,3,2,0,2,52,1,4,5,NA +70846,7,2,1,9,NA,2,2,2,9,112,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,11807.210833,12400.930816,1,90,7,7,2.1,3,3,0,2,0,2,37,1,3,5,NA +70847,7,2,2,19,NA,4,4,2,19,232,2,NA,1,1,NA,12,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11711.384457,11743.959438,2,95,3,3,0.43,4,4,2,0,0,2,23,1,2,5,NA +70848,7,2,1,80,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,6994.319065,7352.726651,2,99,3,3,0.9,1,1,0,0,1,1,80,1,3,2,NA +70849,7,2,2,49,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,37102.230755,38432.724809,2,101,5,2,0.73,2,1,0,0,1,2,49,1,3,6,NA +70850,7,2,2,28,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,17858.942687,20013.475913,1,97,14,14,4.5,3,3,1,0,0,1,30,1,5,1,5 +70851,7,2,1,36,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,73127.351507,77018.309866,1,103,9,9,3.64,2,2,0,0,0,1,36,1,5,1,5 +70852,7,2,1,14,NA,4,4,1,14,179,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10879.348751,11378.044973,2,100,8,8,1.1,7,7,3,3,0,2,58,1,3,5,NA +70853,7,2,2,19,NA,4,4,1,19,235,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12531.903464,12935.738352,2,100,5,5,1.07,4,4,0,1,0,2,36,1,3,5,NA +70854,7,1,2,53,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,4,4,NA,1,2,2,1,2,2,NA,NA,NA,NA,16033.091438,0,1,96,8,8,2.62,3,3,0,0,0,2,53,1,4,4,NA +70855,7,2,1,9,NA,1,1,1,9,115,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14820.807433,15173.085782,2,102,7,7,1.53,5,5,1,2,0,1,36,1,2,1,3 +70856,7,2,1,1,16,4,4,1,NA,17,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10232.679671,11283.202594,2,97,1,1,0.13,4,4,2,0,1,2,62,1,2,4,NA +70857,7,2,1,9,NA,3,3,1,9,119,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,26240.82746,27691.552263,1,94,4,4,0.56,5,5,1,2,0,1,34,1,2,3,NA +70858,7,2,2,9,NA,3,3,2,10,120,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,58907.362493,59749.51689,1,91,10,10,2.77,5,5,0,3,0,1,43,1,5,1,5 +70859,7,2,2,0,6,4,4,2,NA,8,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4581.358327,4715.327587,2,100,6,6,1.34,4,4,1,2,0,2,31,1,4,5,NA +70860,7,2,2,44,NA,4,4,2,NA,NA,2,NA,2,1,4,NA,2,1,2,1,2,2,1,2,2,NA,NA,NA,NA,19075.861607,19725.492117,1,96,7,7,1.69,4,4,0,1,0,2,19,2,4,NA,NA +70861,7,2,2,16,NA,2,2,2,16,201,NA,NA,2,2,2,10,NA,NA,NA,2,2,2,2,2,2,1,2,2,1,17848.732433,20206.102312,2,91,99,99,NA,6,6,1,3,0,2,20,2,2,5,NA +70862,7,2,1,75,NA,5,6,2,NA,NA,2,NA,2,1,9,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,10818.545624,11805.931644,3,90,4,4,0.99,2,2,0,0,2,1,75,2,4,1,NA +70863,7,2,2,77,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,4,3,NA,1,2,1,1,2,1,1,2,1,NA,11462.813869,11819.991623,1,93,2,2,0.87,1,1,0,0,1,2,77,2,4,3,NA +70864,7,2,1,1,12,2,2,2,NA,14,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12567.081957,13464.72134,1,97,5,5,1.04,4,4,1,1,0,1,32,1,3,6,NA +70865,7,2,1,45,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,116464.874823,119757.87667,2,94,9,9,3.35,3,3,0,0,1,2,52,1,2,1,3 +70866,7,2,2,16,NA,3,3,2,16,203,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,80091.55101,82618.226829,1,101,14,14,3.9,4,4,0,2,0,2,41,1,2,1,2 +70867,7,2,2,29,NA,1,1,2,NA,NA,2,NA,2,1,3,NA,4,6,1,2,2,2,2,2,2,2,2,2,2,39426.061521,39404.861746,2,94,7,7,1.34,5,5,2,1,0,1,32,2,1,1,NA +70868,7,2,1,46,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,32980.717958,32895.997285,1,95,4,4,1.21,2,2,0,0,0,1,46,1,2,1,2 +70869,7,2,1,38,NA,1,1,1,NA,NA,2,NA,2,1,6,NA,2,1,NA,2,2,2,1,2,2,1,2,2,2,37715.365512,45063.17837,2,102,7,7,1.04,7,7,1,2,0,2,37,2,1,1,2 +70870,7,2,1,7,NA,3,3,2,7,86,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,46228.073505,47549.950918,2,94,15,15,4.59,4,4,1,1,0,2,37,1,5,1,5 +70871,7,2,1,39,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,11565.978374,12485.281365,1,99,6,6,1.12,4,4,0,2,0,1,39,1,3,1,3 +70872,7,1,2,23,NA,5,6,NA,NA,NA,2,NA,2,2,3,NA,5,5,3,1,2,2,1,2,2,NA,NA,NA,NA,16844.740449,0,3,91,7,7,3.9,2,1,0,0,0,2,21,NA,NA,5,NA +70873,7,2,2,6,NA,1,1,1,6,82,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15962.145468,16371.237244,2,98,14,14,3.25,5,5,2,1,0,1,37,1,5,1,5 +70874,7,2,1,73,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,6725.306794,7069.929472,2,99,7,7,1.52,4,4,0,0,2,1,73,1,3,2,NA +70875,7,2,1,15,NA,3,3,1,15,191,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,71757.969058,71552.342229,1,98,10,10,2.2,6,6,1,3,0,2,31,1,4,6,NA +70876,7,2,1,3,NA,4,4,2,3,36,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9090.947573,10024.256259,1,90,6,6,1.57,3,3,1,0,0,2,25,1,3,6,NA +70877,7,2,1,56,NA,1,1,1,NA,NA,2,NA,2,2,5,NA,1,1,NA,2,2,2,2,2,2,2,2,2,2,22157.736644,21832.606015,1,100,99,99,NA,7,7,2,3,0,2,35,2,1,1,NA +70878,7,2,1,25,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,19163.076248,19068.627285,2,97,7,7,2.38,2,2,0,0,0,1,25,1,2,1,2 +70879,7,2,2,10,NA,5,6,2,10,122,NA,NA,1,1,NA,3,NA,NA,NA,1,1,1,1,2,1,1,2,2,1,9620.269705,10600.850342,2,91,6,6,1.57,3,3,0,1,0,1,41,2,3,1,3 +70880,7,2,2,0,1,3,3,1,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8114.787453,8336.925581,1,94,6,6,0.87,6,6,2,2,0,2,24,1,4,6,NA +70881,7,2,1,23,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,112935.983109,114691.149811,1,102,10,10,4.76,2,2,0,0,0,1,23,1,5,5,NA +70882,7,2,2,8,NA,4,4,1,8,98,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12120.418061,12942.575479,2,101,6,6,0.96,5,5,0,4,0,2,36,1,4,4,NA +70883,7,2,1,31,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,19117.284298,19849.243802,2,95,8,8,2.97,2,2,0,0,0,2,56,1,5,2,NA +70884,7,2,1,14,NA,4,4,2,14,175,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12721.673656,12746.825446,2,100,6,6,1.34,4,4,1,2,0,2,31,1,4,5,NA +70885,7,2,1,8,NA,1,1,1,8,106,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11399.23838,11468.323492,2,103,2,2,0.22,7,7,0,3,0,2,39,2,1,5,NA +70886,7,2,2,21,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,29040.300396,28462.118402,2,101,1,1,0.11,4,1,0,0,0,2,21,1,4,5,NA +70887,7,2,2,59,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,26668.458882,26178.344406,2,102,10,10,4.62,2,2,0,0,0,2,59,1,5,1,NA +70888,7,1,1,0,9,3,3,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,17196.879565,0,2,94,14,14,2.87,5,5,2,1,0,1,37,1,3,1,4 +70889,7,2,2,18,NA,1,1,1,18,220,2,NA,1,1,NA,12,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,16781.078148,17378.8338,2,103,2,2,0.22,7,7,0,3,0,2,39,2,1,5,NA +70890,7,2,2,59,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,16181.169973,15883.791498,1,96,9,7,3.21,2,1,0,0,0,1,58,1,4,6,NA +70891,7,2,2,43,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,4,2,1,2,2,1,2,2,NA,NA,NA,NA,14599.561708,14200.006402,2,99,2,2,0.19,7,7,3,1,0,2,43,1,2,4,NA +70892,7,2,1,6,NA,4,4,2,6,73,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8453.214884,8437.321796,2,101,1,1,0.1,6,6,1,2,1,2,27,1,2,1,2 +70893,7,2,2,30,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,2,1,2,2,1,2,2,1,2,2,1,97101.614214,108614.152251,3,92,6,6,1.17,4,4,0,2,0,2,30,1,2,1,4 +70894,7,2,1,70,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,53149.251154,56449.488341,2,94,8,8,3.4,2,2,0,0,2,2,64,1,4,1,2 +70895,7,2,2,75,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,3,NA,1,2,2,1,2,2,1,2,2,NA,27602.403077,28546.401551,1,94,2,2,0.55,2,2,0,0,2,2,75,1,1,3,NA +70896,7,2,1,15,NA,4,4,1,15,191,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13276.485807,13240.468288,2,100,10,7,2.05,4,3,0,2,0,1,20,1,4,6,NA +70897,7,2,1,52,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,17801.655316,19397.911862,2,95,7,6,1.88,3,2,0,0,0,2,56,1,3,2,NA +70898,7,2,1,71,NA,2,2,2,NA,NA,2,NA,2,2,6,NA,2,1,NA,2,2,2,2,2,2,1,2,2,NA,11755.776731,12827.229805,3,90,12,13,NA,2,1,0,0,1,1,71,2,2,1,NA +70899,7,2,2,66,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,136832.42119,141624.96623,2,91,15,15,5,2,2,0,0,1,2,66,1,5,3,NA +70900,7,2,1,59,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,19093.004278,19032.106491,2,99,2,2,0.19,6,6,0,1,0,1,59,1,2,5,NA +70901,7,2,2,0,11,4,4,1,NA,12,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4943.553921,5444.191192,1,100,14,14,3.47,4,4,2,0,0,1,34,1,5,1,5 +70902,7,2,1,11,NA,4,4,2,11,140,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8930.369586,9237.151674,3,91,4,4,1.09,2,2,0,1,0,2,40,1,5,3,NA +70903,7,2,2,18,NA,1,1,2,19,228,2,NA,2,2,4,13,NA,NA,NA,1,2,2,1,2,2,2,2,2,2,17544.592739,19246.751055,3,92,6,6,1,6,6,1,1,0,1,42,2,1,1,4 +70904,7,2,1,19,NA,2,2,2,19,233,2,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,15351.501195,16874.029415,2,90,4,4,1.29,2,2,0,0,0,2,40,1,2,5,NA +70905,7,2,2,1,16,1,1,1,NA,17,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13322.479814,14708.37523,1,92,14,14,3.9,4,4,2,0,0,2,29,1,4,1,4 +70906,7,2,1,39,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,78529.577822,84771.37367,1,101,14,14,3.9,4,4,0,2,0,2,41,1,2,1,2 +70907,7,2,1,2,NA,4,4,2,2,30,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8064.791396,8892.751276,1,91,99,99,NA,3,3,1,0,0,1,33,2,5,5,NA +70908,7,2,1,25,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,74379.731652,76506.539917,2,92,15,7,3.67,4,1,0,0,0,1,28,1,5,5,NA +70909,7,1,2,13,NA,5,6,NA,NA,NA,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6587.470541,0,1,93,9,9,1.77,7,7,0,2,0,2,56,NA,NA,5,NA +70910,7,2,1,38,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,4,NA,1,2,2,1,2,2,1,2,2,1,18404.681357,20079.255367,1,101,3,3,0.61,4,4,1,2,0,1,38,1,2,4,NA +70911,7,2,1,59,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,146786.506338,147038.128142,1,90,15,15,5,3,3,0,0,0,1,59,1,5,1,5 +70912,7,2,1,67,NA,2,2,1,NA,NA,2,NA,2,1,4,NA,5,2,NA,2,2,2,1,2,2,2,2,2,2,7290.319536,7407.101145,2,93,10,10,5,1,1,0,0,1,1,67,2,5,2,NA +70913,7,2,1,28,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,15507.441472,18423.236589,1,100,9,9,4.92,1,1,0,0,0,1,28,1,5,5,NA +70914,7,2,1,40,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,20568.024192,20733.954282,2,92,1,1,0.02,1,1,0,0,0,1,40,1,2,5,NA +70915,7,1,1,80,NA,3,3,NA,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,37318.801462,0,1,98,6,6,1.95,2,2,0,0,2,1,80,1,3,1,3 +70916,7,2,2,78,NA,2,2,2,NA,NA,2,NA,2,1,9,NA,1,2,NA,2,2,2,2,2,2,1,2,2,NA,17318.187297,23904.945555,2,90,6,3,0.92,2,1,0,0,2,1,76,2,1,2,NA +70917,7,2,1,48,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,22165.906062,24153.500588,1,96,7,7,2.78,2,2,0,0,0,1,48,1,2,6,NA +70918,7,2,2,7,NA,3,3,2,7,89,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,21910.300386,22612.118571,1,99,4,4,1.02,2,2,0,1,0,2,27,1,4,3,NA +70919,7,2,2,7,NA,3,3,1,7,89,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,64166.795496,75335.746424,1,101,5,5,0.89,5,5,1,2,0,1,31,1,2,1,1 +70920,7,2,2,46,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,20303.639991,21936.687597,1,97,7,7,1.48,5,5,0,1,0,2,46,2,4,1,NA +70921,7,2,2,29,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,13976.989712,14629.714123,2,94,77,77,NA,6,6,2,0,0,2,18,1,3,NA,NA +70922,7,2,2,2,NA,5,7,2,2,28,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5588.504831,5743.223814,2,91,15,15,3.7,5,5,1,2,0,1,50,NA,NA,1,5 +70923,7,2,1,63,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,89103.220446,89938.887954,2,98,7,7,2.16,3,3,0,0,1,2,55,1,3,1,4 +70924,7,2,1,0,10,5,6,2,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5528.06179,5490.918184,1,91,14,14,4.48,3,3,1,0,0,1,31,2,5,1,5 +70925,7,2,1,57,NA,5,6,1,NA,NA,2,NA,2,2,7,NA,3,1,NA,1,2,2,1,2,2,1,2,2,3,18416.819037,20059.719948,2,96,5,5,1.36,2,2,0,1,0,1,57,2,3,1,NA +70926,7,1,2,15,NA,2,2,NA,NA,NA,NA,NA,1,1,NA,66,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,17848.732433,0,2,91,8,8,1.85,5,5,0,2,1,1,39,2,3,1,4 +70927,7,2,1,63,NA,2,2,1,NA,NA,2,NA,2,1,6,NA,1,1,NA,2,2,2,1,2,2,NA,NA,NA,NA,9946.027787,10495.972559,2,93,8,8,2.62,3,3,0,0,2,2,64,2,1,1,1 +70928,7,2,2,6,NA,4,4,2,6,74,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,NA,NA,NA,NA,NA,NA,NA,7814.742747,8095.069503,2,95,6,6,0.97,6,6,2,1,0,1,54,1,3,6,NA +70929,7,2,2,29,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,17350.142808,18091.024448,1,92,14,14,2.42,6,6,1,3,0,1,30,1,4,6,NA +70930,7,2,1,6,NA,2,2,2,6,79,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,9807.589376,10028.771,2,90,10,10,3.13,4,4,1,2,0,2,39,1,5,4,NA +70931,7,2,2,44,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,36945.168658,38286.242768,2,96,10,10,3.78,3,3,0,1,0,1,42,1,3,1,3 +70932,7,2,2,43,NA,5,6,2,NA,NA,2,NA,2,2,1,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,18396.558383,19503.669771,1,90,15,15,5,4,4,1,1,0,2,43,2,5,1,5 +70933,7,2,2,46,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,19150.604366,19251.871661,3,91,15,15,5,2,2,0,0,0,2,46,1,5,1,5 +70934,7,2,1,0,4,4,4,1,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5089.464235,5316.261144,2,93,6,6,1.15,5,5,3,1,0,1,29,1,3,5,NA +70935,7,2,2,46,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,20084.755052,20430.629009,1,99,15,15,5,4,4,0,2,0,2,46,1,5,1,5 +70936,7,2,1,27,NA,1,1,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,2,2,2,2,35669.2076,40318.090187,2,94,8,8,2.7,3,3,1,0,0,1,27,1,3,1,4 +70937,7,2,2,12,NA,4,4,2,12,154,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12857.456314,12921.235691,2,97,4,4,0.57,5,5,1,3,0,2,33,1,3,5,NA +70938,7,2,1,49,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,52756.101074,53793.249362,3,92,8,8,2.97,2,2,0,0,1,1,49,1,2,3,NA +70939,7,2,2,28,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,2,6,2,1,2,2,1,2,2,1,2,2,1,39550.779175,41765.24601,2,96,14,14,3.36,4,4,1,1,0,2,28,1,2,6,NA +70940,7,2,1,21,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,131567.279219,134004.437006,1,97,15,15,5,3,3,0,0,0,1,53,NA,NA,1,4 +70941,7,2,1,45,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,87954.465296,90754.904886,2,100,10,10,3.13,4,4,0,2,0,1,45,1,4,1,4 +70942,7,2,2,16,NA,1,1,1,16,194,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,15690.47168,16249.379042,1,102,8,8,1.33,7,7,1,4,0,2,32,1,3,1,2 +70943,7,2,1,8,NA,1,1,2,8,105,NA,NA,1,1,NA,3,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,10449.970381,10975.442173,1,90,2,1,0.17,5,2,0,1,0,1,25,2,2,6,NA +70944,7,2,2,0,0,1,1,1,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7798.643057,7634.568742,1,102,8,8,2.06,4,4,2,0,0,1,28,1,2,1,5 +70945,7,2,1,49,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,33558.731068,36590.680559,1,101,3,1,0,2,1,0,0,1,2,65,1,3,3,NA +70946,7,1,1,2,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,24594.444896,0,1,98,5,2,0.42,4,3,2,0,0,1,24,1,3,6,NA +70947,7,2,2,4,NA,3,3,2,4,59,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,59430.588937,63158.057955,2,91,15,15,4.2,6,6,2,0,2,1,63,1,1,1,3 +70948,7,2,2,19,NA,4,4,1,19,231,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,18163.985724,18905.695776,2,101,1,1,0.05,2,1,0,0,0,2,19,1,3,NA,NA +70949,7,2,2,68,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,128590.415432,131137.819973,1,102,15,15,5,2,2,0,0,2,2,68,1,4,1,5 +70950,7,2,1,50,NA,2,2,1,NA,NA,2,NA,2,2,6,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,34422.302712,34961.637568,2,92,2,2,0.4,3,3,0,0,0,1,50,2,4,1,4 +70951,7,2,1,7,NA,4,4,2,7,91,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8050.419807,8503.565046,2,99,4,4,0.41,7,7,0,2,0,2,36,1,3,5,NA +70952,7,1,2,64,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,19125.640099,0,2,95,77,77,NA,2,2,0,0,2,1,64,NA,NA,1,3 +70953,7,1,2,9,NA,2,2,NA,NA,NA,NA,NA,2,1,2,4,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12789.411811,0,1,102,7,7,1.9,4,4,1,1,0,1,29,1,4,1,3 +70954,7,2,1,61,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,28559.076421,28710.827523,1,95,5,5,2.2,1,1,0,0,1,1,61,1,3,3,NA +70955,7,2,1,14,NA,5,6,1,14,169,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8915.81491,9312.338117,1,92,12,12,NA,4,4,0,1,0,1,53,2,5,1,4 +70956,7,2,1,15,NA,1,1,2,15,188,NA,NA,1,1,NA,9,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,20398.562455,20481.595361,2,94,4,4,0.81,3,3,0,1,0,1,49,2,3,1,3 +70957,7,2,1,12,NA,1,1,2,12,154,NA,NA,1,1,NA,6,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,20398.562455,20710.36162,2,94,13,13,NA,5,5,0,3,0,1,32,2,2,1,1 +70958,7,2,1,1,15,2,2,2,NA,15,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,9237.934626,9085.733547,2,90,5,5,0.89,4,4,2,0,0,2,26,2,2,4,NA +70959,7,2,2,55,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,44296.789734,46174.107604,2,102,4,1,0,2,1,0,0,0,2,43,1,5,6,NA +70960,7,2,2,8,NA,4,4,2,8,100,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7120.704736,7311.203604,1,99,15,8,2.7,4,3,0,2,0,1,49,1,4,6,NA +70961,7,2,2,74,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,NA,55881.349278,57792.483909,2,92,9,9,5,1,1,0,0,1,2,74,1,5,5,NA +70962,7,2,1,40,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,NA,NA,NA,1,2,2,1,14321.1466,14549.731107,1,96,15,15,5,6,6,1,1,1,2,44,1,3,1,3 +70963,7,2,2,17,NA,2,2,1,17,209,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,2,2,2,1,2,2,1,18556.092615,20535.833102,1,103,7,7,1.03,7,7,0,3,0,1,50,2,1,1,1 +70964,7,2,2,35,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,27738.890335,27824.17823,2,101,4,4,0.73,5,5,1,2,0,1,40,1,5,1,5 +70965,7,2,1,5,NA,2,2,2,5,62,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11161.439403,11514.748174,2,99,13,13,NA,6,6,2,1,0,2,31,1,4,6,NA +70966,7,2,1,20,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,14313.345971,15054.191928,3,91,5,3,0.92,2,1,0,0,0,1,20,1,4,6,NA +70967,7,2,1,25,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,22723.53676,24747.854656,1,92,NA,99,NA,4,1,0,2,0,2,56,1,4,4,NA +70968,7,2,2,8,NA,3,3,1,9,108,NA,NA,2,2,3,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,13450.606713,14078.286101,3,91,4,4,0.65,5,5,2,2,0,2,27,2,2,3,NA +70969,7,2,1,45,NA,1,1,1,NA,NA,2,NA,2,2,3,NA,3,1,NA,2,2,2,2,2,2,1,2,2,2,31233.526521,31366.480522,1,100,8,3,1.03,6,1,1,0,0,1,33,2,3,6,NA +70970,7,2,1,31,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,15867.258653,18200.873488,3,91,3,3,0.76,3,3,0,1,0,2,24,1,4,6,NA +70971,7,2,1,39,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,4,NA,1,2,2,1,2,2,1,2,2,1,20486.987447,21605.827026,2,101,3,3,0.6,3,3,0,2,0,1,39,1,4,4,NA +70972,7,2,1,61,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,5950.975297,5997.525697,2,99,77,77,NA,3,3,0,1,1,1,61,1,4,3,NA +70973,7,2,1,39,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,18404.681357,19079.901799,1,101,7,7,1.83,3,3,0,0,2,1,67,1,1,1,2 +70974,7,2,1,49,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,27356.080541,30234.306382,1,101,5,5,1.15,3,3,0,1,0,1,49,1,3,1,4 +70975,7,2,2,22,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,118761.81384,123645.102237,3,91,4,4,1.02,2,2,0,0,0,1,22,1,5,1,5 +70976,7,2,1,17,NA,2,2,1,17,211,2,NA,2,1,4,11,NA,NA,NA,1,2,2,2,2,2,1,2,2,1,20327.892981,20116.618863,2,93,4,4,0.69,4,4,0,1,1,2,66,2,3,2,NA +70977,7,2,1,3,NA,3,3,1,4,48,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,98584.614475,106037.774242,2,101,6,6,1.35,3,3,1,0,0,1,42,1,4,6,NA +70978,7,2,1,15,NA,4,4,2,15,183,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11834.781205,13035.394237,2,90,2,2,0.31,5,5,0,2,1,2,71,1,2,2,NA +70979,7,2,1,46,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,18230.629439,18292.13185,1,93,15,15,5,5,5,1,2,0,2,40,1,5,1,5 +70980,7,2,1,32,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,114168.79702,117438.65007,1,95,8,8,1.28,7,7,1,4,0,1,32,1,3,1,3 +70981,7,2,1,50,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,13525.38183,13953.637486,2,95,15,15,5,3,3,1,0,0,1,50,1,5,1,NA +70982,7,2,1,44,NA,2,2,2,NA,NA,2,NA,2,2,1,NA,2,1,NA,2,2,2,2,2,2,2,2,1,2,39096.402803,46193.238956,2,91,4,4,0.76,4,4,1,0,0,2,25,2,4,77,NA +70983,7,2,2,39,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,71746.365541,83232.546386,1,93,15,15,5,2,2,0,0,0,2,39,1,5,1,5 +70984,7,2,1,73,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,96955.880155,102625.661518,2,101,15,15,5,2,2,0,0,2,1,73,1,5,1,5 +70985,7,2,1,74,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,NA,8601.453077,8734.617022,2,101,5,5,2.02,1,1,0,0,1,1,74,1,2,3,NA +70986,7,2,2,4,NA,4,4,2,4,57,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9268.093277,9507.318489,1,99,14,14,4.05,3,3,1,0,0,2,32,1,5,1,4 +70987,7,2,2,22,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,130601.953362,132156.64994,2,91,15,15,5,4,4,0,0,0,1,54,1,5,1,NA +70988,7,2,2,1,14,4,4,1,NA,15,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8754.193667,9419.610037,2,98,8,8,1.8,5,5,2,1,0,1,32,1,4,1,5 +70989,7,2,1,16,NA,3,3,1,16,193,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,30943.024697,32205.010072,1,101,4,4,0.58,6,6,0,4,0,2,41,1,3,5,NA +70990,7,2,2,6,NA,1,1,1,6,75,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15048.411882,15335.781033,1,103,14,14,2.96,5,5,1,2,0,1,34,1,4,1,5 +70991,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,25520.996455,28503.986081,1,93,3,3,0.75,2,2,0,0,1,2,80,1,1,2,NA +70992,7,2,2,1,14,2,2,2,NA,15,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11412.410776,11898.666241,1,97,3,3,0.44,5,5,2,2,0,2,26,1,4,4,NA +70993,7,2,1,38,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,15399.847485,15604.102319,1,103,8,8,4.3,1,1,0,0,0,1,38,1,5,5,NA +70994,7,2,2,13,NA,2,2,2,13,159,NA,NA,2,2,3,6,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,12680.621719,13709.581084,2,90,99,99,NA,5,5,1,1,0,2,40,2,3,1,1 +70995,7,2,2,34,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,2,1,2,2,1,2,2,1,2,2,1,31335.13799,32015.561405,1,95,6,4,1.26,6,2,1,2,0,1,28,1,2,1,2 +70996,7,2,1,41,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,49072.976757,48585.714967,1,97,15,15,5,2,2,0,0,0,1,41,1,5,1,5 +70997,7,2,2,62,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,NA,9570.416297,10279.373686,2,98,2,2,0.83,1,1,0,0,1,2,62,1,3,3,NA +70998,7,2,2,6,NA,2,2,2,6,73,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,10762.400563,11527.105697,2,90,6,6,2.01,2,2,0,1,0,2,26,1,3,5,NA +70999,7,2,2,50,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,161992.272945,161249.908749,1,91,14,14,3.15,5,5,0,1,0,2,50,1,5,1,5 +71000,7,2,2,0,6,5,6,1,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,7065.624287,7145.357301,2,92,6,6,1.34,4,4,1,1,0,1,40,2,3,1,3 +71001,7,2,1,6,NA,4,4,2,6,74,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7386.979006,7738.237294,2,99,5,5,0.65,6,6,2,1,0,2,53,1,4,3,NA +71002,7,2,1,13,NA,1,1,1,13,165,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,24228.858782,24226.727855,2,102,7,7,2.16,3,3,0,2,0,2,41,1,5,3,NA +71003,7,2,1,78,NA,3,3,1,NA,NA,2,NA,2,1,7,NA,1,5,NA,1,2,1,1,2,1,1,2,1,NA,12184.871688,13005.96831,2,103,2,2,0.45,1,1,0,0,1,1,78,2,1,5,NA +71004,7,2,2,62,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,4,NA,1,2,2,1,2,2,1,2,2,1,14809.997435,16069.288743,2,97,1,1,0.13,4,4,2,0,1,2,62,1,2,4,NA +71005,7,2,2,64,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,11355.3308,12230.621635,1,96,8,8,3.14,2,2,0,0,2,2,64,1,3,1,2 +71006,7,2,2,4,NA,1,1,2,4,59,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,13366.393396,13546.155547,2,94,5,5,1.3,3,3,1,1,0,2,34,2,2,5,NA +71007,7,2,2,1,16,1,1,1,NA,17,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14326.094268,15816.39252,3,92,15,15,5,3,3,1,0,0,1,34,1,5,1,5 +71008,7,2,1,50,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,25969.864445,25963.066565,1,97,14,14,5,3,3,0,0,0,2,51,1,5,1,4 +71009,7,1,2,4,NA,5,7,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15046.736747,0,1,101,6,6,1.07,5,5,2,1,0,1,30,1,3,1,3 +71010,7,2,2,23,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,43813.24867,47156.814318,1,98,5,2,0.42,4,3,2,0,0,1,24,1,3,6,NA +71011,7,2,2,57,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,175997.804296,176135.086149,1,101,3,3,0.73,2,2,0,0,1,1,60,1,3,1,5 +71012,7,2,2,24,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,144794.522788,148845.957701,1,97,8,8,3.57,2,2,0,0,0,2,49,1,3,3,NA +71013,7,2,2,5,NA,4,4,2,5,66,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9986.420822,10886.623262,2,97,2,2,0.21,7,7,2,3,0,2,32,1,4,5,NA +71014,7,2,2,16,NA,5,7,2,16,199,NA,NA,1,1,NA,8,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11747.462633,12227.159724,2,99,6,6,1.18,5,5,0,3,0,2,38,1,2,5,NA +71015,7,2,2,49,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,23342.391629,23465.824854,1,92,15,15,5,2,2,0,0,0,2,49,1,5,3,NA +71016,7,2,2,5,NA,1,1,1,5,62,NA,NA,2,2,1,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,17282.036547,19079.832121,2,102,15,15,5,3,3,1,0,0,1,41,2,2,1,5 +71017,7,2,2,10,NA,3,3,2,10,122,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15442.305642,16400.253331,2,94,5,5,1.3,3,3,0,1,0,1,43,1,3,6,NA +71018,7,2,1,5,NA,3,3,2,5,62,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,57680.74785,67586.530677,1,99,5,5,0.89,4,4,2,0,0,2,31,1,4,1,5 +71019,7,2,2,10,NA,1,1,1,10,130,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,15962.145468,16061.826248,2,98,2,2,0.27,4,4,2,1,0,2,32,2,2,5,NA +71020,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,30212.098573,34791.026267,1,92,3,3,1.01,1,1,0,0,1,2,80,1,3,2,NA +71021,7,2,1,64,NA,5,6,2,NA,NA,2,NA,2,1,8,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,6011.560142,6320.246286,2,99,3,3,1.29,1,1,0,0,1,1,64,2,4,3,NA +71022,7,2,1,11,NA,3,3,1,11,135,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,19590.665143,20475.022602,3,91,5,5,0.87,4,4,0,2,0,2,38,1,2,3,NA +71023,7,2,1,10,NA,1,1,1,10,122,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13822.148996,13905.918164,3,92,15,15,3.15,7,7,0,4,0,2,35,2,3,3,NA +71024,7,2,1,7,NA,3,3,2,7,93,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,47596.305609,49235.587472,1,99,14,14,5,3,3,0,1,0,1,35,1,5,1,5 +71025,7,2,1,61,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,7514.993062,9722.610426,2,90,1,1,0.28,1,1,0,0,1,1,61,1,2,5,NA +71026,7,2,1,14,NA,1,1,1,14,176,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,19570.996814,19477.677478,2,100,4,4,0.81,4,4,0,2,0,1,56,1,4,1,2 +71027,7,2,1,10,NA,1,1,1,10,129,NA,NA,1,1,NA,2,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,13927.458372,14147.852881,2,98,3,3,0.33,7,7,2,3,0,1,40,2,1,1,1 +71028,7,2,1,2,NA,1,1,1,2,32,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10736.26749,11503.13577,1,103,5,5,1.02,4,4,2,0,0,1,25,1,2,1,4 +71029,7,2,2,25,NA,5,6,2,NA,NA,2,NA,2,1,3,NA,3,1,2,1,2,1,1,2,2,NA,NA,NA,NA,13820.210756,14687.211885,1,90,8,8,1.43,7,7,2,0,0,1,23,2,4,1,3 +71030,7,2,2,13,NA,2,2,2,13,167,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14437.97544,15197.369043,2,90,14,14,3.45,4,4,1,1,0,2,34,2,5,6,NA +71031,7,1,1,27,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,34087.731449,0,3,92,4,3,0.52,5,4,0,0,0,2,57,1,4,1,2 +71032,7,2,2,12,NA,1,1,1,13,156,NA,NA,1,1,NA,5,NA,NA,NA,2,1,2,2,2,2,1,2,2,2,22424.988432,23223.784759,1,94,7,7,2.1,3,3,0,1,0,2,48,2,1,1,3 +71033,7,1,1,26,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,17579.006909,0,2,103,15,15,5,1,1,0,0,0,1,26,1,3,5,NA +71034,7,2,1,11,NA,4,4,2,11,134,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8451.853606,8465.026785,1,93,7,7,1.97,4,4,1,2,0,2,33,1,4,3,NA +71035,7,2,1,7,NA,5,6,2,7,95,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10810.913614,11461.625841,1,97,14,14,2.87,5,5,0,3,0,2,40,2,5,1,5 +71036,7,2,1,29,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,105262.341027,110623.017272,2,98,8,8,3.67,2,2,0,0,0,2,54,1,4,3,NA +71037,7,2,2,52,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,15497.844354,15358.163767,1,99,15,15,5,2,2,0,0,0,1,56,1,4,1,4 +71038,7,2,1,60,NA,2,2,2,NA,NA,2,NA,2,1,8,NA,2,1,NA,2,2,2,2,2,2,1,2,2,2,8609.250304,11228.904188,2,90,1,1,0.27,2,2,0,0,1,1,60,2,2,1,1 +71039,7,2,2,30,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,81385.450947,85814.999376,1,93,15,15,5,2,2,0,0,0,2,30,1,5,1,5 +71040,7,2,1,63,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,36541.405352,36735.571242,1,101,4,4,1.22,2,2,0,0,1,1,63,1,2,1,2 +71041,7,2,1,9,NA,5,6,2,9,112,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10810.913614,11461.625841,1,97,15,15,2.33,7,7,2,4,0,2,40,2,5,1,4 +71042,7,2,1,38,NA,5,6,1,NA,NA,2,NA,2,2,6,NA,2,1,NA,1,2,2,1,2,2,1,2,2,3,13147.594977,14207.241654,1,102,5,5,0.92,5,5,1,2,0,2,44,2,1,1,2 +71043,7,2,2,9,NA,4,4,1,9,110,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13192.206605,13608.834197,2,102,9,9,2.68,4,4,0,2,0,2,32,1,4,1,NA +71044,7,2,1,0,2,5,7,2,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9570.577309,9675.725524,1,95,6,6,1.15,5,5,2,1,0,1,29,1,4,6,NA +71045,7,2,1,80,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,3,4,NA,1,2,2,1,2,2,1,2,2,NA,10947.445281,13128.299802,1,94,4,4,1.43,1,1,0,0,1,1,80,1,3,4,NA +71046,7,2,1,52,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,144353.133634,150786.620773,1,91,14,14,4.03,4,4,0,2,0,1,52,1,4,1,5 +71047,7,2,2,52,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,NA,16058.142925,17306.419461,2,95,5,5,1.18,3,3,0,1,0,2,55,1,4,5,NA +71048,7,2,2,52,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,4,NA,1,2,2,1,2,2,NA,NA,NA,NA,24870.513993,26515.471818,2,98,1,1,0.13,4,4,2,0,0,2,52,1,2,4,NA +71049,7,2,2,20,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,57438.356061,66140.327263,2,101,1,1,0.08,1,1,0,0,0,2,20,1,4,5,NA +71050,7,2,2,0,4,2,2,2,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,4481.392842,4343.672823,2,90,12,12,NA,7,7,2,2,0,1,39,2,1,1,1 +71051,7,2,1,78,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,79754.311902,90534.066519,1,97,15,15,5,2,2,0,0,2,1,78,1,3,1,3 +71052,7,2,2,18,NA,1,1,1,18,217,2,NA,2,2,3,10,NA,NA,NA,2,2,2,2,2,2,2,2,2,2,19993.78712,21491.713499,1,100,99,99,NA,7,7,2,3,0,2,35,2,1,1,NA +71053,7,2,2,61,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,9680.216878,10112.428208,1,96,12,10,5,2,1,0,0,1,2,61,1,4,3,NA +71054,7,2,2,51,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,140431.173819,139253.659476,1,94,10,6,2.42,2,1,0,0,0,1,59,1,4,6,NA +71055,7,2,2,0,4,5,6,2,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6580.402774,6856.045444,1,94,99,99,NA,5,5,1,1,0,2,21,1,3,5,NA +71056,7,1,1,59,NA,5,6,NA,NA,NA,2,NA,2,1,7,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,15409.233853,0,1,92,12,12,NA,4,4,0,0,0,1,59,2,3,1,4 +71057,7,2,2,62,NA,4,4,2,NA,NA,1,2,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,11190.39853,11690.037855,2,99,99,99,NA,2,2,0,0,2,2,62,1,5,3,NA +71058,7,2,2,19,NA,3,3,2,19,233,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,41202.729804,43105.611516,2,91,6,6,1.26,5,5,0,1,2,2,80,1,4,2,NA +71059,7,2,1,53,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,1,27227.937106,27501.844882,1,101,3,3,0.96,2,2,0,0,0,1,53,1,1,1,2 +71060,7,2,2,31,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,4,2,2,1,2,2,1,2,2,1,2,2,1,21306.824647,21870.080421,2,98,1,1,0.19,3,3,2,0,0,2,31,1,4,2,NA +71061,7,2,1,54,NA,1,1,1,NA,NA,2,NA,2,1,7,NA,4,1,NA,2,2,2,2,2,2,1,2,2,2,37557.946192,37296.340716,2,102,9,9,3.24,3,3,0,0,0,1,54,2,4,1,4 +71062,7,2,1,52,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,31291.360507,32453.566842,2,91,12,3,1.25,3,1,0,0,1,1,52,1,4,3,NA +71063,7,2,2,34,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,6,2,1,2,2,1,2,2,NA,NA,NA,NA,85610.546667,92292.669073,2,91,15,15,5,5,5,1,2,0,1,37,1,4,6,NA +71064,7,2,2,26,NA,5,6,1,NA,NA,2,NA,2,2,4,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,10783.449126,11243.921386,1,103,5,5,0.65,6,6,0,0,1,2,26,2,4,5,NA +71065,7,2,2,51,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,38739.556504,38769.774143,2,101,6,6,2.04,2,2,0,0,0,2,51,1,5,1,4 +71066,7,2,2,71,NA,2,2,2,NA,NA,2,NA,2,1,8,NA,1,5,NA,2,2,2,2,2,2,1,2,2,NA,18697.677461,20882.090197,1,93,6,6,2.66,1,1,0,0,1,2,71,2,1,5,NA +71067,7,2,2,4,NA,1,1,2,4,55,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,14812.229505,15746.041025,1,97,4,4,0.72,5,5,2,1,0,2,33,2,1,6,NA +71068,7,2,1,45,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,108839.502248,114346.356011,2,95,3,3,0.93,2,2,0,0,0,1,45,1,4,1,5 +71069,7,2,2,62,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,133022.268903,132572.26134,1,98,6,6,1.75,2,2,0,0,2,1,62,1,4,1,3 +71070,7,2,2,79,NA,4,4,2,NA,NA,2,NA,2,1,6,NA,2,2,NA,1,2,1,1,2,1,1,2,1,NA,12344.929687,13268.288363,1,93,2,2,0.73,1,1,0,0,1,2,79,2,2,2,NA +71071,7,2,2,36,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,14939.690418,15327.735621,2,92,8,8,3.54,2,2,0,0,0,1,30,1,5,1,5 +71072,7,2,2,50,NA,2,2,1,NA,NA,2,NA,2,1,7,NA,3,4,NA,2,2,2,1,2,2,1,2,2,1,19676.781212,20391.029456,1,103,6,6,1.57,3,3,0,1,0,2,50,2,3,4,NA +71073,7,2,2,18,NA,4,4,2,18,226,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12857.456314,12921.235691,2,97,8,8,2.7,3,3,0,0,1,2,72,1,2,3,NA +71074,7,1,2,1,14,5,6,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6565.095533,0,1,90,15,15,5,4,4,2,0,0,1,36,1,5,1,5 +71075,7,2,2,3,NA,3,3,2,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,50908.326714,56187.051166,1,99,5,5,0.89,4,4,2,0,0,2,31,1,4,1,5 +71076,7,2,2,63,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,15732.436891,16737.04767,1,97,14,14,3.93,3,3,0,1,2,2,63,1,4,1,4 +71077,7,2,2,13,NA,1,1,1,13,158,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,2,2,2,1,2,2,1,12970.724558,13432.752316,2,103,8,8,1.29,7,7,3,1,0,2,53,2,2,4,NA +71078,7,2,2,22,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,23614.167119,30467.110717,2,97,3,3,0.82,2,2,1,0,0,2,22,1,4,5,NA +71079,7,2,1,34,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,78529.577822,81088.445647,1,98,14,14,3.15,5,5,0,3,0,1,34,1,4,1,4 +71080,7,1,1,22,NA,3,3,NA,NA,NA,1,2,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,88006.905716,0,1,92,6,6,1.51,3,3,0,0,0,1,46,1,3,3,NA +71081,7,2,1,4,NA,4,4,2,4,52,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7431.820906,7738.904727,1,99,5,5,0.84,5,5,2,1,0,1,35,1,3,1,2 +71082,7,2,1,78,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,1,1,NA,1,2,1,1,2,1,1,2,1,NA,11550.158096,13775.328408,2,92,7,7,1.17,6,6,0,1,1,1,78,2,1,1,3 +71083,7,2,2,62,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,9497.094386,9921.129492,2,100,15,15,5,2,2,0,0,1,1,51,1,5,1,3 +71084,7,2,1,55,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,4,NA,1,2,2,1,2,2,1,2,2,1,23205.758348,23717.246496,3,92,5,5,1.03,4,4,0,3,0,1,55,1,4,4,NA +71085,7,2,1,1,15,4,4,2,NA,17,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6837.992772,6921.398172,1,96,12,12,NA,2,2,1,0,0,2,32,1,5,5,NA +71086,7,2,1,24,NA,5,6,1,NA,NA,1,2,2,2,3,NA,4,5,NA,1,2,2,1,2,2,1,2,2,3,14979.624397,15387.451243,1,102,3,1,0.28,2,1,0,0,0,1,24,2,4,5,NA +71087,7,2,2,65,NA,1,1,1,NA,NA,2,NA,2,2,8,NA,1,2,NA,2,2,2,2,2,2,2,2,2,2,15207.312407,15896.113669,2,98,4,4,0.48,6,6,2,0,2,2,65,2,1,2,NA +71088,7,2,2,13,NA,2,2,2,13,160,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,16680.090857,17557.412914,1,90,15,15,5,4,4,0,2,0,2,43,1,5,1,5 +71089,7,2,2,32,NA,1,1,1,NA,NA,2,NA,2,7,77,NA,3,4,2,2,2,2,2,2,2,1,2,2,2,49274.703023,52411.531429,2,102,77,77,NA,3,3,0,0,0,2,48,2,2,1,3 +71090,7,2,1,49,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,11113.602843,11901.173467,3,90,15,15,5,4,4,0,2,0,2,41,2,5,1,5 +71091,7,2,2,39,NA,2,2,1,NA,NA,2,NA,2,1,NA,NA,4,6,2,1,2,2,1,2,2,NA,NA,NA,NA,45662.166351,45001.161705,1,92,14,9,3.77,3,2,0,1,0,2,39,2,4,6,NA +71092,7,2,2,71,NA,1,1,1,NA,NA,2,NA,2,2,77,NA,1,2,NA,2,2,2,2,2,2,2,2,2,NA,20127.084548,24087.460037,1,103,77,77,NA,4,4,1,0,1,1,20,1,3,6,NA +71093,7,2,1,50,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,185033.990584,188295.9196,1,97,15,15,5,2,2,0,0,0,1,50,1,3,6,NA +71094,7,2,2,51,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,140431.173819,139253.659476,1,94,9,9,3.97,2,2,0,0,0,1,59,1,3,5,NA +71095,7,2,1,31,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,81642.217375,85347.318656,3,91,14,14,5,3,3,1,0,0,2,30,1,4,1,5 +71096,7,2,2,13,NA,1,1,1,13,160,NA,NA,1,1,NA,6,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,18515.058419,19360.671834,2,96,6,6,1.11,6,6,0,2,1,1,40,2,2,1,2 +71097,7,2,1,21,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,25815.880139,25989.236835,2,101,99,1,0.21,3,1,0,0,0,1,20,1,4,5,NA +71098,7,2,2,19,NA,4,4,1,19,229,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,18163.985724,18749.311901,2,101,2,1,0.32,4,1,0,0,0,2,19,1,4,NA,NA +71099,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,NA,47566.45715,54102.989916,1,90,9,9,5,1,1,0,0,1,2,80,1,5,3,NA +71100,7,2,2,80,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,12020.872946,12623.344251,3,90,15,15,4.07,5,5,0,2,1,1,42,1,5,1,4 +71101,7,2,1,51,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,19541.667675,20187.705923,2,95,2,2,0.75,1,1,0,0,0,1,51,1,2,5,NA +71102,7,2,1,19,NA,5,6,1,20,NA,2,NA,2,2,4,15,NA,NA,NA,1,2,2,1,2,1,1,2,2,1,5904.602463,6308.718622,2,92,6,6,1.3,4,4,0,1,0,2,48,2,3,1,3 +71103,7,2,2,57,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,32709.179605,34590.259766,1,94,6,6,1.26,5,5,0,2,0,2,38,1,4,1,NA +71104,7,2,2,78,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,13141.36586,14020.834298,1,96,6,6,2.46,1,1,0,0,1,2,78,1,2,2,NA +71105,7,2,2,66,NA,2,2,1,NA,NA,2,NA,2,2,2,NA,2,3,NA,2,2,2,2,2,2,2,2,1,2,8725.210615,9371.55685,2,93,14,14,2.43,7,7,1,1,1,2,66,2,2,3,NA +71106,7,2,1,1,19,3,3,2,NA,20,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,31199.621619,36557.677601,1,97,5,5,0.87,4,4,2,0,0,1,35,1,5,1,5 +71107,7,2,2,34,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,2,1,2,2,1,2,2,1,2,2,1,64581.191728,65990.445093,2,94,15,10,5,3,1,0,0,0,1,26,NA,NA,77,NA +71108,7,2,2,20,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,23845.8146,22808.13483,1,98,2,1,0.04,4,1,0,0,0,2,19,1,4,NA,NA +71109,7,2,2,0,9,1,1,1,NA,9,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8775.375504,9358.559086,2,102,14,14,3.8,4,4,2,0,0,2,41,2,4,1,5 +71110,7,2,1,2,NA,2,2,1,2,35,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13002.944731,13931.716845,2,91,4,4,0.69,4,4,2,0,0,2,21,1,3,6,NA +71111,7,2,2,75,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,18069.116427,18623.459107,2,100,2,2,0.62,1,1,0,0,1,2,75,1,4,2,NA +71112,7,2,2,55,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,22631.175755,22215.258702,2,96,7,7,2.58,2,2,0,0,1,2,55,1,4,3,NA +71113,7,2,2,26,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,12412.338679,12980.380959,3,90,15,15,3.7,5,5,0,0,0,1,56,2,3,1,3 +71114,7,2,2,20,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,132307.499792,154386.779868,1,98,1,1,0.31,1,1,0,0,0,2,20,1,4,5,NA +71115,7,2,2,12,NA,4,4,2,12,150,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11600.051433,12143.645666,3,90,14,14,2.97,5,5,0,2,1,1,73,2,3,2,NA +71116,7,2,2,7,NA,4,4,2,7,92,NA,NA,2,2,2,0,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,9412.419416,10343.079616,1,93,5,5,0.64,7,7,0,2,1,1,21,2,4,5,NA +71117,7,2,2,32,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,NA,NA,NA,NA,25241.487585,26857.231387,2,97,2,2,0.21,7,7,2,3,0,2,32,1,4,5,NA +71118,7,2,2,51,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,34802.051557,36349.694696,1,101,4,4,0.99,2,2,0,0,0,2,51,1,5,1,2 +71119,7,2,1,36,NA,3,3,1,NA,NA,2,NA,2,2,4,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,71111.990643,75738.399435,2,103,15,15,5,4,4,2,0,0,1,36,2,4,1,5 +71120,7,2,1,69,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,28559.076421,28710.827523,1,95,2,2,0.88,1,1,0,0,1,1,69,1,3,3,NA +71121,7,2,2,0,11,5,6,2,NA,12,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4326.150649,4254.537398,1,99,14,14,2.66,7,7,3,1,0,1,35,1,5,1,5 +71122,7,2,1,63,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,121588.761604,120347.630506,1,91,15,15,5,2,2,0,0,2,1,63,1,4,1,5 +71123,7,2,1,41,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,23824.065321,24171.124621,1,100,14,14,3.6,4,4,1,1,0,1,41,1,4,1,5 +71124,7,1,1,0,10,2,2,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,4944.997189,0,1,103,13,13,NA,6,6,1,2,0,2,40,2,3,3,NA +71125,7,2,2,9,NA,5,6,1,9,115,NA,NA,1,1,NA,3,NA,NA,NA,1,1,1,1,2,1,1,2,2,1,5064.232234,5712.276567,2,92,99,2,0.31,7,4,3,3,1,1,61,2,1,1,3 +71126,7,2,1,5,NA,1,1,1,5,68,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,2,2,2,NA,NA,NA,NA,14321.363328,14968.737037,2,96,6,6,0.77,7,7,2,1,0,1,53,2,1,1,1 +71127,7,2,2,70,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,59282.809425,61101.54758,1,101,14,14,5,2,2,0,0,2,2,70,1,5,1,2 +71128,7,2,1,6,NA,3,3,1,6,76,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,19998.804,20570.663593,1,94,3,3,0.37,5,5,0,3,0,2,29,1,4,4,NA +71129,7,2,1,16,NA,3,3,1,16,200,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,69211.537407,74163.290023,1,92,14,14,3.16,6,6,1,1,0,1,49,1,1,1,3 +71130,7,2,2,50,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,4,NA,1,2,2,1,2,2,1,2,2,1,19130.568715,18607.010517,2,98,5,5,0.59,7,7,3,0,0,2,50,1,5,4,NA +71131,7,2,1,13,NA,3,3,1,13,156,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,71934.689876,71392.8162,1,100,15,15,5,4,4,0,1,0,1,50,1,4,1,4 +71132,7,2,2,68,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,134694.414609,139412.076132,2,94,10,10,4.3,2,2,0,0,2,1,69,1,4,1,5 +71133,7,2,2,36,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,82820.100138,94804.847305,1,90,7,7,3.13,1,1,0,0,0,2,36,1,5,5,NA +71134,7,2,1,3,NA,3,3,2,3,41,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,57680.74785,67586.530677,1,99,77,77,NA,4,4,1,1,0,1,31,2,3,1,3 +71135,7,2,2,76,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,33731.056243,35845.261325,2,98,3,3,0.88,2,2,0,0,2,1,77,1,1,1,3 +71136,7,2,1,21,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,9956.598907,12313.186759,1,95,5,5,0.73,6,6,1,0,1,1,62,2,3,1,NA +71137,7,2,1,61,NA,1,1,1,NA,NA,1,1,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,NA,14488.953694,14771.336069,3,92,1,1,0.24,1,1,0,0,1,1,61,1,4,5,NA +71138,7,2,1,0,7,4,4,1,NA,7,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10070.421465,10410.321555,2,101,4,4,0.76,4,4,1,1,0,1,28,1,2,1,4 +71139,7,2,1,7,NA,1,1,1,7,90,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11159.151566,11210.524757,1,102,4,4,0.5,6,6,2,2,0,1,25,1,2,1,3 +71140,7,2,1,26,NA,1,1,2,NA,NA,2,NA,2,2,2,NA,4,5,NA,2,2,2,2,2,2,2,2,2,2,35669.2076,36620.108921,2,94,15,15,5,3,3,0,0,0,1,41,2,3,1,NA +71141,7,2,2,78,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,20131.904783,20903.590301,1,92,8,8,2.51,3,3,0,0,1,2,78,1,5,2,NA +71142,7,1,1,8,NA,5,6,NA,NA,NA,NA,NA,1,1,NA,1,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,8943.919305,0,1,92,5,5,0.63,7,7,0,4,1,1,60,NA,NA,1,NA +71143,7,2,2,53,NA,4,4,2,NA,NA,2,NA,2,1,8,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,19548.136896,19371.951409,1,90,15,15,5,2,2,0,0,0,1,57,2,4,1,5 +71144,7,2,2,30,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,NA,NA,NA,NA,22758.541444,24464.617143,1,98,7,7,1.03,7,7,0,4,0,2,20,1,3,5,NA +71145,7,2,2,15,NA,1,1,1,15,191,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,21062.314667,21467.226385,1,94,10,10,2.94,4,4,0,2,0,2,52,1,5,2,NA +71146,7,2,1,34,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,130589.073376,141489.20172,2,102,8,6,2.57,2,1,0,0,0,1,34,1,4,5,NA +71147,7,2,2,11,NA,4,4,2,11,134,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8757.841043,8910.615224,2,100,13,13,NA,4,4,0,2,0,2,28,1,2,6,NA +71148,7,2,1,0,0,4,4,2,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6433.441277,6898.375971,2,97,1,1,0,5,5,3,0,0,2,23,1,2,1,3 +71149,7,2,1,12,NA,5,7,2,12,148,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,5504.178541,5957.59682,1,99,15,15,4.47,4,4,0,2,0,2,52,2,5,1,5 +71150,7,2,1,8,NA,4,4,2,8,100,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14125.862146,14295.209168,1,97,5,5,0.91,4,4,0,3,0,2,44,1,4,5,NA +71151,7,2,2,8,NA,4,4,1,8,102,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11334.095519,11753.9565,2,96,5,5,0.67,6,6,1,2,1,1,34,1,4,1,4 +71152,7,2,1,80,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,1,2,1,2,2,1,2,2,NA,18812.694081,19206.027387,1,102,14,14,4.59,3,3,0,0,1,2,46,1,4,1,1 +71153,7,2,2,7,NA,4,4,2,7,94,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6655.097829,7106.52929,2,99,15,15,4.9,7,7,1,4,0,2,53,1,5,1,5 +71154,7,2,2,11,NA,5,6,2,11,139,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10699.45895,11230.540406,1,97,15,15,2.33,7,7,2,4,0,2,40,2,5,1,4 +71155,7,2,1,41,NA,3,3,2,NA,NA,2,NA,2,2,5,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,117676.178911,119449.245993,2,99,14,14,5,1,1,0,0,0,1,41,2,5,5,NA +71156,7,2,2,16,NA,1,1,2,16,194,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,21120.105603,21750.292661,1,98,6,6,1.98,2,2,0,1,0,2,37,1,4,3,NA +71157,7,2,2,26,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,1,1,2,2,1,2,2,1,2,2,1,15967.106149,16195.487754,2,103,6,6,1.3,4,4,1,1,0,2,26,1,4,1,3 +71158,7,2,1,39,NA,5,6,1,NA,NA,2,NA,2,2,1,NA,5,1,NA,1,2,1,1,2,1,1,2,2,3,16939.617906,17443.653216,3,91,14,14,3.58,4,4,1,1,0,1,39,2,5,1,5 +71159,7,2,2,37,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,97101.614214,100848.484003,3,92,15,15,5,4,4,2,0,0,1,38,1,5,1,5 +71160,7,2,2,3,NA,5,6,1,3,45,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7483.230909,7475.326886,2,96,7,7,2.27,3,3,1,0,0,1,34,2,5,1,5 +71161,7,2,1,45,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,18178.365056,18317.23991,1,94,6,6,2.05,2,2,0,1,0,1,45,1,2,5,NA +71162,7,2,1,13,NA,5,7,1,13,164,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14831.338089,14976.576871,1,98,3,3,0.43,4,4,0,1,0,2,39,1,2,5,NA +71163,7,2,1,11,NA,3,3,1,11,135,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,49922.147265,52289.098209,1,98,6,6,1.11,5,5,0,2,1,2,37,1,1,1,1 +71164,7,2,1,48,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,126789.52929,129656.862785,1,101,14,14,3.25,4,4,0,1,0,1,48,1,4,1,2 +71165,7,2,2,0,4,4,4,1,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4128.726485,4546.845595,2,93,5,5,1.05,3,3,1,0,0,2,29,1,3,5,NA +71166,7,2,1,55,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,NA,32720.69734,33802.428047,1,95,2,2,0.67,1,1,0,0,0,1,55,1,3,3,NA +71167,7,2,2,19,NA,5,7,2,19,231,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,91797.787708,94488.443358,1,95,5,5,1.3,3,3,0,0,1,2,19,1,3,NA,NA +71168,7,1,1,79,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,7,1,NA,1,2,2,NA,NA,NA,NA,NA,NA,NA,74473.849242,0,2,98,NA,NA,NA,2,2,0,0,2,1,79,1,7,1,NA +71169,7,2,1,62,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,121588.761604,120347.630506,1,91,10,10,3.78,3,3,0,0,2,1,62,1,5,1,5 +71170,7,1,1,23,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,106185.516032,0,2,96,5,5,2.02,1,1,0,0,0,1,23,1,4,5,NA +71171,7,2,2,61,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,12331.419303,13281.948926,2,95,6,6,1.65,2,2,0,0,2,1,62,1,1,1,3 +71172,7,2,2,42,NA,4,4,1,NA,NA,2,NA,2,2,5,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,25774.834017,25516.02368,1,100,5,5,1.05,3,3,1,0,0,2,42,2,5,1,NA +71173,7,2,2,5,NA,1,1,1,5,69,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,1,1,2,1,NA,NA,NA,NA,13560.780585,14415.696661,2,96,3,3,0.46,5,5,1,2,0,1,37,1,1,1,2 +71174,7,2,1,11,NA,3,3,1,11,141,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,19272.757026,20113.595939,1,94,6,6,1.18,5,5,1,2,0,1,30,1,3,1,3 +71175,7,2,1,73,NA,2,2,2,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,16928.800715,17540.589716,1,90,9,9,3.97,2,2,0,0,1,1,73,1,4,1,5 +71176,7,2,1,62,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,7611.107768,7521.80097,2,97,4,4,1.47,1,1,0,0,1,1,62,1,4,3,NA +71177,7,1,2,4,NA,2,2,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10308.095307,0,2,90,14,14,3.06,5,5,1,2,0,1,42,1,4,1,5 +71178,7,2,2,4,NA,2,2,2,4,53,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10308.095307,10747.298537,2,90,3,3,0.46,5,5,3,0,0,2,22,1,2,5,NA +71179,7,1,2,32,NA,4,4,NA,NA,NA,2,NA,2,1,2,NA,5,1,3,1,2,2,1,2,2,NA,NA,NA,NA,27303.803575,0,1,96,7,7,2.23,3,3,1,0,0,1,29,2,5,1,5 +71180,7,2,1,57,NA,4,4,2,NA,NA,2,NA,2,2,2,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,12517.592486,12477.667198,1,96,10,10,1.8,7,7,1,1,0,1,57,2,1,1,3 +71181,7,2,1,19,NA,4,4,1,19,235,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,NA,NA,NA,NA,17606.165994,17558.40257,2,101,6,1,0.23,3,1,0,0,0,1,21,1,4,5,NA +71182,7,2,2,47,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,20084.755052,20500.648257,1,99,15,8,2.7,4,3,0,2,0,1,49,1,4,6,NA +71183,7,2,1,38,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,107347.639721,117795.71535,3,92,6,6,1.17,4,4,0,2,0,2,30,1,2,1,4 +71184,7,2,1,64,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,12579.986433,13271.133625,1,92,14,14,5,1,1,0,0,1,1,64,1,5,3,NA +71185,7,2,1,29,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,50647.682308,56120.478778,2,96,7,7,2.38,2,2,0,0,0,1,29,1,3,1,4 +71186,7,2,1,1,17,1,1,1,NA,18,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12493.910388,13386.323284,2,98,6,6,1.25,4,4,1,0,1,1,46,1,2,6,NA +71187,7,2,2,63,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,1,3,NA,1,2,2,1,2,2,1,2,2,1,9609.522554,10094.833809,3,91,2,2,0.72,1,1,0,0,1,2,63,1,1,3,NA +71188,7,2,2,1,14,4,4,1,NA,15,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7382.686927,7710.515686,2,100,5,5,0.94,4,4,2,0,0,2,33,1,4,6,NA +71189,7,2,1,51,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,144353.133634,150786.620773,1,94,15,15,5,3,3,0,1,0,2,43,1,5,1,5 +71190,7,2,2,12,NA,4,4,1,12,150,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12327.773112,12176.001893,2,95,1,1,0.18,4,4,2,1,0,2,38,1,2,5,NA +71191,7,2,2,15,NA,4,4,2,16,192,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11711.384457,11558.024533,2,95,8,8,1.61,6,6,1,3,0,2,48,1,3,5,NA +71192,7,2,1,1,23,2,2,2,NA,23,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13002.944731,13931.716845,2,91,9,9,2.6,4,4,1,1,0,2,31,2,4,1,5 +71193,7,2,2,7,NA,3,3,2,7,85,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,19880.837381,19616.828143,1,101,6,6,0.87,6,6,2,2,0,2,23,1,4,6,NA +71194,7,2,2,61,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,11696.973403,11982.125462,2,101,4,4,0.85,4,4,1,0,1,2,61,1,4,3,NA +71195,7,2,2,36,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,16663.714937,17273.763859,2,93,15,15,5,3,3,1,0,0,1,41,2,5,1,5 +71196,7,2,2,18,NA,5,6,1,18,223,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,1,1,2,2,1,5668.184078,5913.178809,2,92,10,8,2.01,7,4,1,1,1,2,27,2,3,1,3 +71197,7,2,1,36,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,15867.258653,16587.349339,3,91,5,5,1.07,4,4,0,2,0,2,36,1,5,1,4 +71198,7,2,2,11,NA,4,4,1,11,138,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11195.065587,11726.17681,2,96,7,7,1.33,6,6,0,3,1,1,74,1,1,1,NA +71199,7,2,2,49,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,21857.756498,23340.233721,2,97,7,7,1.92,3,3,0,1,0,1,57,1,4,1,4 +71200,7,2,1,51,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,151766.599459,151581.541662,3,91,15,15,5,1,1,0,0,0,1,51,1,5,5,NA +71201,7,2,2,57,NA,5,6,2,NA,NA,2,NA,2,2,6,NA,1,1,NA,1,2,2,1,2,2,1,2,2,1,17852.668137,18572.420627,3,91,6,6,1.77,2,2,0,0,0,2,57,2,1,1,1 +71202,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,65706.229298,75664.626338,1,101,7,7,2.64,2,2,0,0,2,1,80,1,1,1,3 +71203,7,2,2,63,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,10391.563983,10953.658293,3,90,14,14,4.96,2,2,0,0,2,1,68,1,3,1,5 +71204,7,2,2,27,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,46606.430863,46728.795934,2,102,14,14,3.25,5,5,2,0,0,1,27,1,5,1,5 +71205,7,2,2,12,NA,3,3,2,12,146,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,132630.209478,135755.422092,1,97,14,14,3.36,4,4,0,2,0,2,49,1,5,1,5 +71206,7,2,1,29,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,9938.495618,10209.075521,1,93,15,6,2.3,6,1,0,0,0,1,34,2,5,5,NA +71207,7,1,1,7,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10229.206765,0,1,96,14,14,2.96,5,5,0,3,0,1,46,NA,NA,1,5 +71208,7,2,1,32,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,16905.961576,17805.493573,2,94,10,10,4.76,2,2,0,0,0,1,32,1,5,1,5 +71209,7,2,2,2,NA,1,1,1,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,10099.930724,10530.26456,2,96,6,6,0.87,6,6,1,3,0,1,46,2,1,1,1 +71210,7,2,1,0,0,3,3,1,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12909.068713,12685.898973,2,92,1,1,0.22,3,3,1,0,0,1,22,1,4,6,NA +71211,7,2,2,32,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,23038.68441,23821.989403,1,92,6,6,1.92,2,2,0,0,0,2,33,2,4,5,NA +71212,7,2,2,65,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,1,49568.196121,50175.172049,1,101,3,3,1.24,1,1,0,0,1,2,65,1,2,2,NA +71213,7,2,2,38,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,6,2,1,2,2,1,2,2,1,2,2,1,65897.669973,68436.247366,1,99,77,77,NA,3,3,0,0,0,1,42,1,4,6,NA +71214,7,2,2,11,NA,1,1,1,11,138,NA,NA,1,1,NA,4,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,14414.529053,14932.182215,2,96,6,6,0.87,6,6,1,3,0,1,46,2,1,1,1 +71215,7,2,1,60,NA,3,3,2,NA,NA,2,NA,2,1,77,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,19328.482066,19868.466665,3,90,77,77,NA,1,1,0,0,1,1,60,2,5,5,NA +71216,7,2,1,46,NA,5,6,1,NA,NA,2,NA,2,2,5,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,20197.354438,20310.389983,2,96,8,8,3.4,2,2,0,0,0,1,46,2,4,1,4 +71217,7,2,1,28,NA,1,1,1,NA,NA,2,NA,2,7,5,NA,3,5,NA,2,2,2,2,2,2,1,2,2,1,47487.549895,48753.51505,1,102,7,7,1.89,3,3,0,0,0,1,53,2,1,1,1 +71218,7,2,1,33,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,87891.395784,92007.216086,2,99,15,15,5,1,1,0,0,0,1,33,1,5,5,NA +71219,7,2,1,60,NA,4,4,1,NA,NA,2,NA,2,1,6,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,7915.816068,7977.736071,2,93,6,6,1.13,4,4,0,0,2,1,60,2,3,1,3 +71220,7,2,1,4,NA,4,4,1,4,49,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11920.911192,13144.753907,2,96,14,14,3.58,4,4,2,0,0,1,36,1,4,1,5 +71221,7,2,1,1,20,1,1,1,NA,21,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13305.770449,13726.956753,3,92,5,5,0.68,6,6,3,0,0,2,19,1,4,NA,NA +71222,7,2,2,55,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,191547.714427,193526.009858,2,91,15,10,5,2,1,0,0,0,2,55,1,5,6,NA +71223,7,2,2,25,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,30275.274308,30320.430859,2,101,3,2,0.82,2,1,0,0,0,2,25,1,4,5,NA +71224,7,2,2,68,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,44636.780791,46200.180609,2,91,6,6,1.26,5,5,0,1,2,2,80,1,4,2,NA +71225,7,2,1,0,1,1,1,2,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,6298.658963,6412.943673,2,94,77,77,NA,4,4,2,0,0,2,27,2,3,1,3 +71226,7,2,2,0,7,3,3,1,NA,7,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7272.728291,7471.815482,1,98,13,13,NA,5,5,2,1,0,1,31,1,3,1,3 +71227,7,2,1,39,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,13209.159597,13930.540942,2,95,6,6,1.08,4,4,1,1,0,1,39,1,4,1,4 +71228,7,2,2,49,NA,1,1,2,NA,NA,2,NA,2,1,7,NA,1,1,NA,2,2,2,1,2,2,NA,NA,NA,NA,31273.071103,31436.157508,1,90,12,12,NA,5,5,0,1,0,2,49,2,1,1,NA +71229,7,2,1,48,NA,5,6,1,NA,NA,2,NA,2,2,4,NA,4,1,NA,1,2,1,1,2,1,1,2,1,3,12066.381592,12177.318898,1,103,4,4,0.82,3,3,0,0,0,1,48,2,4,1,1 +71230,7,1,1,30,NA,1,1,NA,NA,NA,2,NA,2,2,4,NA,1,1,NA,2,2,2,2,2,2,NA,NA,NA,NA,34887.439952,0,2,94,4,4,0.72,4,4,1,1,0,1,30,2,1,1,3 +71231,7,2,1,52,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,3,4,NA,1,2,2,1,2,2,1,2,2,1,17796.910402,18163.842064,1,103,2,2,0.63,1,1,0,0,0,1,52,1,3,4,NA +71232,7,2,2,55,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,32041.645327,32131.786508,1,94,2,2,0.73,1,1,0,0,0,2,55,1,3,3,NA +71233,7,2,1,6,NA,4,4,1,6,73,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12267.215138,12511.113657,2,102,2,2,0.36,4,4,1,2,0,2,36,1,3,5,NA +71234,7,2,2,47,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,154825.466557,157902.106304,1,91,7,7,2.92,2,2,0,0,1,2,47,1,5,5,NA +71235,7,2,1,9,NA,3,3,1,9,115,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,38712.032122,41122.784973,3,91,15,15,5,6,6,1,3,0,2,40,1,5,1,5 +71236,7,2,2,2,NA,4,4,2,2,26,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7338.212404,7527.624117,1,93,7,7,2.16,3,3,1,0,0,2,28,2,2,1,5 +71237,7,2,2,43,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,2,1,2,2,1,2,2,NA,NA,NA,NA,35469.911999,36868.395052,2,91,12,13,NA,3,1,0,0,1,1,52,1,4,3,NA +71238,7,2,2,53,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,20186.483875,20343.011032,1,99,13,13,NA,4,4,0,2,0,1,55,NA,NA,1,4 +71239,7,2,1,48,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,1,148090.195644,148420.972197,1,98,5,5,1.79,1,1,0,0,0,1,48,1,1,2,NA +71240,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,6512.729795,7017.196255,1,93,2,2,0.69,1,1,0,0,1,1,80,1,5,2,NA +71241,7,2,2,0,9,4,4,2,NA,10,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4588.59937,4638.701468,2,95,10,10,3.82,3,3,1,0,0,1,25,1,4,1,4 +71242,7,2,1,48,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,19436.026093,19746.342802,2,97,9,9,1.45,7,7,1,2,2,2,45,1,3,5,NA +71243,7,2,1,17,NA,4,4,1,18,216,2,NA,2,1,5,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,19163.050164,19648.623212,2,102,14,14,4.48,3,3,0,2,0,1,41,1,3,4,NA +71244,7,2,2,64,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,118437.327505,122585.585802,1,90,15,15,5,1,1,0,0,1,2,64,1,5,3,NA +71245,7,2,1,62,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,7654.035132,8195.014907,3,90,9,9,2.6,4,4,0,0,1,1,62,2,4,1,5 +71246,7,2,1,14,NA,1,1,1,14,178,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,23389.620035,24913.232835,1,91,14,14,3.9,4,4,0,1,0,1,41,1,2,1,4 +71247,7,2,1,13,NA,4,4,1,13,162,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,NA,NA,NA,1,2,2,1,14650.502937,14679.468181,2,102,14,14,3.25,5,5,1,1,0,2,32,1,4,1,3 +71248,7,2,1,4,NA,5,6,1,4,49,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10123.286306,10422.822776,1,100,15,15,5,3,3,1,0,0,2,28,2,5,1,5 +71249,7,2,1,24,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,17420.978407,17335.115714,2,97,3,3,0.82,2,2,0,0,0,1,24,1,3,5,NA +71250,7,2,1,39,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,1,6,NA,1,2,2,1,2,2,1,2,2,1,20486.987447,22351.0228,2,101,3,1,0,4,1,0,2,0,1,39,1,1,6,NA +71251,7,1,1,60,NA,4,4,NA,NA,NA,2,NA,2,1,99,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,12848.137255,0,1,101,15,15,5,2,2,0,0,2,1,60,2,5,1,NA +71252,7,2,2,41,NA,2,2,2,NA,NA,2,NA,2,2,6,NA,4,1,2,2,2,2,1,2,2,1,2,2,2,25778.164795,25912.595732,2,90,2,2,0.25,5,5,0,1,0,2,41,2,4,1,NA +71253,7,1,2,47,NA,3,3,NA,NA,NA,2,NA,2,1,6,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,125799.478905,0,1,100,15,15,4.63,5,5,0,0,0,1,51,1,5,1,3 +71254,7,2,2,50,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,10964.859884,13217.672684,3,90,77,77,NA,3,3,0,1,0,1,54,2,3,1,3 +71255,7,2,2,2,NA,3,3,1,2,35,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14950.402914,15888.087777,1,102,5,1,0.21,5,4,1,1,0,2,24,1,4,5,NA +71256,7,2,2,7,NA,4,4,2,7,94,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7428.928475,8424.338415,3,91,1,1,0.07,6,6,2,3,0,2,30,1,2,3,NA +71257,7,2,1,7,NA,4,4,1,7,90,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8714.559478,8887.823591,2,96,7,7,1.04,7,7,0,4,0,2,37,1,3,3,NA +71258,7,2,2,19,NA,2,2,2,19,232,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,15442.648697,17482.235263,3,90,10,8,4.3,2,1,0,0,0,1,33,1,3,6,NA +71259,7,2,2,23,NA,5,6,2,NA,NA,1,2,1,1,NA,NA,3,5,2,1,2,2,1,2,2,1,2,2,1,16844.740449,19586.242825,3,91,99,1,0.28,3,1,0,0,0,2,23,1,3,5,NA +71260,7,2,2,14,NA,1,1,1,14,171,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,20347.899985,21072.708732,3,92,15,15,3.15,7,7,0,4,0,2,35,2,3,3,NA +71261,7,2,2,50,NA,2,2,1,NA,NA,2,NA,2,1,3,NA,1,5,NA,2,2,2,1,2,2,1,2,2,2,24004.6026,24129.784561,2,91,6,6,0.93,5,5,1,2,0,2,50,2,1,5,NA +71262,7,2,1,15,NA,3,3,2,15,181,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,61479.689958,61628.148021,2,100,15,15,4.5,6,6,0,4,0,1,45,1,5,1,5 +71263,7,2,1,47,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,22685.373982,23664.393091,1,98,1,1,0,4,4,0,3,0,1,47,1,5,3,NA +71264,7,2,2,20,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,NA,NA,NA,NA,30253.427014,30121.660039,2,90,15,15,4.2,5,5,1,0,0,2,50,NA,NA,6,NA +71265,7,2,2,15,NA,4,4,2,15,187,NA,NA,1,1,NA,10,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7825.55935,7975.961244,3,90,15,15,5,5,5,0,1,1,2,61,1,5,2,NA +71266,7,2,2,68,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,117131.838201,119452.245796,1,94,14,14,5,2,2,0,0,2,1,74,1,4,1,4 +71267,7,2,2,41,NA,5,6,1,NA,NA,2,NA,2,1,3,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,20001.392001,20614.835005,1,100,8,8,2.62,3,3,0,1,0,1,41,2,5,1,5 +71268,7,2,1,5,NA,3,3,2,5,65,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,26500.001625,29898.299515,2,91,7,7,1.29,6,6,2,2,0,1,33,2,3,6,NA +71269,7,1,1,33,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,12556.207754,0,2,99,13,13,NA,6,6,2,1,0,2,31,1,4,6,NA +71270,7,2,2,15,NA,2,2,2,15,185,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17381.663677,18792.085501,1,90,7,7,2.1,3,3,0,2,0,2,37,1,3,5,NA +71271,7,2,1,57,NA,1,1,1,NA,NA,2,NA,2,2,3,NA,1,1,NA,2,2,2,1,2,2,2,2,2,2,31872.125984,31404.451666,2,96,6,6,1.12,4,4,0,1,0,1,57,2,1,1,4 +71272,7,2,1,30,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,77440.662578,92128.223811,2,93,8,8,3.3,2,2,0,0,0,2,26,1,4,1,5 +71273,7,2,1,11,NA,1,1,1,11,135,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13927.458372,13933.628196,2,98,6,6,1.9,2,2,0,1,0,2,34,1,4,3,NA +71274,7,2,2,28,NA,1,1,2,NA,NA,2,NA,1,1,NA,NA,5,6,2,1,2,2,1,2,2,1,2,2,1,49473.624024,50829.110777,3,91,14,14,5,2,2,0,0,0,1,32,1,4,6,NA +71275,7,2,2,12,NA,4,4,1,12,148,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,20473.346601,20523.769333,2,102,15,15,3.82,5,5,1,2,0,1,34,1,3,1,4 +71276,7,2,2,0,5,3,3,2,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,17070.097848,16606.436082,1,101,7,7,1.79,4,4,1,0,0,2,30,1,4,1,4 +71277,7,2,2,4,NA,1,1,1,4,52,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15457.736897,17065.756351,2,98,2,2,0.27,4,4,2,1,0,2,32,2,2,5,NA +71278,7,2,1,69,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,7101.739553,7379.502561,1,96,99,99,NA,1,1,0,0,1,1,69,1,2,1,NA +71279,7,2,1,40,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,27356.080541,27285.808403,1,98,6,6,1.11,5,5,1,2,0,2,32,1,2,1,2 +71280,7,2,2,23,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,6,2,1,2,2,1,2,2,1,2,2,1,95778.224595,101717.815372,1,98,8,8,2.46,3,3,1,0,0,1,29,1,4,6,NA +71281,7,2,1,2,NA,4,4,2,3,36,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7667.509064,7761.032365,2,91,2,2,0.41,3,3,1,1,0,2,30,1,3,5,NA +71282,7,2,2,25,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,12426.473257,13266.565637,2,92,14,7,3.4,2,1,0,0,0,1,26,NA,NA,5,NA +71283,7,2,2,0,1,2,2,1,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,8168.833251,8141.91987,2,91,5,5,1.05,3,3,2,0,0,2,26,2,3,4,NA +71284,7,2,2,64,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,10049.7347,10691.470743,2,90,2,2,0.67,2,2,0,0,1,2,64,1,5,5,NA +71285,7,2,1,10,NA,1,1,1,10,125,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13927.458372,14258.502552,2,98,5,5,1.07,4,4,0,1,0,1,52,2,1,1,3 +71286,7,2,2,56,NA,2,2,1,NA,NA,2,NA,2,1,8,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,22969.116046,23497.145655,2,93,6,6,2.69,1,1,0,0,0,2,56,2,4,3,NA +71287,7,1,2,3,NA,3,3,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,26966.264969,0,1,98,4,4,0.66,4,4,2,0,0,2,22,1,4,6,NA +71288,7,2,1,68,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,140586.349952,144513.945685,2,91,15,15,5,2,2,0,0,2,1,68,1,5,1,5 +71289,7,2,2,32,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,2,1,2,2,1,2,2,1,2,2,1,27375.405353,27906.494528,1,94,5,5,0.95,4,4,1,2,0,2,32,1,4,3,NA +71290,7,2,2,10,NA,2,2,2,10,127,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12737.089292,13281.887291,1,94,14,14,3.4,5,5,0,3,0,2,41,1,4,1,4 +71291,7,2,1,50,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,4,NA,1,2,2,1,2,2,1,2,2,1,182279.501656,183739.903765,1,100,6,6,1.98,2,2,0,0,0,1,50,1,5,4,NA +71292,7,2,2,36,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,28747.860416,30448.398533,1,99,10,10,3.13,4,4,0,2,0,1,35,1,4,1,5 +71293,7,2,1,3,NA,2,2,2,3,41,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,13353.801759,13870.061432,1,93,6,6,0.99,5,5,1,0,0,1,28,2,2,5,NA +71294,7,2,1,16,NA,4,4,1,16,201,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,19163.050164,19648.623212,2,102,14,14,4.48,3,3,0,2,0,1,41,1,3,4,NA +71295,7,2,1,25,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,110218.970616,129453.540645,1,93,7,7,3.21,1,1,0,0,0,1,25,1,4,5,NA +71296,7,2,2,32,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,6,2,1,2,2,1,2,2,1,2,2,1,27367.658704,28808.672115,1,91,4,4,0.81,4,4,1,1,0,1,32,1,4,6,NA +71297,7,2,1,19,NA,4,4,1,19,230,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12147.046136,12703.852077,2,100,4,4,0.91,3,3,0,0,0,2,49,1,2,1,2 +71298,7,2,2,7,NA,5,6,2,7,90,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10699.45895,11403.206057,1,97,14,14,2.29,7,7,1,2,2,1,40,2,1,1,1 +71299,7,2,1,2,NA,4,4,1,2,26,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10232.679671,11283.202594,2,101,4,4,1.22,2,2,1,0,0,2,25,1,4,5,NA +71300,7,2,2,35,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,12381.032047,12845.540957,1,102,15,15,4.59,4,4,1,1,0,1,35,1,5,1,5 +71301,7,2,2,24,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,NA,NA,NA,NA,44417.237618,45651.906489,1,102,1,1,0.24,3,2,0,0,1,2,50,1,3,3,NA +71302,7,2,2,56,NA,4,4,1,NA,NA,2,NA,2,2,6,NA,3,4,NA,1,2,2,1,2,2,1,2,2,1,18146.994087,18265.36374,2,93,4,4,1.29,2,2,0,1,0,2,56,2,3,4,NA +71303,7,2,2,4,NA,4,4,1,4,50,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9707.610673,10138.677842,2,93,5,5,0.92,4,4,1,1,0,1,27,2,2,5,NA +71304,7,2,1,1,19,1,1,2,NA,19,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,11972.170914,12351.142913,1,97,8,8,1.45,6,6,2,2,0,2,36,2,2,1,1 +71305,7,2,1,7,NA,1,1,1,7,89,NA,NA,1,1,NA,0,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,14820.807433,15055.338709,2,102,7,7,1.89,3,3,0,1,0,1,41,2,2,6,NA +71306,7,2,2,52,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,12441.719186,12605.354834,2,100,15,15,5,3,3,0,1,0,1,58,2,5,1,5 +71307,7,2,1,58,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,132969.642582,132807.505002,2,91,5,5,1.39,2,2,0,0,0,1,58,1,4,3,NA +71308,7,2,2,69,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,1,1,NA,1,2,2,1,2,2,1,2,2,1,8493.33267,8821.144988,3,91,7,7,1.33,6,6,0,0,2,2,51,2,5,1,5 +71309,7,2,2,59,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,NA,25964.813959,27606.791932,2,101,NA,77,NA,2,1,0,0,0,1,55,1,2,3,NA +71310,7,2,2,67,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,11879.290971,12409.688606,2,96,6,6,2.04,2,2,0,0,1,2,67,1,4,2,NA +71311,7,2,2,80,NA,2,2,1,NA,NA,2,NA,2,1,9,NA,2,1,NA,2,2,2,1,2,2,2,2,2,NA,21810.940874,23452.513609,2,93,8,8,2.17,4,4,0,0,3,1,80,2,2,1,2 +71312,7,2,2,52,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,15521.115746,15214.43631,2,100,8,8,2.67,3,3,0,0,1,1,61,1,3,1,4 +71313,7,2,1,52,NA,4,4,2,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,19374.410926,19463.695548,1,96,77,77,NA,4,4,0,0,0,1,52,2,5,1,5 +71314,7,2,1,51,NA,1,1,1,NA,NA,2,NA,2,1,7,NA,1,1,NA,2,2,2,1,2,2,2,2,2,2,30839.213846,30386.695922,1,92,4,4,0.74,4,4,1,1,0,1,51,2,1,1,1 +71315,7,2,1,44,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,1,105141.812429,112387.793787,1,98,6,6,1.11,5,5,0,2,1,2,37,1,1,1,1 +71316,7,2,1,57,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,100418.893093,106630.269812,2,100,10,10,3.13,4,4,0,0,1,2,53,1,2,1,2 +71317,7,2,1,0,1,4,4,2,NA,2,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5848.582979,6109.207769,2,97,4,4,0.57,5,5,1,3,0,2,33,1,3,5,NA +71318,7,2,2,2,NA,4,4,1,2,30,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6984.912286,7371.360851,2,93,10,10,2.26,6,6,2,0,0,1,34,1,4,1,4 +71319,7,2,2,2,NA,3,3,2,3,36,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,33502.281129,33942.512387,1,91,15,15,5,4,4,1,1,0,1,29,1,4,6,NA +71320,7,1,1,2,NA,5,6,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,10273.602479,0,1,92,12,12,NA,4,4,1,1,0,1,33,2,4,1,4 +71321,7,2,2,54,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,4,NA,1,2,2,1,2,2,1,2,2,1,24713.281483,24036.937705,1,92,14,14,4.96,2,2,0,0,0,1,25,1,4,5,NA +71322,7,2,2,21,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,20949.647122,21006.826162,2,91,4,4,0.84,3,3,1,0,0,2,21,1,4,1,2 +71323,7,2,1,9,NA,5,6,2,9,117,NA,NA,2,2,1,3,NA,NA,NA,1,1,1,1,2,1,1,2,2,1,5855.595238,6345.238788,1,91,14,14,4.32,3,3,0,2,0,2,37,2,5,1,NA +71324,7,2,1,35,NA,2,2,2,NA,NA,2,NA,2,2,5,NA,1,1,NA,2,2,2,1,2,2,2,2,2,2,38923.140296,40970.697433,1,93,9,9,2.46,4,4,0,2,0,1,35,2,1,1,1 +71325,7,2,2,3,NA,3,3,2,3,42,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,24600.429016,26143.360672,1,91,6,6,1.07,6,6,3,1,0,2,27,1,4,6,NA +71326,7,2,1,6,NA,4,4,2,7,84,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8655.162127,8668.652185,2,95,6,6,0.86,6,6,0,4,0,2,32,1,4,6,NA +71327,7,2,1,3,NA,1,1,1,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,16775.083123,16797.750213,2,98,2,2,0.27,4,4,2,0,0,2,20,2,2,6,NA +71328,7,2,2,54,NA,2,2,1,NA,NA,2,NA,2,1,4,NA,4,3,NA,2,2,2,1,2,2,2,2,2,2,26226.50904,26977.257389,2,93,7,7,1.74,4,4,1,0,1,2,24,NA,NA,4,NA +71329,7,2,1,8,NA,3,3,2,8,100,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,63513.013195,68899.034203,2,101,7,7,1.57,4,4,0,2,0,2,28,1,3,6,NA +71330,7,2,1,39,NA,5,6,1,NA,NA,2,NA,2,1,3,NA,3,1,NA,1,2,1,1,2,1,1,2,1,3,9585.652672,9712.791327,2,92,10,6,1.12,7,4,1,1,1,2,27,2,3,1,3 +71331,7,2,2,0,10,1,1,1,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,9767.083234,9561.595244,3,92,10,10,2.82,4,4,2,0,0,1,26,2,3,1,3 +71332,7,2,2,10,NA,1,1,1,10,129,NA,NA,1,1,NA,4,NA,NA,NA,2,1,1,1,2,1,1,2,2,1,20495.125801,20710.596821,3,92,6,6,0.96,5,5,2,1,0,2,26,2,1,1,1 +71333,7,2,2,30,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,52521.960331,51104.807504,1,92,10,10,4.63,2,2,0,0,0,1,35,2,5,1,4 +71334,7,2,1,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,15682.233511,17550.107712,1,98,6,6,1.9,2,2,0,0,2,1,80,1,1,1,2 +71335,7,1,1,61,NA,2,2,NA,NA,NA,2,NA,2,1,6,NA,1,1,NA,2,2,2,2,2,2,NA,NA,NA,NA,6449.12882,0,2,93,77,77,NA,3,3,0,0,3,1,61,2,1,1,1 +71336,7,2,1,45,NA,5,6,1,NA,NA,2,NA,2,1,8,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,14695.245859,15160.543049,2,92,15,15,5,3,3,0,1,0,1,45,2,4,1,4 +71337,7,2,1,7,NA,3,3,2,7,87,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,64268.100156,67147.933534,1,98,15,15,4.07,5,5,0,3,0,1,38,1,2,1,4 +71338,7,2,2,8,NA,4,4,1,8,106,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11195.065587,11638.702248,2,96,2,2,0.43,3,3,0,2,0,2,50,1,2,5,NA +71339,7,2,2,69,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,39030.893313,39804.103933,1,91,5,5,1.2,3,3,0,0,1,1,58,1,2,1,2 +71340,7,2,2,36,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,3,2,1,2,2,1,2,2,1,2,2,1,24919.497762,26574.647337,1,95,5,5,1.1,3,3,0,0,1,2,63,1,4,1,5 +71341,7,2,1,58,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,14897.510053,14959.811939,1,101,15,15,5,3,3,0,0,1,1,58,2,4,1,5 +71342,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,46965.818538,52174.805072,1,101,7,7,2.64,2,2,0,0,2,1,80,1,1,1,3 +71343,7,2,2,29,NA,3,3,2,NA,NA,2,NA,2,1,6,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,105134.853452,122679.602456,2,99,14,14,5,1,1,0,0,0,2,29,2,5,5,NA +71344,7,2,1,65,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,28953.774534,29107.622897,1,98,4,4,1,3,3,0,1,1,1,65,1,2,1,NA +71345,7,1,1,60,NA,1,1,NA,NA,NA,2,NA,2,2,77,NA,2,1,NA,2,2,2,2,2,2,NA,NA,NA,NA,12845.115724,0,1,100,4,4,0.78,4,4,0,0,1,1,33,2,1,1,1 +71346,7,2,2,74,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,NA,44856.466004,46390.551109,2,94,12,9,5,2,1,0,0,1,2,74,1,5,3,NA +71347,7,2,1,53,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,32461.799549,32422.216998,1,95,6,2,0.81,2,1,0,0,0,1,53,1,2,6,NA +71348,7,2,1,56,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,25118.469449,26051.81361,2,98,6,6,1.4,3,3,0,1,0,1,56,1,2,1,2 +71349,7,1,1,78,NA,5,6,NA,NA,NA,2,NA,2,1,6,NA,1,2,NA,1,2,1,1,2,2,NA,NA,NA,NA,9748.579573,0,3,90,8,8,1.85,5,5,0,0,1,2,25,1,5,5,NA +71350,7,2,2,6,NA,4,4,2,6,76,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9502.76472,9802.874785,1,96,3,3,0.93,2,2,0,1,0,2,40,1,5,5,NA +71351,7,2,2,52,NA,5,6,1,NA,NA,2,NA,2,1,8,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,11876.875273,12162.823626,2,103,15,15,5,3,3,0,0,0,2,52,2,4,1,5 +71352,7,2,2,10,NA,5,6,2,10,130,NA,NA,2,1,3,3,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9227.090107,9685.088635,2,100,5,5,0.89,4,4,0,1,0,2,40,2,3,1,3 +71353,7,2,2,76,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,36067.495928,37024.300659,1,95,3,3,1.29,1,1,0,0,1,2,76,1,3,2,NA +71354,7,2,1,50,NA,1,1,1,NA,NA,1,1,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,37557.946192,37666.079092,2,102,7,7,3.49,4,1,0,0,1,1,63,NA,NA,5,NA +71355,7,2,2,20,NA,5,6,1,NA,NA,2,NA,2,1,4,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,16026.446928,16774.880842,1,94,14,14,2.78,6,5,0,2,1,1,61,1,4,1,5 +71356,7,2,1,63,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,129867.826953,131085.811251,1,101,9,9,2.6,4,4,0,1,2,2,63,1,4,1,4 +71357,7,2,1,29,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,15408.94893,15333.002917,1,99,7,7,2.38,2,2,0,0,0,2,27,1,5,1,5 +71358,7,2,2,1,22,2,2,1,NA,23,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,2,2,2,NA,NA,NA,NA,7815.664341,8308.38945,2,103,5,5,0.65,6,6,1,0,1,2,61,2,1,2,NA +71359,7,2,1,41,NA,2,2,2,NA,NA,2,NA,2,7,77,NA,1,1,NA,2,2,2,2,2,2,NA,NA,NA,NA,31640.296506,33247.715312,2,94,1,1,0.01,7,7,1,3,0,1,41,2,1,1,1 +71360,7,2,2,25,NA,1,1,2,NA,NA,2,NA,2,2,3,NA,2,1,2,2,2,2,2,2,2,NA,NA,NA,NA,39426.061521,43773.817687,2,94,4,4,0.81,4,4,2,0,0,1,26,2,2,1,2 +71361,7,2,2,55,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,17852.668137,17947.072019,3,91,7,7,2.58,2,2,0,0,0,2,55,2,5,3,NA +71362,7,2,1,23,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,25815.880139,26503.609729,2,101,2,1,0.05,2,1,0,0,0,1,24,1,4,5,NA +71363,7,2,2,30,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,5,5,2,1,2,2,NA,NA,NA,1,2,2,1,16165.066826,16696.869727,2,96,NA,NA,NA,4,4,0,0,1,1,67,2,3,1,2 +71364,7,2,1,13,NA,4,4,1,13,157,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11666.009872,12200.765691,2,100,14,4,0.43,7,7,1,3,1,2,62,1,3,5,NA +71365,7,2,1,22,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,21763.209029,22385.504537,2,92,4,4,1.38,4,1,0,0,0,1,21,1,4,5,NA +71366,7,2,2,20,NA,3,3,1,NA,NA,2,NA,2,2,2,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,114492.825466,119073.624167,2,101,3,1,0.06,3,1,0,0,0,2,20,2,4,5,NA +71367,7,2,1,7,NA,2,2,1,7,91,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13533.281742,13475.903543,1,100,10,10,2.91,4,4,1,1,0,1,32,1,5,1,5 +71368,7,2,1,35,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,82363.088109,88909.58429,1,90,14,14,3.93,3,3,1,0,0,1,35,1,2,1,5 +71369,7,2,2,3,NA,5,6,2,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,3842.794137,4026.588867,1,93,6,6,1.15,5,5,1,0,2,2,70,NA,NA,1,NA +71370,7,2,1,9,NA,3,3,2,9,114,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,21087.869274,22686.932895,1,101,1,1,0.1,4,4,1,1,0,2,52,1,4,3,NA +71371,7,2,2,63,NA,5,7,2,NA,NA,2,NA,2,1,7,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,28759.144922,29766.431764,3,90,7,7,2.51,2,2,0,0,2,1,62,2,3,1,4 +71372,7,2,1,37,NA,1,1,1,NA,NA,2,NA,2,2,5,NA,1,6,NA,2,2,2,2,2,2,2,2,2,2,51543.062078,51154.050295,3,92,3,3,0.51,5,5,1,2,0,2,34,2,1,6,NA +71373,7,2,1,1,15,1,1,1,NA,15,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,9925.934568,9762.398236,2,92,5,5,1.08,3,3,1,0,0,2,30,2,3,1,2 +71374,7,2,2,52,NA,5,6,1,NA,NA,2,NA,2,2,5,NA,4,4,NA,1,2,2,1,2,2,1,2,2,1,12059.495297,12169.751033,1,102,15,15,3.82,5,5,1,1,0,1,29,1,4,1,4 +71375,7,2,1,73,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,70819.746399,73506.573727,1,98,6,6,1.98,2,2,0,0,2,2,70,1,4,1,5 +71376,7,2,1,3,NA,1,1,1,3,39,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,18754.85406,20094.472571,2,102,14,14,3.8,4,4,2,0,0,2,41,2,4,1,5 +71377,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,27199.141352,28737.286192,1,98,77,77,NA,2,2,0,0,2,1,80,1,5,1,5 +71378,7,2,1,5,NA,3,3,2,6,72,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,39061.897809,44649.899401,1,95,15,15,3.62,7,7,2,4,0,1,59,1,5,1,2 +71379,7,2,2,60,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,27351.473517,27893.312251,2,94,2,2,0.83,1,1,0,0,1,2,60,1,5,5,NA +71380,7,1,2,80,NA,4,4,NA,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,15914.916287,0,2,99,5,5,1.59,2,2,0,0,1,2,80,1,3,2,NA +71381,7,2,1,48,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,4,1,NA,1,2,2,1,2,2,1,2,2,3,12765.378725,13670.003215,2,90,14,14,4.32,3,3,0,1,0,1,48,2,4,1,5 +71382,7,2,2,80,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,54095.581484,61529.339683,2,94,9,9,3.97,2,2,0,0,2,1,80,1,5,1,5 +71383,7,2,2,3,NA,5,6,2,3,46,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,1,1,2,2,NA,NA,NA,NA,5060.292252,5371.954509,1,90,8,8,1.43,7,7,2,0,0,1,23,2,4,1,3 +71384,7,2,2,7,NA,1,1,1,7,91,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15962.145468,16285.000268,3,92,7,7,1.49,5,5,0,2,1,2,62,1,4,2,NA +71385,7,2,2,6,NA,3,3,2,6,76,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,28723.999699,28637.704803,1,97,6,6,1.03,6,6,2,2,0,2,38,1,5,1,4 +71386,7,2,2,1,23,1,1,1,NA,24,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14326.094268,14518.763259,3,92,14,14,3.47,4,4,1,1,0,1,44,1,3,1,5 +71387,7,2,2,3,NA,4,4,1,3,44,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10437.988787,11378.89676,2,97,NA,99,NA,7,6,2,1,1,2,56,1,3,5,NA +71388,7,2,1,42,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,49060.272708,48340.388834,1,92,7,7,1.48,5,5,0,1,0,1,42,1,5,1,4 +71389,7,2,2,1,21,2,2,1,NA,22,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11443.671453,12634.120381,1,100,15,15,4.34,4,4,2,0,0,2,35,1,5,1,5 +71390,7,2,1,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,30626.145273,33111.125584,2,103,7,7,2.64,2,2,0,0,1,1,54,1,5,5,NA +71391,7,2,1,11,NA,3,3,1,11,137,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,38712.032122,41122.784973,3,91,15,15,5,6,6,1,3,0,2,40,1,5,1,5 +71392,7,2,2,43,NA,2,2,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,35485.230645,37305.51435,1,94,7,7,1.74,4,4,0,2,0,1,44,1,5,1,5 +71393,7,2,1,27,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,108410.783716,113500.095101,1,91,15,7,3.58,3,1,0,0,0,1,27,1,3,6,NA +71394,7,1,1,78,NA,5,6,NA,NA,NA,2,NA,2,1,5,NA,3,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,12320.168636,0,2,92,4,4,1.09,2,2,0,0,2,1,78,2,3,1,NA +71395,7,2,1,30,NA,2,2,2,NA,NA,2,NA,2,2,6,NA,1,4,NA,2,2,2,2,2,2,2,2,2,2,27605.196104,27396.850962,2,99,12,7,3.31,5,1,0,1,0,1,30,2,2,4,NA +71396,7,2,2,3,NA,4,4,2,3,37,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10936.097083,12221.030117,2,95,2,2,0.42,3,3,2,0,0,1,25,1,3,5,NA +71397,7,2,1,24,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,4,4,NA,1,2,2,1,2,2,1,2,2,1,23484.626749,26526.417464,2,96,14,14,5,1,1,0,0,0,1,24,1,4,4,NA +71398,7,2,1,13,NA,4,4,2,13,167,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11788.330261,12582.159913,2,95,6,6,0.97,6,6,2,2,0,1,37,1,3,1,4 +71399,7,2,1,55,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,103893.364631,104494.238956,2,95,9,9,2.22,5,5,1,0,0,1,55,1,4,1,5 +71400,7,1,1,18,NA,5,6,NA,NA,NA,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,NA,NA,NA,NA,7669.677276,0,2,95,3,3,0.99,2,2,0,0,0,1,18,1,3,NA,NA +71401,7,2,2,54,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,31785.728924,32871.467684,1,101,4,4,1.22,2,2,0,0,1,1,63,1,2,1,2 +71402,7,2,1,0,3,3,3,2,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,21055.122405,20691.125102,1,93,15,15,4.47,4,4,2,0,0,1,31,1,5,1,5 +71403,7,2,2,30,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,31335.13799,31552.004994,1,95,5,5,0.92,5,5,1,2,0,2,30,1,4,1,4 +71404,7,2,1,18,NA,4,4,1,18,219,2,NA,1,1,NA,66,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13276.485807,15665.287637,2,100,99,99,NA,3,3,0,0,0,1,46,1,9,3,NA +71405,7,2,1,63,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,6910.118936,7233.371983,2,95,4,4,1.77,1,1,0,0,1,1,63,1,2,3,NA +71406,7,2,2,8,NA,4,4,1,8,106,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8558.832746,8898.001102,2,96,3,3,0.38,5,5,1,2,0,2,30,1,3,5,NA +71407,7,2,2,49,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,20418.635225,20918.390367,2,95,14,14,5,2,2,0,0,0,1,44,1,3,1,4 +71408,7,2,2,19,NA,2,2,2,19,238,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,NA,NA,NA,NA,16995.403684,17639.03984,2,97,2,2,0.27,3,3,2,0,0,2,19,1,3,NA,NA +71409,7,2,1,41,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,116464.874823,116165.700541,2,94,14,14,2.83,6,6,0,4,0,2,38,1,2,1,2 +71410,7,2,2,15,NA,3,3,2,15,182,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,103007.696238,104941.393061,1,101,15,15,5,4,4,0,2,0,1,43,1,4,1,5 +71411,7,2,1,8,NA,4,4,1,8,103,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,NA,9261.557132,9782.87535,2,100,1,1,0.08,5,5,1,2,0,2,19,1,3,NA,NA +71412,7,2,2,35,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,35269.9609,35902.08788,2,96,14,14,3.58,4,4,2,0,0,1,36,1,4,1,5 +71413,7,2,1,40,NA,2,2,1,NA,NA,2,NA,2,2,77,NA,4,6,NA,2,2,2,1,2,2,1,2,2,2,28726.575428,28964.259011,2,100,3,3,0.76,3,3,1,0,0,2,31,2,1,6,NA +71414,7,2,1,17,NA,1,1,1,17,213,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,24228.858782,24355.020132,2,102,77,77,NA,4,4,0,1,0,1,47,1,2,1,3 +71415,7,2,1,38,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,78529.577822,86568.047729,1,98,7,7,1,7,7,2,2,0,2,34,1,4,3,NA +71416,7,2,2,39,NA,5,6,1,NA,NA,2,NA,2,2,4,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,16411.593279,16445.104385,2,103,15,15,5,2,2,0,0,0,2,39,2,5,5,NA +71417,7,2,1,64,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,12279.19827,12375.250021,2,102,6,6,2.04,2,2,0,0,1,1,64,1,3,1,4 +71418,7,2,2,7,NA,5,6,2,7,90,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10699.45895,11230.540406,1,97,15,15,4.77,4,4,1,1,0,2,40,1,5,1,5 +71419,7,2,2,37,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,NA,NA,NA,NA,74517.751389,77393.175383,2,94,15,15,4.59,4,4,1,1,0,2,37,1,5,1,5 +71420,7,2,2,54,NA,1,1,2,NA,NA,2,NA,2,1,6,NA,2,1,NA,2,2,2,1,2,2,2,2,2,2,23953.14388,24078.057488,1,90,12,12,NA,4,4,0,0,0,1,54,2,4,1,2 +71421,7,2,1,3,NA,3,3,1,3,46,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,32621.433667,37288.094364,2,101,3,3,0.3,7,7,1,2,0,2,50,1,2,4,NA +71422,7,2,2,37,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,77778.949308,80709.488833,1,101,14,14,4.21,4,4,1,1,0,2,37,1,5,1,5 +71423,7,2,1,27,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,12540.575493,12881.998163,2,94,77,77,NA,6,6,2,0,0,2,18,1,3,NA,NA +71424,7,2,1,19,NA,3,3,1,19,236,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,110478.18082,109645.964567,2,101,1,1,0.09,2,1,0,0,0,1,19,1,4,NA,NA +71425,7,2,2,13,NA,3,3,2,13,167,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,35589.982806,42898.287648,1,101,6,6,1.31,3,3,0,2,0,1,43,1,3,4,NA +71426,7,2,1,3,NA,4,4,1,3,45,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9016.053035,9035.668246,2,100,3,3,0.31,7,7,3,2,0,2,28,1,3,1,3 +71427,7,2,2,39,NA,5,6,1,NA,NA,2,NA,2,2,1,NA,5,1,2,1,2,1,1,2,1,NA,NA,NA,NA,15951.963269,17051.924396,3,91,14,14,3.58,4,4,1,1,0,1,39,2,5,1,5 +71428,7,2,1,35,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,99741.609501,104268.100538,1,94,6,6,1.57,3,3,0,1,0,2,28,1,4,1,4 +71429,7,2,2,9,NA,4,4,2,9,111,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8579.490652,8729.153641,2,97,3,3,0.4,6,6,2,3,0,2,25,1,2,5,NA +71430,7,2,2,65,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,1,10468.473646,11728.156896,2,90,7,7,1.61,4,4,1,1,1,2,65,1,3,2,NA +71431,7,2,2,2,NA,4,4,1,2,32,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7382.686927,8048.181894,2,100,3,3,0.27,7,7,2,1,0,2,41,1,2,5,NA +71432,7,2,2,13,NA,1,1,1,13,158,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,19329.26314,19883.967368,1,103,14,14,2.96,5,5,1,2,0,1,34,1,4,1,5 +71433,7,2,1,33,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,19020.83925,19736.003798,2,99,6,6,1.13,4,4,1,1,0,1,33,1,3,6,NA +71434,7,2,1,17,NA,5,6,2,17,214,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,9202.202094,9789.088627,1,90,15,15,5,5,5,0,2,0,1,47,2,5,1,5 +71435,7,2,1,4,NA,5,6,2,4,49,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6564.381324,7362.671865,2,90,77,77,NA,4,3,1,0,0,2,30,2,2,5,NA +71436,7,2,2,60,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,11355.3308,11862.334174,1,96,9,9,4.13,2,2,0,0,1,2,55,1,4,5,NA +71437,7,1,2,3,NA,4,4,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,9707.610673,0,2,93,1,1,0.2,2,2,1,0,0,2,33,2,3,5,NA +71438,7,2,2,70,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,13549.492282,14020.967918,2,93,12,12,NA,4,4,0,0,2,1,72,1,2,1,4 +71439,7,2,2,3,NA,3,3,2,3,45,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,64475.568487,69419.338511,1,91,14,14,2.44,7,7,2,4,0,1,33,1,5,1,5 +71440,7,2,1,10,NA,1,1,1,10,124,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12665.770043,13116.669484,1,100,9,9,2.02,6,6,0,3,1,2,39,1,4,1,5 +71441,7,2,2,12,NA,2,2,2,12,153,NA,NA,1,1,NA,7,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,14437.97544,16344.869867,2,90,3,3,0.38,5,5,0,4,0,2,33,2,2,5,NA +71442,7,2,1,1,12,3,3,1,NA,12,NA,NA,2,2,1,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,21380.815125,22997.240081,1,103,15,15,5,3,3,1,0,0,1,26,2,5,1,5 +71443,7,2,1,7,NA,1,1,2,7,94,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,12477.812875,12553.43469,2,94,4,4,0.63,6,6,1,2,0,2,36,2,3,1,1 +71444,7,2,2,0,3,5,7,2,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6399.50062,6586.636465,1,101,2,2,0.33,4,4,2,1,0,2,26,1,4,5,NA +71445,7,2,1,2,NA,2,2,1,2,30,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,12005.116852,12547.788444,3,92,6,6,0.86,7,7,1,4,0,2,36,2,1,1,1 +71446,7,2,2,11,NA,1,1,1,11,135,NA,NA,2,2,3,4,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,16986.005478,17733.622754,2,102,4,4,0.57,5,5,0,3,0,1,41,2,1,1,2 +71447,7,2,2,1,19,4,4,2,NA,20,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7348.24433,8211.623817,2,95,2,2,0.33,2,2,1,0,0,2,21,1,1,5,NA +71448,7,2,2,6,NA,4,4,1,7,84,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9453.111053,10094.338553,1,100,6,6,1.39,4,4,0,3,0,2,29,1,4,5,NA +71449,7,2,2,40,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,4,3,2,1,2,2,1,2,2,1,2,2,1,128187.954928,128313.829811,1,99,12,7,3.81,2,1,0,0,0,2,40,1,4,3,NA +71450,7,2,2,34,NA,3,3,1,NA,NA,2,NA,2,2,2,NA,4,1,2,2,2,2,2,2,2,NA,NA,NA,NA,66218.994273,67969.524045,2,93,7,7,1.52,4,4,1,1,0,1,44,2,4,1,NA +71451,7,2,2,51,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,24217.957803,24014.890408,2,94,4,4,1.56,2,1,0,0,0,2,51,1,2,6,NA +71452,7,2,1,36,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,96897.480702,107123.014093,2,91,15,15,5,4,4,2,0,0,2,33,1,5,1,5 +71453,7,2,1,14,NA,5,6,1,14,171,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11657.164593,12175.606972,1,92,9,9,2.88,3,3,0,2,0,1,50,2,5,3,NA +71454,7,2,2,8,NA,3,3,1,8,106,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,18417.272091,18465.044105,1,94,5,5,1.04,4,4,0,2,0,2,29,1,3,1,3 +71455,7,2,1,70,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,NA,13838.08267,16302.45001,1,94,3,3,1.16,1,1,0,0,1,1,70,1,3,5,NA +71456,7,2,1,21,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,59473.789098,72577.011806,3,92,4,1,0.27,5,1,0,0,0,2,57,1,4,1,2 +71457,7,2,2,53,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,23325.73926,22687.369215,1,101,2,2,0.68,1,1,0,0,0,2,53,1,4,2,NA +71458,7,2,1,5,NA,5,6,1,5,66,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,1,NA,NA,NA,NA,8838.066777,9670.229845,3,92,77,77,NA,7,7,2,4,1,1,62,NA,NA,1,NA +71459,7,2,2,14,NA,3,3,2,14,176,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,93307.64449,95903.481223,2,94,15,15,5,3,3,0,1,0,1,49,1,3,1,1 +71460,7,2,2,47,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,19075.861607,19022.257361,1,96,15,15,5,4,4,1,1,0,1,50,1,3,1,4 +71461,7,2,1,7,NA,4,4,1,7,88,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13423.881856,13521.226684,2,101,8,8,2.43,3,3,0,1,0,1,35,1,4,6,NA +71462,7,2,1,7,NA,4,4,2,7,91,NA,NA,2,1,1,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10424.657432,11237.830079,1,93,6,6,1.35,3,3,0,1,0,1,32,2,4,1,4 +71463,7,2,1,0,4,1,1,2,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6298.658963,6651.880632,2,94,15,15,3.33,6,6,1,2,0,2,20,1,3,1,NA +71464,7,2,2,3,NA,1,1,2,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,13366.393396,13791.68675,2,94,5,5,1.07,4,4,2,0,0,1,37,2,1,1,1 +71465,7,2,2,26,NA,4,4,2,NA,NA,2,NA,2,2,3,NA,5,4,2,1,2,2,1,2,2,1,2,2,1,18070.666316,19871.407536,1,99,6,6,2.75,1,1,0,0,0,2,26,2,5,4,NA +71466,7,2,1,2,NA,2,2,1,2,33,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,2,2,2,NA,NA,NA,NA,11727.291842,11865.933582,2,91,2,2,0.19,5,5,3,0,0,1,24,2,1,1,3 +71467,7,2,1,48,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,141134.499671,148176.982862,2,101,8,8,2.81,3,3,0,2,0,1,48,1,3,3,NA +71468,7,2,2,50,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,17191.889135,17295.278265,2,93,2,2,0.75,1,1,0,0,0,2,50,1,3,3,NA +71469,7,2,1,12,NA,4,4,2,12,155,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9313.795042,9381.627752,1,96,77,77,NA,7,7,1,3,0,1,56,1,3,1,4 +71470,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,52209.836905,58077.47757,1,98,8,8,3.48,2,2,0,0,2,1,80,1,3,1,2 +71471,7,2,1,10,NA,3,3,2,10,123,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,44777.275016,47565.734765,1,91,7,7,1.88,4,4,1,2,0,2,43,1,5,4,NA +71472,7,2,1,32,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,16058.989596,15830.0816,2,97,3,3,0.33,6,6,2,0,0,2,32,1,2,1,3 +71473,7,2,2,38,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,34007.843648,34076.908664,2,98,10,10,4.76,2,2,0,0,0,1,42,1,2,6,NA +71474,7,2,1,25,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,18509.151292,19027.688747,2,95,2,2,0.42,3,3,2,0,0,1,25,1,3,5,NA +71475,7,2,2,12,NA,3,3,1,12,145,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,39616.634313,47751.80094,2,101,3,3,0.59,4,3,0,2,0,1,39,1,1,6,NA +71476,7,2,2,49,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,35375.447072,38057.027004,1,97,8,8,2.51,3,3,0,1,0,1,35,1,3,1,4 +71477,7,2,2,80,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,12842.559946,13702.031196,2,95,13,13,NA,2,2,0,0,2,2,80,1,1,1,NA +71478,7,2,1,43,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,1,6,NA,1,2,2,1,2,2,1,2,2,1,35406.972937,35535.728875,2,98,7,7,1.53,5,5,0,0,0,2,48,1,3,5,NA +71479,7,2,2,15,NA,5,6,2,15,190,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,12224.9472,12547.183925,1,97,14,14,2.72,7,7,0,2,0,1,40,1,5,1,5 +71480,7,2,2,5,NA,4,4,2,5,65,NA,NA,2,1,2,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10544.002566,11127.362026,1,91,7,7,1.49,5,5,3,0,0,2,38,2,4,1,4 +71481,7,2,2,26,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,50915.06085,56529.78018,3,92,7,7,1.65,4,4,1,1,0,1,27,1,3,1,3 +71482,7,2,2,40,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,19075.861607,18884.31701,1,96,8,8,2,4,4,1,2,0,2,40,1,4,5,NA +71483,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,49191.372812,61149.379277,3,91,7,7,2.45,2,2,0,0,2,1,80,1,2,1,2 +71484,7,1,1,39,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,113827.590402,0,2,91,7,7,1.89,3,3,0,0,2,2,69,NA,NA,1,4 +71485,7,1,1,18,NA,5,6,NA,NA,NA,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,NA,NA,NA,NA,6666.045669,0,3,90,8,8,1.85,5,5,0,0,1,2,25,1,5,5,NA +71486,7,2,2,11,NA,4,4,2,11,139,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8549.049441,9128.952244,2,99,6,6,1.73,3,3,1,1,1,2,60,1,4,3,NA +71487,7,2,2,13,NA,5,6,1,13,159,NA,NA,2,2,4,7,NA,NA,NA,1,1,1,1,2,1,1,2,2,1,6145.01663,6410.621394,2,92,6,6,1.3,4,4,0,1,0,2,48,2,3,1,3 +71488,7,2,2,41,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,23409.362971,23966.406748,2,96,5,5,1.08,3,3,0,1,0,2,41,1,3,1,NA +71489,7,2,2,24,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,23545.494186,22594.243077,2,99,8,8,3.47,2,2,0,0,1,2,74,1,5,2,NA +71490,7,2,2,11,NA,1,1,1,11,133,NA,NA,1,1,NA,4,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,13490.527555,13974.998066,2,96,5,5,0.68,6,6,0,3,2,1,60,2,1,1,1 +71491,7,2,1,12,NA,3,3,1,13,156,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,23588.786918,23619.012758,1,94,7,7,1.29,6,6,1,3,0,1,38,1,3,1,2 +71492,7,2,2,51,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,32041.645327,31772.976371,3,91,7,7,1.1,7,7,0,4,0,1,40,1,4,1,3 +71493,7,2,1,14,NA,1,1,1,15,180,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,22768.423624,22944.003607,2,98,8,8,3.06,2,2,0,1,0,2,56,1,3,3,NA +71494,7,2,1,29,NA,5,6,1,NA,NA,2,NA,2,2,3,NA,5,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,17191.065623,18600.361918,1,100,5,5,1.79,2,1,0,0,0,1,27,NA,NA,5,NA +71495,7,2,2,28,NA,2,2,2,NA,NA,2,NA,2,1,6,NA,3,6,2,1,2,2,1,2,2,1,2,2,1,43200.700326,51577.05558,1,97,5,5,1.04,4,4,1,1,0,1,32,1,3,6,NA +71496,7,2,1,65,NA,2,2,2,NA,NA,2,NA,2,1,7,NA,1,4,NA,2,2,2,2,2,2,1,2,2,2,6564.099986,6927.048144,2,95,12,3,1.07,4,1,0,0,1,1,65,2,1,4,NA +71497,7,2,2,71,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,NA,27602.403077,28546.401551,1,94,2,2,0.55,2,2,0,0,2,2,75,1,1,3,NA +71498,7,2,2,5,NA,4,4,2,5,68,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10389.292229,10850.629517,2,95,4,4,0.65,4,4,1,2,0,2,27,1,3,5,NA +71499,7,2,1,16,NA,4,4,2,16,197,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11834.781205,12063.950506,2,90,15,15,5,4,4,1,1,0,1,53,2,5,1,5 +71500,7,2,1,6,NA,1,1,1,6,81,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13927.458372,14007.413517,2,98,15,15,4.97,5,5,0,3,0,1,39,1,5,1,5 +71501,7,2,2,2,NA,3,3,2,2,29,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,50995.241584,52601.79766,2,91,14,14,4.12,4,4,2,0,0,1,35,1,5,1,5 +71502,7,2,1,16,NA,1,1,1,16,193,NA,NA,1,1,NA,8,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,19570.996814,19477.677478,2,100,4,4,0.81,4,4,0,2,0,1,56,1,4,1,2 +71503,7,2,1,30,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,21200.922169,24170.169783,2,99,9,9,4.92,1,1,0,0,0,1,30,1,4,5,NA +71504,7,2,2,16,NA,1,1,1,16,200,NA,NA,2,2,4,10,NA,NA,NA,2,2,2,1,2,2,1,2,2,1,22753.900764,24458.613732,1,100,2,2,0.35,4,4,0,1,0,2,40,2,2,5,NA +71505,7,2,1,33,NA,2,2,2,NA,NA,2,NA,2,1,3,NA,3,1,NA,2,2,2,1,2,2,NA,NA,NA,NA,43108.74283,42989.380022,2,91,7,7,2.64,2,2,0,1,0,1,33,2,3,1,NA +71506,7,2,2,0,2,5,7,1,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9148.090461,9086.623516,1,92,9,9,3.14,3,3,1,0,0,2,30,1,5,1,5 +71507,7,2,1,1,15,1,1,2,NA,16,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11160.282155,11957.436882,2,97,2,2,0.27,3,3,2,0,0,2,19,1,3,NA,NA +71508,7,2,1,1,20,4,4,2,NA,21,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10232.679671,11283.202594,2,101,2,2,0.48,2,2,1,0,0,2,19,1,3,NA,NA +71509,7,2,2,60,NA,5,6,1,NA,NA,2,NA,2,2,5,NA,3,2,NA,1,2,1,1,2,1,1,2,1,3,12627.660237,14547.347393,2,101,99,99,NA,2,2,0,0,1,2,60,2,3,2,NA +71510,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,1,2,1,2,2,1,2,2,NA,46372.402053,52744.849017,1,90,5,5,1.05,3,3,0,0,3,2,60,1,5,77,NA +71511,7,2,1,64,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,4,1,NA,1,2,2,NA,NA,NA,1,2,2,1,11842.156092,12450.236093,2,96,NA,NA,NA,3,3,0,0,2,1,64,2,4,1,NA +71512,7,2,1,18,NA,2,2,1,18,222,2,NA,2,2,2,13,NA,NA,NA,2,2,2,2,2,2,2,2,2,2,18206.126374,18280.234909,2,93,4,4,0.82,4,4,0,0,0,1,51,2,3,1,3 +71513,7,2,1,18,NA,2,2,1,18,217,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,2,2,2,1,2,2,1,17555.907575,17627.369376,2,93,6,6,1.39,4,4,0,0,0,1,53,2,3,1,3 +71514,7,2,2,1,15,2,2,2,NA,17,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,9955.153132,10089.038145,2,94,77,77,NA,4,4,2,0,0,2,32,2,4,1,4 +71515,7,2,1,55,NA,2,2,2,NA,NA,2,NA,2,1,8,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,27735.830485,32770.478954,2,91,14,14,4.19,3,3,0,1,0,1,55,2,3,1,5 +71516,7,2,1,23,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,79607.896323,82775.96099,2,92,6,6,2.75,1,1,0,0,0,1,23,1,5,5,NA +71517,7,2,2,56,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,15521.115746,15563.161752,1,96,2,2,0.4,3,3,0,0,0,2,56,1,3,3,NA +71518,7,2,2,6,NA,5,6,1,6,75,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5139.061504,5511.809249,2,103,77,77,NA,5,5,0,2,0,2,39,2,5,1,5 +71519,7,2,1,12,NA,4,4,2,12,155,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11085.075029,10992.519505,1,93,7,7,1.97,4,4,1,2,0,2,33,1,4,3,NA +71520,7,2,2,2,NA,2,2,1,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,10099.930724,10736.663476,2,96,1,1,0.06,5,5,2,1,0,1,27,2,3,1,4 +71521,7,2,1,18,NA,4,4,2,18,222,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,13416.172328,13513.882801,1,96,15,15,5,4,4,0,1,0,1,42,2,4,1,4 +71522,7,2,2,63,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,41983.304745,42669.243011,1,95,5,5,1.1,3,3,0,0,1,2,63,1,4,1,5 +71523,7,2,1,2,NA,4,4,2,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6441.733603,6707.906886,1,91,7,7,1.49,5,5,3,0,0,2,38,2,4,1,4 +71524,7,2,2,16,NA,5,6,1,16,199,NA,NA,2,2,2,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,8391.252153,8753.945484,1,92,12,12,NA,7,7,1,2,1,2,45,2,3,1,3 +71525,7,2,2,70,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,72295.614975,73067.691445,1,98,6,6,1.98,2,2,0,0,2,2,70,1,4,1,5 +71526,7,2,2,39,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,17978.142628,18083.929198,1,91,15,15,5,5,5,0,3,0,1,40,1,5,1,5 +71527,7,2,2,54,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,32032.578233,33220.140308,1,91,4,4,0.86,3,3,1,0,0,2,54,1,4,3,NA +71528,7,2,2,30,NA,4,4,2,NA,NA,2,NA,2,1,4,NA,5,5,2,1,2,2,1,2,2,NA,NA,NA,NA,26462.874679,26479.317455,2,99,15,15,4.34,4,4,0,0,0,1,59,2,4,1,5 +71529,7,2,1,33,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,26972.787983,26588.312559,2,96,10,10,4.76,2,2,0,0,0,2,26,1,5,1,4 +71530,7,2,1,68,NA,1,1,1,NA,NA,1,1,2,1,9,NA,4,1,NA,2,2,2,1,2,2,1,2,2,2,11568.876339,11794.347884,1,102,77,77,NA,2,2,0,0,2,1,68,2,4,1,1 +71531,7,2,1,35,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,109181.566304,112308.582503,2,91,15,2,0.72,7,1,0,0,1,1,49,NA,NA,5,NA +71532,7,2,1,21,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,42077.383821,44759.048785,1,102,6,6,1.34,4,4,0,1,0,2,48,2,3,1,1 +71533,7,2,2,38,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,3,2,1,2,2,1,2,2,NA,NA,NA,NA,31646.000316,42635.226522,1,93,1,1,0,2,2,0,1,0,2,38,1,4,3,NA +71534,7,2,1,76,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,15844.527135,16703.540642,1,95,6,6,2.04,2,2,0,0,2,2,67,1,1,2,NA +71535,7,2,2,46,NA,2,2,1,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,32606.880052,33604.492246,2,93,14,14,3.25,4,4,0,2,0,2,46,2,5,1,4 +71536,7,2,2,44,NA,3,3,2,NA,NA,2,NA,2,1,5,NA,5,3,1,1,2,2,1,2,2,NA,NA,NA,NA,26763.110196,27429.212861,1,100,3,3,0.92,1,1,0,0,0,2,44,2,5,3,NA +71537,7,2,1,11,NA,4,4,1,11,135,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13423.881856,14179.490667,2,101,4,4,1.02,2,2,0,1,0,2,30,1,2,77,NA +71538,7,2,2,54,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,1,21143.964074,20565.30403,1,100,5,5,0.85,5,5,0,2,0,2,54,1,2,2,NA +71539,7,2,2,16,NA,5,6,1,16,195,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,NA,NA,NA,NA,4445.888073,4534.01329,1,103,77,77,NA,6,6,0,2,2,1,70,NA,NA,1,1 +71540,7,2,2,57,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,17364.980275,17214.230108,2,93,8,8,1.67,5,5,1,1,0,2,31,1,4,5,NA +71541,7,2,2,8,NA,1,1,2,8,104,NA,NA,1,1,NA,2,NA,NA,NA,2,1,2,1,2,2,1,2,2,NA,15225.935813,15373.8033,2,94,5,5,1.08,3,3,0,1,0,2,37,2,2,4,NA +71542,7,2,2,67,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,99831.393624,101809.075589,2,94,15,15,5,2,2,0,0,2,2,67,1,5,1,NA +71543,7,2,2,10,NA,1,1,1,11,132,NA,NA,1,1,NA,4,NA,NA,NA,2,1,2,1,2,2,1,2,2,1,12789.411811,13899.276526,1,102,4,4,0.67,4,4,0,1,0,1,23,2,4,5,NA +71544,7,2,1,49,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,126789.52929,140129.484883,1,98,10,10,3.04,4,4,0,2,0,2,47,1,4,1,3 +71545,7,2,1,27,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,39915.513053,42616.161803,2,98,9,9,4.01,2,2,0,0,0,1,27,1,5,1,4 +71546,7,2,1,9,NA,4,4,2,9,117,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6377.235034,7094.374704,2,90,6,6,0.84,6,6,1,3,1,2,43,1,2,5,NA +71547,7,2,2,21,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,NA,NA,NA,NA,61710.107686,63275.181919,1,98,5,3,0.9,3,1,0,0,0,2,21,1,4,5,NA +71548,7,2,2,13,NA,1,1,1,14,168,NA,NA,1,1,NA,7,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,26325.414456,26852.811114,3,92,3,3,0.51,5,5,1,2,0,2,34,2,1,6,NA +71549,7,2,1,80,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,7912.12564,8378.94011,2,99,5,5,1.88,1,1,0,0,1,1,80,1,1,2,NA +71550,7,2,2,0,3,3,3,2,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10692.488346,10402.056617,1,98,4,4,1.01,3,3,1,0,0,1,23,1,2,6,NA +71551,7,2,1,3,NA,3,3,2,3,38,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,39061.897809,44649.899401,1,95,15,15,3.62,7,7,2,4,0,1,59,1,5,1,2 +71552,7,2,1,65,NA,2,2,2,NA,NA,2,NA,2,1,9,NA,2,6,NA,2,2,2,2,2,2,1,2,2,2,8609.250304,9380.869295,2,90,4,4,1.02,2,2,0,0,2,2,75,2,1,6,NA +71553,7,2,1,2,NA,4,4,2,3,36,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4455.468915,4730.507566,3,90,3,3,0.37,5,5,2,2,0,2,36,2,4,4,NA +71554,7,2,2,33,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,25558.459243,25637.043034,1,101,3,3,0.44,5,5,0,3,0,1,35,1,3,1,4 +71555,7,2,1,60,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,14488.953694,14771.336069,3,92,6,6,1.65,2,2,0,0,1,1,60,1,3,1,4 +71556,7,2,1,0,2,1,1,1,NA,3,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,6876.075003,7261.67751,1,100,4,4,0.56,5,5,3,0,0,2,28,2,2,6,NA +71557,7,2,1,6,NA,5,7,1,6,76,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13614.165673,13762.118902,1,95,14,14,3.04,6,6,0,4,0,1,56,1,5,1,4 +71558,7,2,2,12,NA,4,4,2,12,145,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12581.940435,12644.353117,2,97,6,6,0.92,7,7,1,4,0,2,29,1,3,5,NA +71559,7,2,2,51,NA,2,2,2,NA,NA,2,NA,2,1,7,NA,2,5,NA,2,2,2,2,2,2,1,2,2,2,17054.056149,20556.446647,2,90,2,2,0.3,3,3,0,1,0,2,51,2,2,5,NA +71560,7,2,1,80,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,14979.892428,17964.055881,1,92,5,5,1.45,2,2,0,0,2,1,80,1,2,1,3 +71561,7,2,2,40,NA,5,6,1,NA,NA,2,NA,2,2,4,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,12544.244874,13057.037707,1,102,15,15,5,4,4,0,2,0,2,40,2,5,1,4 +71562,7,2,2,0,8,4,4,2,NA,8,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4543.931297,5004.098497,1,96,7,7,2.23,3,3,1,0,0,1,29,2,5,1,5 +71563,7,2,1,4,NA,2,2,1,4,58,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,15745.774489,15931.923312,2,91,6,6,0.93,5,5,1,2,0,1,34,1,2,1,3 +71564,7,2,1,25,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,27374.067425,29791.861332,1,98,2,2,0.36,5,5,3,0,0,1,25,1,3,1,3 +71565,7,2,2,24,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,142639.05444,145244.474771,1,100,8,8,2.97,2,2,0,0,0,1,24,1,5,1,5 +71566,7,2,1,48,NA,5,6,2,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,19184.316833,20543.822351,1,97,15,15,5,3,3,0,1,0,2,45,2,5,1,5 +71567,7,2,1,35,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,6,NA,1,2,2,1,2,2,1,2,2,1,114838.671743,123195.718665,1,91,15,3,0.92,2,1,0,0,0,1,30,1,5,6,NA +71568,7,2,1,13,NA,1,1,1,13,159,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,NA,NA,NA,1,2,2,1,22768.423624,22766.421142,3,92,7,7,1.49,5,5,0,2,1,2,62,1,4,2,NA +71569,7,2,1,56,NA,1,1,2,NA,NA,2,NA,2,2,77,NA,1,1,NA,2,2,2,1,2,2,2,2,2,2,22446.308035,22116.943066,2,94,6,4,1.38,2,1,0,0,0,1,40,2,3,1,NA +71570,7,2,1,3,NA,2,2,1,3,38,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,17458.543556,17482.134163,2,91,5,5,1.05,3,3,2,0,0,2,26,2,3,4,NA +71571,7,2,1,60,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,10717.375231,11136.552864,2,101,14,14,5,2,2,0,0,1,1,60,1,3,1,3 +71572,7,2,1,8,NA,3,3,1,8,104,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,54897.892683,57357.850008,2,98,14,14,3.58,4,4,0,2,0,1,36,1,3,1,4 +71573,7,2,2,11,NA,3,3,2,11,134,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,39810.933651,39282.261038,2,95,15,15,4.34,4,4,0,2,0,2,37,1,4,1,4 +71574,7,2,2,31,NA,2,2,1,NA,NA,2,NA,2,2,3,NA,3,1,2,2,2,2,2,2,2,2,2,2,2,35464.8385,36323.14329,2,96,6,6,1.25,4,4,1,1,0,1,31,2,3,1,3 +71575,7,2,2,66,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,16420.864787,17817.127844,2,102,3,3,0.76,3,3,0,1,1,2,66,1,2,3,NA +71576,7,2,2,0,9,1,1,1,NA,10,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8359.077295,8583.668456,3,92,5,5,0.68,6,6,3,0,0,2,19,1,4,NA,NA +71577,7,2,1,47,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,17787.524589,17894.667705,2,100,4,4,1.02,2,2,0,0,1,1,79,1,1,2,NA +71578,7,2,1,41,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,126789.52929,152250.956405,1,101,8,8,1.85,5,5,0,3,0,1,41,1,3,1,4 +71579,7,2,1,0,9,1,1,1,NA,10,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,6910.953528,6911.08091,2,96,3,3,0.59,3,3,1,0,0,2,28,2,1,77,NA +71580,7,2,2,50,NA,2,2,1,NA,NA,2,NA,2,1,7,NA,3,1,NA,2,2,2,2,2,2,2,2,2,2,19969.163208,20694.024637,2,93,8,8,2.57,3,3,0,0,1,1,59,2,3,1,3 +71581,7,2,1,36,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,51543.062078,57043.574316,3,92,10,10,2.82,4,4,0,1,1,1,36,1,3,1,5 +71582,7,2,1,29,NA,1,1,2,NA,NA,2,NA,2,2,4,NA,3,6,NA,2,2,2,2,2,2,2,2,1,2,39084.166385,40378.039385,1,97,4,4,0.72,5,5,2,1,0,2,33,2,1,6,NA +71583,7,2,1,53,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,19374.410926,19463.695548,1,96,12,12,NA,3,3,0,0,2,1,77,NA,NA,6,NA +71584,7,2,2,58,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,21171.165283,21533.12194,1,100,15,15,5,3,3,0,0,1,1,69,1,5,1,4 +71585,7,2,2,39,NA,2,2,1,NA,NA,2,NA,2,2,4,NA,4,1,2,1,2,2,1,2,2,2,2,2,2,36904.965687,36815.84758,2,93,8,8,2,4,4,1,1,0,1,50,2,4,1,4 +71586,7,2,2,7,NA,5,7,1,7,87,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7252.281896,7644.510498,2,92,6,6,1.7,2,2,0,1,0,2,32,2,4,3,NA +71587,7,2,2,9,NA,1,1,1,9,116,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17053.854294,17379.519997,3,92,8,8,2.17,4,4,0,2,0,1,40,2,2,1,4 +71588,7,2,2,12,NA,3,3,2,12,152,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,86497.469217,90071.968674,1,91,14,14,2.44,7,7,2,4,0,1,33,1,5,1,5 +71589,7,2,1,4,NA,3,3,2,4,53,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,30883.231636,34843.624635,1,95,5,5,0.92,5,5,1,2,0,2,30,1,4,1,4 +71590,7,2,1,0,3,1,1,1,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5777.934266,5882.770795,2,103,9,9,2.6,4,4,2,0,0,2,35,1,4,1,3 +71591,7,2,2,55,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,38954.135779,39992.589933,1,91,4,3,0.82,3,2,0,0,0,2,22,1,5,6,NA +71592,7,2,2,8,NA,1,1,2,8,103,NA,NA,1,1,NA,2,NA,NA,NA,2,1,2,1,2,2,2,2,2,2,14300.71869,14671.891945,2,94,9,9,2.29,5,5,2,1,0,2,33,2,3,1,1 +71593,7,2,1,45,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,26215.80546,26132.189255,1,92,9,7,1.74,7,4,2,1,0,1,45,1,4,2,NA +71594,7,2,1,27,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,91704.59836,93129.802737,1,93,15,14,5,6,1,0,0,0,1,23,1,5,5,NA +71595,7,2,2,56,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,207590.346266,205849.702763,1,92,15,15,5,2,2,0,0,0,2,56,1,4,1,5 +71596,7,2,2,19,NA,1,1,1,19,237,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,NA,NA,NA,NA,26325.414456,27702.295836,3,92,5,5,0.68,6,6,3,0,0,2,19,1,4,NA,NA +71597,7,2,2,13,NA,3,3,2,13,158,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,29885.567338,31265.78413,1,94,7,7,0.94,7,7,1,4,0,2,46,2,5,1,5 +71598,7,2,2,27,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,1,1,2,2,1,2,2,1,2,2,1,77792.702831,79765.659277,1,102,14,14,4.32,3,3,1,0,0,1,25,1,4,1,4 +71599,7,2,1,59,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,105379.391148,106074.259408,1,93,15,15,3.92,5,5,0,1,0,2,54,1,5,1,5 +71600,7,2,1,1,14,1,1,1,NA,14,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,12493.910388,13386.323284,2,98,1,1,0.13,4,4,2,0,0,2,52,1,2,4,NA +71601,7,2,1,6,NA,5,7,2,6,81,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9502.15317,9616.069144,2,97,5,5,0.84,5,5,0,2,0,2,33,1,4,1,3 +71602,7,2,2,9,NA,3,3,1,9,112,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17685.703081,17770.107744,1,98,6,6,0.81,6,6,0,4,0,2,34,NA,NA,1,2 +71603,7,2,2,16,NA,4,4,2,16,201,NA,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,10484.6104,10912.740054,2,99,13,13,NA,3,3,1,1,0,2,36,NA,NA,5,NA +71604,7,2,1,49,NA,1,1,2,NA,NA,2,NA,2,2,5,NA,3,1,NA,2,2,2,2,2,2,2,2,2,2,31640.296506,34765.415986,2,94,4,4,0.81,3,3,0,1,0,1,49,2,3,1,3 +71605,7,2,2,38,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,64581.191728,64779.757488,2,94,9,5,1.84,2,1,0,0,0,2,38,1,4,6,NA +71606,7,2,1,13,NA,5,6,1,13,163,NA,NA,2,1,3,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9048.093498,9416.694257,1,100,8,8,2.62,3,3,0,1,0,1,41,2,5,1,5 +71607,7,2,2,8,NA,1,1,1,8,104,NA,NA,2,2,2,2,NA,NA,NA,2,1,2,2,2,2,1,2,2,NA,16986.005478,17733.622754,2,102,4,4,0.57,5,5,0,3,0,1,41,2,1,1,2 +71608,7,2,1,10,NA,4,4,1,10,125,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10138.00454,10211.52145,1,100,8,8,1.61,6,6,1,3,0,1,29,1,5,6,NA +71609,7,2,2,28,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,NA,NA,NA,NA,21640.010524,20970.872814,1,93,6,6,0.83,6,6,3,1,0,1,37,NA,NA,1,3 +71610,7,2,1,16,NA,1,1,1,16,200,NA,NA,2,2,2,8,NA,NA,NA,2,2,2,2,2,2,2,2,1,2,22203.024273,23172.92708,1,100,99,99,NA,7,7,2,3,0,2,35,2,1,1,NA +71611,7,2,2,15,NA,3,3,2,15,191,NA,NA,1,1,NA,9,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,103007.696238,104941.393061,1,101,14,14,3.25,4,4,0,1,0,1,48,1,4,1,2 +71612,7,2,2,4,NA,2,2,2,4,57,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,11429.37307,11583.084593,2,90,2,2,0.54,2,2,1,0,0,2,32,2,2,4,NA +71613,7,2,1,75,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,12824.368043,13581.00423,2,101,9,9,4.08,2,2,0,0,1,1,75,1,1,2,NA +71614,7,2,1,4,NA,4,4,1,4,50,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10040.033098,11070.778245,1,100,14,14,3.47,4,4,2,0,0,1,34,1,5,1,5 +71615,7,2,1,41,NA,5,6,1,NA,NA,2,NA,2,1,7,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,15952.616949,16443.31736,2,93,15,15,5,3,3,1,0,0,1,41,2,5,1,5 +71616,7,2,2,3,NA,2,2,2,3,46,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,13490.92482,14894.343037,1,90,2,2,0.56,2,2,1,0,0,2,27,1,3,5,NA +71617,7,2,1,2,NA,2,2,2,2,27,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9237.934626,9250.417252,2,90,3,3,0.7,3,3,1,1,0,2,25,1,1,1,NA +71618,7,2,1,4,NA,4,4,2,4,59,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7604.054172,7918.254694,2,99,6,6,1.03,6,6,3,0,0,1,33,1,3,6,NA +71619,7,2,1,55,NA,5,6,2,NA,NA,2,NA,2,1,2,NA,4,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,11690.444016,12095.591726,3,90,3,3,0.75,3,3,0,0,0,1,55,2,4,1,3 +71620,7,2,1,65,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,3,1,NA,1,2,1,1,2,1,1,2,1,3,7289.557268,7804.776102,3,90,77,77,NA,2,2,0,0,1,1,65,2,3,1,5 +71621,7,2,2,12,NA,1,1,1,12,152,NA,NA,2,2,4,6,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,26325.414456,27702.295836,3,92,4,4,0.46,7,7,1,2,0,2,31,2,2,1,1 +71622,7,2,1,80,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,40157.007559,44610.827766,2,98,5,5,1.63,2,2,0,0,2,1,80,1,3,1,3 +71623,7,2,1,12,NA,4,4,2,12,144,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8364.097643,9212.617312,2,90,6,6,1.03,6,6,3,1,0,1,45,2,2,1,2 +71624,7,2,2,18,NA,5,6,1,18,219,2,NA,2,2,2,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,10767.566937,11183.935292,2,91,15,15,4.63,7,7,1,2,0,1,36,2,4,1,3 +71625,7,2,1,39,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,18353.275855,20139.588201,1,91,4,4,0.76,4,4,0,2,0,2,44,1,4,6,NA +71626,7,2,1,59,NA,2,2,1,NA,NA,2,NA,2,1,7,NA,4,1,NA,1,2,2,1,2,2,2,2,2,2,30839.213846,31462.493685,1,92,10,10,2.93,4,4,1,0,0,2,55,1,4,1,4 +71627,7,2,1,19,NA,5,6,2,19,236,2,NA,1,1,NA,12,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,9099.599144,9725.105491,1,90,9,9,2.6,4,4,0,1,0,2,49,2,2,1,5 +71628,7,2,2,53,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,3,4,NA,1,2,2,1,2,2,1,2,2,1,28349.668436,29178.127765,1,102,5,5,1.56,2,2,0,0,0,2,53,1,3,4,NA +71629,7,2,2,16,NA,4,4,1,16,193,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,20473.346601,20523.769333,2,102,14,14,4.05,3,3,0,1,0,1,18,1,2,NA,NA +71630,7,2,1,0,10,1,1,1,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6121.794646,6421.491158,1,102,4,4,0.61,5,5,2,2,0,2,27,2,2,5,NA +71631,7,2,1,22,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,37970.860743,38488.432875,2,92,NA,3,0.92,5,1,0,0,0,1,22,1,5,5,NA +71632,7,2,1,18,NA,4,4,1,18,223,2,NA,1,1,NA,12,NA,NA,NA,1,2,2,NA,NA,NA,1,2,2,1,13276.485807,13885.0639,2,100,NA,NA,NA,4,4,1,0,0,2,38,NA,NA,77,NA +71633,7,2,2,64,NA,5,6,1,NA,NA,2,NA,2,2,5,NA,1,1,NA,1,2,1,1,2,1,1,2,1,NA,11838.431472,12356.62484,2,92,3,3,0.4,6,6,0,1,2,1,78,2,1,1,1 +71634,7,2,2,21,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,36850.868456,37875.214466,2,103,5,5,1.2,3,3,0,0,2,1,66,2,2,1,2 +71635,7,2,2,42,NA,4,4,2,NA,NA,2,NA,2,1,8,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,22513.236051,21981.065205,1,91,15,15,5,6,6,1,2,0,2,42,2,5,1,5 +71636,7,2,1,9,NA,4,4,1,9,111,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10410.106675,10390.534388,2,96,4,4,0.57,5,5,0,3,0,2,26,1,2,5,NA +71637,7,2,1,14,NA,3,3,1,14,173,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,95925.820151,96188.020601,1,92,8,8,3.17,2,2,0,1,0,2,35,1,2,77,NA +71638,7,2,1,23,NA,4,4,1,NA,NA,1,2,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,25815.880139,26503.609729,2,101,99,13,NA,2,1,0,0,0,1,24,1,4,5,NA +71639,7,2,2,48,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,22109.546782,22635.660435,1,93,12,12,NA,3,3,0,1,0,2,48,1,3,5,NA +71640,7,2,2,51,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,15497.844354,15720.409191,1,99,14,14,5,2,1,0,0,0,2,51,1,5,1,NA +71641,7,2,2,7,NA,3,3,2,7,95,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,73810.484644,74865.697805,1,91,15,15,5,4,4,1,1,0,1,38,1,5,1,5 +71642,7,1,2,3,NA,1,1,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,15358.480588,0,1,102,2,2,0.31,4,4,1,2,0,2,25,1,2,4,NA +71643,7,2,1,31,NA,2,2,1,NA,NA,1,2,2,1,3,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,53303.690379,53390.332272,1,100,8,8,3.17,2,2,0,0,0,1,31,2,4,1,5 +71644,7,2,2,80,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,45973.010529,51521.910389,1,91,7,7,2.68,2,2,0,0,2,1,80,1,4,1,4 +71645,7,2,1,7,NA,3,3,2,7,93,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,44777.275016,47565.734765,1,91,14,14,3.06,5,5,0,3,0,2,46,1,5,1,5 +71646,7,2,1,3,NA,1,1,1,3,44,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,16775.083123,16335.348923,2,98,3,3,0.33,7,7,2,3,0,1,40,2,1,1,1 +71647,7,2,2,80,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,16076.770364,16942.062244,1,90,14,14,5,2,2,0,0,1,1,58,1,5,5,NA +71648,7,2,1,7,NA,1,1,1,7,91,NA,NA,1,1,NA,1,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,13533.281742,14131.961026,1,100,7,7,1.74,4,4,0,2,0,2,39,2,1,1,3 +71649,7,2,1,12,NA,5,6,2,12,154,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7057.977053,7861.480262,2,92,12,12,NA,7,7,2,4,0,1,54,2,2,1,5 +71650,7,2,1,60,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,7140.457792,7196.312698,2,101,7,7,1.3,5,5,2,0,1,2,50,1,4,1,3 +71651,7,2,2,46,NA,5,6,2,NA,NA,2,NA,2,2,6,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,19294.309,26319.879121,1,93,14,14,5,2,2,0,1,0,2,46,2,5,3,NA +71652,7,2,1,5,NA,5,6,2,5,68,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,4858.407579,4952.635908,1,99,14,14,2.66,7,7,3,1,0,1,35,1,5,1,5 +71653,7,2,2,10,NA,5,6,1,10,124,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6779.975678,7239.998882,3,91,15,15,5,3,3,0,1,0,1,47,2,5,1,5 +71654,7,2,2,17,NA,3,3,1,17,213,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,49337.766842,51601.905979,2,103,15,15,3.44,7,7,0,1,2,2,79,1,3,2,NA +71655,7,2,1,65,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,1,5,NA,1,2,2,1,2,2,1,2,2,1,7323.703412,7380.991723,2,97,NA,99,NA,7,1,2,1,1,2,56,1,3,5,NA +71656,7,2,1,58,NA,3,3,2,NA,NA,2,NA,2,1,9,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,163791.427718,171966.737289,1,93,15,15,5,2,2,0,0,0,1,58,2,5,1,5 +71657,7,2,2,49,NA,2,2,2,NA,NA,2,NA,2,1,8,NA,5,1,NA,2,2,2,1,2,2,1,2,2,1,30105.942022,31646.425257,1,96,8,8,2.17,4,4,0,0,2,1,80,NA,NA,1,NA +71658,7,2,1,25,NA,1,1,2,NA,NA,2,NA,2,2,3,NA,2,6,NA,2,2,2,2,2,2,1,2,1,2,37987.561992,39245.132137,1,90,2,1,0.13,5,3,0,1,0,1,25,2,2,6,NA +71659,7,2,2,33,NA,4,4,2,NA,NA,2,NA,2,2,3,NA,3,1,2,1,2,2,1,2,2,NA,NA,NA,NA,32799.237043,32564.866412,1,91,6,6,0.99,5,5,3,0,0,2,33,2,3,1,4 +71660,7,2,2,35,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,4,3,1,2,2,1,2,2,1,2,2,1,19498.713386,19652.836095,2,97,4,4,1.09,2,2,0,1,0,2,35,1,2,4,NA +71661,7,2,1,8,NA,5,6,1,8,105,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,5651.170392,5934.27615,1,102,5,5,0.92,5,5,1,2,0,2,44,2,1,1,2 +71662,7,2,1,74,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,79733.665046,84684.628619,1,92,9,9,3.8,2,2,0,0,2,2,66,1,4,1,5 +71663,7,2,2,9,NA,4,4,1,9,112,NA,NA,1,1,NA,2,NA,NA,NA,1,1,1,1,2,1,1,2,2,1,11195.065587,11548.620784,2,96,77,77,NA,7,3,1,4,0,2,32,NA,NA,1,NA +71664,7,2,1,4,NA,4,4,2,4,55,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6299.35077,6688.213305,3,90,3,3,0.37,5,5,2,2,0,2,36,2,4,4,NA +71665,7,2,2,7,NA,4,4,1,7,88,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11334.095519,11753.9565,2,96,4,4,0.65,5,5,0,3,0,1,30,1,4,1,2 +71666,7,2,1,61,NA,4,4,2,NA,NA,1,1,1,1,NA,NA,5,6,NA,1,2,2,1,2,2,1,2,2,1,7017.945976,7072.842557,2,99,1,1,0.36,3,1,1,0,1,2,55,1,4,6,NA +71667,7,2,2,9,NA,1,1,2,9,118,NA,NA,1,1,NA,4,NA,NA,NA,2,1,2,1,2,2,1,2,2,2,13231.432201,13706.598104,2,97,4,4,0.67,4,4,0,2,0,1,39,2,2,6,NA +71668,7,2,2,12,NA,4,4,1,12,154,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12531.903464,13043.632492,2,100,9,9,2.46,4,4,1,1,1,2,59,1,3,1,3 +71669,7,2,1,0,7,5,6,2,NA,8,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6918.643947,7208.455005,1,101,8,8,1.81,5,5,2,0,1,2,37,2,4,1,2 +71670,7,2,1,24,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,14860.312419,14555.816778,3,90,15,15,4.34,4,4,0,0,1,1,65,1,3,1,4 +71671,7,2,1,65,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,125558.167126,127168.668278,3,91,7,7,2.89,2,2,0,0,2,2,64,1,4,1,4 +71672,7,2,2,18,NA,4,4,2,18,227,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11372.489138,11836.874523,1,99,14,14,3.67,4,4,1,0,0,2,49,1,3,1,3 +71673,7,2,2,9,NA,5,7,2,9,112,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7294.840846,7578.01532,1,93,15,15,5,5,5,1,2,0,2,40,1,5,1,5 +71674,7,2,1,10,NA,4,4,2,10,127,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,9502.15317,9484.287948,2,97,3,3,0.4,6,6,2,3,0,2,25,1,2,5,NA +71675,7,2,2,73,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,66567.821082,76362.988288,3,91,7,7,2.92,2,2,0,0,2,1,74,1,3,1,3 +71676,7,2,1,80,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,37318.801462,40047.525745,1,98,8,8,3.48,2,2,0,0,2,1,80,1,3,1,2 +71677,7,2,1,35,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,29756.291619,30875.098449,2,101,5,5,1.19,3,3,1,0,0,2,32,1,4,1,3 +71678,7,2,2,70,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,98976.420245,102012.919253,2,101,15,15,5,2,2,0,0,2,1,73,1,5,1,5 +71679,7,2,2,27,NA,1,1,1,NA,NA,2,NA,2,2,5,NA,2,5,2,1,2,2,1,2,2,NA,NA,NA,NA,41537.508946,44104.799715,1,102,4,4,0.61,5,5,2,2,0,2,27,2,2,5,NA +71680,7,2,1,55,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,28575.926692,28541.082411,3,92,4,3,0.52,5,4,0,0,0,2,57,1,4,1,2 +71681,7,2,2,35,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,1,1,2,2,1,2,2,NA,NA,NA,NA,68146.615091,70082.037538,2,99,15,15,5,3,3,1,0,0,1,43,1,5,1,5 +71682,7,2,1,69,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,7101.739553,7379.502561,2,100,5,5,1.56,2,2,0,0,2,1,69,1,2,1,3 +71683,7,2,2,1,17,4,4,1,NA,18,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8412.350508,9400.756791,1,100,5,5,1.05,3,3,1,0,0,2,42,2,5,1,NA +71684,7,2,1,0,3,3,3,1,NA,4,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,24509.975935,26238.985016,1,94,5,5,1.04,4,4,1,1,0,1,18,1,2,NA,NA +71685,7,2,2,11,NA,4,4,2,11,140,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10994.192555,11605.838362,2,97,2,2,0.27,4,4,0,2,0,1,51,1,2,4,NA +71686,7,2,1,31,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,16505.268729,16996.380056,3,91,8,8,2.7,3,3,1,0,0,1,31,1,5,1,5 +71687,7,2,2,13,NA,5,6,2,13,157,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,6486.356303,6952.179218,1,91,7,7,1.57,4,4,0,3,0,2,38,2,2,3,NA +71688,7,2,1,51,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,16628.326744,17325.680634,2,102,10,10,3.62,3,3,0,0,0,1,51,2,5,1,5 +71689,7,2,2,17,NA,4,4,1,17,210,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,16659.324602,16974.753267,1,92,15,15,4.44,5,5,0,3,0,2,43,1,5,6,NA +71690,7,2,1,2,NA,2,2,1,2,31,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,9382.177239,9806.283152,2,93,6,6,0.64,7,7,2,1,3,2,60,2,3,2,NA +71691,7,2,2,76,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,62212.598767,64340.261278,1,91,10,10,4.3,2,2,0,0,2,1,78,1,4,1,4 +71692,7,2,1,8,NA,3,3,1,8,104,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,22651.436723,23515.701302,3,92,7,7,0.81,7,7,2,4,0,1,40,NA,NA,1,4 +71693,7,2,2,4,NA,5,6,2,4,53,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7497.268293,8158.717681,1,101,10,10,3.67,3,3,1,0,0,1,36,2,5,1,5 +71694,7,2,1,0,6,5,6,1,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,5024.464768,5303.683185,2,92,10,6,1.12,7,4,1,1,1,2,27,2,3,1,3 +71695,7,2,2,54,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,1,1,NA,1,2,2,1,2,1,1,2,2,1,14680.520497,14758.150245,3,91,6,6,1.34,4,4,0,2,0,1,52,2,3,1,1 +71696,7,1,2,58,NA,5,6,NA,NA,NA,2,NA,2,2,4,NA,1,2,NA,1,2,1,1,2,1,NA,NA,NA,NA,12649.084278,0,3,90,12,12,NA,4,4,0,0,0,2,58,2,1,2,NA +71697,7,2,1,74,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,NA,15176.622228,16685.078243,1,101,4,4,1.16,2,2,0,0,2,1,74,1,1,1,2 +71698,7,2,2,46,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,127315.335607,133282.596235,1,91,14,14,4.03,4,4,0,2,0,1,52,1,4,1,5 +71699,7,2,2,15,NA,2,2,1,15,184,NA,NA,2,1,4,9,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,15809.066118,17342.845429,2,93,3,3,0.52,5,5,0,2,0,1,41,2,4,1,4 +71700,7,2,2,1,16,5,6,1,NA,17,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5610.22155,6105.185511,2,92,15,15,5,3,3,1,0,0,1,39,2,5,1,5 +71701,7,2,2,17,NA,3,3,1,17,210,2,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,113907.203714,124196.980527,1,94,8,8,1.67,5,5,1,2,0,1,52,1,4,1,4 +71702,7,2,2,70,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,2,NA,1,2,2,1,2,2,1,2,2,NA,12669.609493,13517.506264,2,98,99,99,NA,1,1,0,0,1,2,70,1,3,2,NA +71703,7,2,1,53,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,NA,NA,NA,NA,26240.791307,26334.983911,1,90,4,4,1.34,1,1,0,0,0,1,53,1,4,6,NA +71704,7,2,1,77,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,71070.181743,73766.510327,1,95,4,4,1.12,2,2,0,0,2,2,78,1,4,1,2 +71705,7,2,1,67,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,1,14488.953694,14771.336069,3,92,3,3,0.95,2,2,0,0,2,2,63,1,4,1,1 +71706,7,2,2,30,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,4,2,1,2,2,1,2,2,1,2,2,1,25423.189953,34604.094756,2,98,2,2,0.34,2,2,0,1,0,2,30,1,4,4,NA +71707,7,2,2,7,NA,4,4,1,7,91,NA,NA,1,1,NA,2,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11195.065587,11638.702248,2,96,13,13,NA,4,4,1,1,0,2,40,1,3,77,NA +71708,7,2,1,64,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,6612.194774,6663.917441,2,99,5,5,1.88,1,1,0,0,1,1,64,1,5,5,NA +71709,7,2,2,45,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,40760.712736,41570.695949,1,98,3,3,0.73,2,2,0,0,0,1,49,1,2,1,2 +71710,7,2,1,68,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,8491.292032,8557.713588,1,96,15,15,5,2,2,0,0,2,1,68,1,3,1,4 +71711,7,2,1,3,NA,4,4,1,3,43,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10273.522239,11328.238204,1,100,14,6,1.85,3,2,1,0,0,1,33,1,5,5,NA +71712,7,2,2,53,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,19927.035776,20217.558558,2,96,8,8,3.67,2,2,0,0,0,1,56,2,5,1,5 +71713,7,2,1,17,NA,5,6,2,17,213,2,NA,2,1,4,12,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,8965.57404,9581.867503,1,90,15,15,5,5,5,0,3,0,2,46,2,4,1,5 +71714,7,2,1,80,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,29470.441678,31861.649147,1,103,6,6,1.98,2,2,0,0,2,1,80,1,5,1,4 +71715,7,2,2,47,NA,4,4,2,NA,NA,2,NA,2,2,6,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,21969.841763,21566.078744,1,96,14,14,5,2,2,0,0,0,2,47,2,4,5,NA +71716,7,2,2,21,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,14516.765165,13843.248577,3,90,15,15,4.89,5,5,0,0,0,2,57,2,3,1,3 +71717,7,2,2,27,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,5,2,1,2,2,1,2,2,1,2,2,1,23255.074483,22360.893796,2,98,4,4,1.29,2,2,0,1,0,2,27,1,2,5,NA +71718,7,2,2,68,NA,4,4,2,NA,NA,2,NA,2,2,4,NA,4,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,9644.668529,10075.292662,1,93,3,3,1.1,1,1,0,0,1,2,68,2,4,1,NA +71719,7,2,1,59,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,1,5,NA,1,2,2,1,2,2,1,2,2,1,26135.885159,26946.665552,2,101,2,2,0.74,1,1,0,0,0,1,59,1,1,5,NA +71720,7,1,1,80,NA,3,3,NA,NA,NA,1,2,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,6882.452425,0,1,99,3,3,1.19,1,1,0,0,1,1,80,1,5,2,NA +71721,7,2,2,11,NA,3,3,2,11,138,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,73810.484644,74865.697805,1,94,10,10,2.67,5,5,0,3,0,1,40,1,5,1,2 +71722,7,2,2,48,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,4,NA,1,2,2,1,2,2,1,2,2,1,19258.69251,18731.627868,2,99,12,3,1.16,6,1,0,0,0,2,57,1,5,2,NA +71723,7,2,2,5,NA,5,6,2,6,72,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5520.445386,5614.569811,2,100,15,15,4.83,4,4,1,1,0,1,43,2,5,1,5 +71724,7,2,1,54,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,37557.946192,39249.822004,2,102,99,3,1.29,3,1,0,0,1,1,61,NA,NA,5,NA +71725,7,2,1,24,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,9177.295801,9548.31812,2,92,15,3,0.92,3,1,0,0,0,2,25,1,5,5,NA +71726,7,2,2,5,NA,4,4,2,5,70,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9268.093277,9507.318489,1,99,3,3,0.82,2,2,1,0,0,2,29,1,4,4,NA +71727,7,1,2,11,NA,5,6,NA,NA,NA,NA,NA,1,1,NA,5,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,8851.712341,0,1,92,5,5,0.63,7,7,0,4,1,1,60,NA,NA,1,NA +71728,7,2,2,61,NA,2,2,1,NA,NA,2,NA,2,1,3,NA,5,1,NA,2,2,2,1,2,2,1,2,2,2,11291.029617,11762.265953,2,102,14,14,5,2,2,0,0,2,1,68,1,4,1,5 +71729,7,2,1,33,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,16214.132654,20271.082789,3,90,8,8,3.3,2,2,0,0,1,2,64,2,2,1,NA +71730,7,2,2,40,NA,2,2,2,NA,NA,2,NA,2,2,3,NA,1,3,2,2,2,2,2,2,2,1,2,2,2,33737.181071,33913.1176,2,91,99,99,NA,6,6,1,3,0,2,20,2,2,5,NA +71731,7,1,2,24,NA,5,6,NA,NA,NA,2,NA,2,1,4,NA,5,5,3,1,2,2,1,2,2,NA,NA,NA,NA,15265.136017,0,1,93,15,5,1.84,3,1,0,0,0,2,24,2,5,5,NA +71732,7,2,1,63,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,1,6,NA,2,2,2,2,2,2,1,2,2,2,10596.142548,10856.489537,1,94,12,3,1.07,4,1,0,0,1,2,37,NA,NA,6,NA +71733,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,1,2,NA,1,2,2,1,2,2,1,2,2,NA,24816.484998,26631.048773,1,91,3,3,1.33,1,1,0,0,1,1,80,1,1,2,NA +71734,7,2,1,5,NA,4,4,1,5,65,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7311.663111,7613.781996,2,93,6,6,1.15,5,5,3,1,0,1,29,1,3,5,NA +71735,7,2,2,67,NA,2,2,1,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,1,14204.126838,15368.918135,2,98,4,4,1.34,2,2,0,0,2,1,66,1,1,1,1 +71736,7,2,1,74,NA,3,3,1,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,1,2,1,2,2,1,2,2,NA,62359.83753,66231.994715,1,94,14,14,5,2,2,0,0,2,1,74,1,4,1,4 +71737,7,2,2,36,NA,1,1,1,NA,NA,2,NA,2,2,3,NA,1,5,2,2,2,2,2,2,2,2,2,2,2,45655.090694,49537.803198,3,92,4,4,0.67,4,4,0,3,0,2,36,2,1,5,NA +71738,7,1,2,80,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,NA,NA,NA,NA,47254.485787,0,1,90,8,8,4.21,1,1,0,0,1,2,80,1,4,2,NA +71739,7,2,1,80,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,NA,13116.035678,14391.817492,2,91,4,4,1.02,2,2,0,0,2,1,80,1,4,1,2 +71740,7,2,2,20,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,NA,NA,NA,1,2,2,1,20443.961017,19438.354372,2,99,3,3,0.44,5,5,1,1,0,2,53,1,4,1,3 +71741,7,2,1,63,NA,2,2,1,NA,NA,2,NA,2,2,2,NA,5,3,NA,2,2,2,1,2,2,2,2,2,2,6449.12882,6552.435629,2,93,3,3,0.9,1,1,0,0,1,1,63,2,5,3,NA +71742,7,2,1,0,10,5,6,2,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,5441.212985,5743.59084,1,93,8,8,1.2,7,7,1,1,1,1,24,2,2,5,NA +71743,7,2,2,0,4,1,1,1,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,2,2,2,NA,NA,NA,NA,8359.077295,8418.658174,3,92,6,6,1.06,5,5,2,0,0,2,54,2,1,77,NA +71744,7,2,2,40,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,144726.059187,145423.66071,2,98,15,15,4.17,6,6,1,1,0,2,40,1,4,1,4 +71745,7,2,2,21,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,5,2,1,2,2,1,2,2,1,2,2,1,130601.953362,132156.64994,2,91,15,15,5,4,4,0,0,0,1,54,1,5,1,NA +71746,7,2,2,18,NA,3,3,1,18,219,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,32725.110579,34226.88515,2,92,3,1,0.28,2,1,0,0,0,2,18,1,4,NA,NA +71747,7,2,1,7,NA,5,7,1,7,88,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11800.806722,11886.381633,1,100,9,9,2.78,4,4,0,2,0,1,39,1,5,1,5 +71748,7,2,2,36,NA,1,1,2,NA,NA,2,NA,2,2,4,NA,3,6,2,2,2,2,2,2,2,2,2,1,2,32910.619435,32637.844845,1,90,2,1,0.17,5,2,0,1,0,1,25,2,2,6,NA +71749,7,2,2,0,4,1,1,2,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7011.218293,6863.710472,2,97,6,6,1.84,2,2,1,0,0,2,27,1,4,5,NA +71750,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,NA,19552.617734,21912.600615,2,92,4,4,1.12,2,2,0,0,1,2,80,1,5,2,NA +71751,7,2,2,42,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,2,1,2,2,1,2,2,1,2,2,1,110070.015649,117535.388004,3,91,14,14,3.4,4,4,0,2,0,1,40,1,4,1,4 +71752,7,2,1,36,NA,1,1,1,NA,NA,2,NA,2,2,4,NA,2,1,NA,1,2,2,1,2,2,2,2,2,2,45660.210546,48177.324946,1,101,9,9,2.88,3,3,1,0,0,1,36,2,2,1,4 +71753,7,2,2,80,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,NA,33147.414266,37148.276517,2,94,14,14,5,2,2,0,0,1,2,80,1,4,2,NA +71754,7,2,1,0,0,3,3,1,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,20173.318836,21596.406788,2,103,15,15,5,4,4,2,0,0,1,36,2,4,1,5 +71755,7,2,1,22,NA,2,2,1,NA,NA,2,NA,2,2,3,NA,2,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,38474.772527,42632.210531,2,93,7,3,0.9,3,1,0,0,0,1,25,2,4,5,NA +71756,7,2,1,63,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,133262.624177,131902.330801,1,98,9,9,3.97,2,2,0,0,2,1,63,1,5,1,4 +71757,7,2,1,23,NA,5,6,1,NA,NA,2,NA,2,2,3,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,13254.861315,15747.113823,1,101,8,8,4.48,1,1,0,0,0,1,23,2,5,5,NA +71758,7,2,2,24,NA,2,2,2,NA,NA,2,NA,2,1,3,NA,4,6,2,2,2,2,2,2,2,1,2,2,2,30253.427014,30121.660039,2,90,6,6,0.66,7,7,2,2,0,2,24,2,4,6,NA +71759,7,2,1,16,NA,4,4,1,17,204,NA,NA,1,1,NA,10,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,17606.165994,17558.40257,2,101,8,8,2.7,3,3,0,1,0,1,53,1,4,1,2 +71760,7,2,2,60,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,14994.337564,16150.13007,1,100,8,8,2.36,3,3,1,0,1,2,60,1,3,3,NA +71761,7,2,1,38,NA,1,1,1,NA,NA,2,NA,2,7,77,NA,2,1,NA,2,2,2,1,2,2,NA,NA,NA,NA,32907.512068,32659.148672,2,92,12,12,NA,7,7,0,1,2,2,64,2,1,2,NA +71762,7,2,1,12,NA,3,3,1,12,155,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,30943.024697,32205.010072,1,101,4,4,0.58,6,6,0,4,0,2,41,1,3,5,NA +71763,7,2,1,40,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,109309.268477,116308.99629,3,91,14,14,3.4,4,4,0,2,0,1,40,1,4,1,4 +71764,7,2,1,33,NA,5,6,1,NA,NA,2,NA,2,1,5,NA,4,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,20181.692021,21173.351412,1,92,12,12,NA,4,4,1,1,0,1,33,2,4,1,4 +71765,7,2,1,39,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,19144.719218,23354.203452,1,101,8,8,1.81,5,5,2,0,1,2,37,2,4,1,2 +71766,7,2,2,38,NA,2,2,1,NA,NA,2,NA,2,1,2,NA,3,1,3,2,2,2,2,2,2,NA,NA,NA,NA,40476.413979,41456.006766,2,93,5,5,0.87,4,4,1,1,0,1,41,2,5,1,3 +71767,7,2,1,38,NA,1,1,2,NA,NA,2,NA,1,1,NA,NA,5,3,NA,1,2,2,1,2,2,1,2,2,1,39133.405322,40210.578118,1,91,12,8,4.59,5,1,0,2,0,1,38,1,5,3,NA +71768,7,2,2,7,NA,3,3,2,7,88,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,24070.467912,25563.654853,1,95,15,15,3.62,7,7,2,4,0,1,59,1,5,1,2 +71769,7,2,1,24,NA,2,2,2,NA,NA,2,NA,2,2,3,NA,4,5,NA,2,2,2,2,2,2,2,2,2,2,35669.2076,36155.406423,2,94,14,8,3.06,5,2,0,0,0,1,24,2,4,5,NA +71770,7,2,2,64,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,10687.292889,11164.469085,2,99,3,3,0.75,2,2,0,0,1,2,64,1,4,3,NA +71771,7,2,1,3,NA,1,1,2,3,47,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,18363.136017,19674.774959,1,91,4,4,0.86,3,3,1,0,0,2,54,1,4,3,NA +71772,7,2,2,52,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,NA,NA,NA,NA,37518.850453,37204.255172,1,98,3,3,1.18,1,1,0,0,0,2,52,1,4,3,NA +71773,7,2,1,53,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,4,3,NA,1,2,2,1,2,2,1,2,2,1,23775.734331,23918.947415,2,96,12,99,NA,2,1,0,0,1,1,53,1,4,3,NA +71774,7,1,1,2,NA,1,1,NA,NA,NA,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,10412.950357,0,1,90,15,15,5,5,5,1,1,0,1,32,2,1,1,4 +71775,7,2,1,62,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,28216.191929,29365.059825,1,101,6,6,1.52,3,3,0,1,1,1,62,1,2,1,3 +71776,7,2,2,0,10,1,1,1,NA,11,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,5328.475628,5508.797375,1,103,13,13,NA,6,6,1,2,0,1,42,2,9,1,9 +71777,7,2,2,77,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,9807.668192,10541.248354,2,95,5,5,0.87,4,4,0,0,2,2,77,1,2,1,1 +71778,7,2,1,20,NA,2,2,2,NA,NA,2,NA,2,1,3,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,43798.832177,56306.768819,1,90,3,3,0.79,2,2,0,0,1,1,70,2,2,1,NA +71779,7,2,1,19,NA,4,4,2,19,239,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11125.932433,11147.929312,1,96,6,6,1.21,4,4,0,2,0,2,41,1,4,4,NA +71780,7,2,1,10,NA,4,4,2,10,128,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,14125.862146,14370.909235,1,97,15,15,5,4,4,0,2,0,1,48,1,5,1,5 +71781,7,2,2,52,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,17152.714252,16683.285229,1,102,12,12,NA,7,7,3,2,0,2,52,1,4,5,NA +71782,7,2,1,5,NA,5,6,1,5,70,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,10498.222836,11004.769407,1,100,15,15,5,4,4,2,0,0,1,39,2,5,1,5 +71783,7,1,1,12,NA,5,6,NA,NA,NA,NA,NA,2,1,3,5,NA,NA,NA,1,1,1,1,2,1,NA,NA,NA,NA,6174.283826,0,2,92,77,77,NA,5,5,0,1,2,2,80,NA,NA,1,1 +71784,7,2,2,24,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,41018.498876,42180.331054,2,98,6,6,1.07,5,5,3,0,0,2,24,1,3,1,3 +71785,7,2,1,64,NA,4,4,1,NA,NA,1,1,1,1,NA,NA,2,3,NA,1,2,2,1,2,2,1,2,2,1,7101.739553,7433.956549,2,100,77,77,NA,1,1,0,0,1,1,64,1,2,3,NA +71786,7,2,2,42,NA,5,7,1,NA,NA,2,NA,2,1,7,NA,5,4,2,1,2,2,1,2,2,1,2,2,1,18588.235275,19331.159141,2,96,15,15,5,3,3,0,2,0,2,42,2,5,4,NA +71787,7,2,2,50,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,16859.368198,17492.963343,1,99,13,13,NA,4,4,1,0,0,2,26,1,4,4,NA +71788,7,2,1,6,NA,1,1,1,6,82,NA,NA,1,1,NA,0,NA,NA,NA,2,1,1,2,2,1,NA,NA,NA,NA,14880.007592,15997.505807,3,92,4,4,0.66,4,4,0,1,0,1,52,2,1,1,1 +71789,7,2,2,50,NA,5,7,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,13149.417265,14101.663559,2,103,15,15,5,3,3,0,0,0,2,50,1,4,1,4 +71790,7,2,2,11,NA,5,7,1,11,139,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,10332.067017,11032.916236,1,100,9,9,2.22,5,5,0,3,0,2,52,1,4,1,4 +71791,7,2,1,18,NA,1,1,1,18,221,2,NA,1,1,NA,12,NA,NA,NA,2,2,2,1,2,2,1,2,2,2,32262.881978,32260.04446,2,102,8,8,2.01,4,4,0,0,0,2,48,2,4,3,NA +71792,7,2,1,34,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,69548.324117,71540.223881,2,95,6,6,2.69,1,1,0,0,0,1,34,1,5,5,NA +71793,7,2,2,57,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,170311.62251,168883.560827,3,91,15,15,5,2,2,0,0,0,2,57,1,5,1,5 +71794,7,2,1,4,NA,4,4,2,4,57,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8973.990262,9527.959827,2,101,7,7,1.3,5,5,2,0,1,2,50,1,4,1,3 +71795,7,2,2,8,NA,5,7,1,9,108,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,17706.623308,17924.842987,1,94,2,2,0.3,5,5,1,2,0,1,23,1,1,6,NA +71796,7,2,2,45,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,2,NA,1,2,2,1,2,2,1,2,2,1,135834.019526,140154.312816,2,92,10,10,3.51,3,3,0,0,0,1,24,1,4,5,NA +71797,7,2,1,80,NA,3,3,1,NA,NA,1,1,1,1,NA,NA,3,2,NA,1,2,2,NA,NA,NA,1,2,2,NA,26771.485907,29740.715741,2,100,NA,NA,NA,4,4,0,0,2,2,51,NA,NA,1,NA +71798,7,2,1,61,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,8491.292032,8557.713588,1,96,15,15,5,2,2,0,0,2,2,62,1,4,1,2 +71799,7,2,1,59,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,151766.599459,151581.541662,3,91,14,1,0.41,2,1,0,0,0,1,47,NA,NA,5,NA +71800,7,2,2,33,NA,1,1,1,NA,NA,2,NA,2,1,6,NA,2,1,2,2,2,2,1,2,2,1,2,2,1,45655.090694,44423.220436,3,92,7,7,1.3,5,5,1,2,0,2,33,2,2,1,1 +71801,7,2,2,4,NA,1,1,1,4,56,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,17887.570772,19748.358154,1,92,10,10,3.04,4,4,1,1,0,1,32,1,3,1,2 +71802,7,2,1,53,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,NA,1,2,2,1,2,2,1,2,2,1,27250.100481,27216.872857,1,99,6,3,0.92,2,1,0,0,0,2,50,1,3,6,NA +71803,7,2,2,52,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,16063.886913,15924.431895,2,96,4,4,0.57,6,6,0,3,0,2,29,1,3,4,NA +71804,7,2,2,9,NA,1,1,1,9,110,NA,NA,1,1,NA,2,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,13616.85154,13950.045541,1,102,6,6,0.96,5,5,0,2,0,1,32,2,2,1,3 +71805,7,2,1,22,NA,5,6,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,1,2,2,1,14313.345971,14977.822328,3,91,7,7,1.33,6,6,0,0,2,2,51,2,5,1,5 +71806,7,2,2,12,NA,4,4,1,12,147,NA,NA,1,1,NA,6,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12412.374308,12473.945857,2,96,4,4,0.57,6,6,0,3,0,2,29,1,3,4,NA +71807,7,2,1,12,NA,2,2,1,12,147,NA,NA,1,1,NA,5,NA,NA,NA,2,1,2,2,2,2,2,2,2,2,20560.901695,20667.963739,2,96,7,7,1.57,4,4,0,2,0,1,40,2,2,1,5 +71808,7,2,1,12,NA,1,1,1,12,147,NA,NA,1,1,NA,5,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,24228.858782,24355.020132,2,102,7,7,1.53,5,5,0,3,0,1,43,2,2,1,4 +71809,7,2,1,5,NA,4,4,1,5,65,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,14467.4421,14643.906573,2,101,4,4,1.22,2,2,1,0,0,2,31,1,4,77,NA +71810,7,2,1,33,NA,2,2,2,NA,NA,2,NA,2,2,2,NA,3,1,NA,2,2,2,2,2,2,2,2,2,2,34887.439952,34624.133414,2,94,14,4,1.47,5,1,0,0,0,1,24,2,4,5,NA +71811,7,2,2,53,NA,5,6,2,NA,NA,2,NA,2,1,99,NA,1,3,NA,1,2,1,1,2,2,1,1,1,3,14813.321679,14891.653673,2,94,77,77,NA,6,6,2,0,0,2,18,1,3,NA,NA +71812,7,2,1,3,NA,2,2,1,3,38,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,11179.43727,11533.315753,2,93,14,14,2.91,6,6,2,0,1,2,74,NA,NA,2,NA +71813,7,2,1,36,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,17091.959624,18613.193853,1,90,15,15,5,4,4,2,0,0,1,36,1,5,1,5 +71814,7,2,1,3,NA,1,1,1,3,45,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,20874.345556,22365.354744,3,92,14,14,3.25,4,4,2,0,0,2,33,1,5,1,5 +71815,7,2,1,0,0,2,2,2,NA,1,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,2,2,2,NA,NA,NA,NA,4857.494088,5095.295928,2,90,4,4,0.57,5,5,1,0,2,2,80,2,1,2,NA +71816,7,2,1,2,NA,1,1,1,2,34,NA,NA,1,1,NA,NA,NA,NA,NA,2,1,2,1,2,2,NA,NA,NA,NA,14457.854197,14219.651494,1,92,6,6,1.34,4,4,1,0,0,1,25,2,3,1,3 +71817,7,2,1,8,NA,4,4,1,8,103,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8294.996898,8761.908989,2,100,8,8,1.1,7,7,3,3,0,2,58,1,3,5,NA +71818,7,2,1,8,NA,1,1,1,8,105,NA,NA,1,1,NA,2,NA,NA,NA,2,1,2,2,2,2,1,2,2,1,11036.458246,10927.552283,1,102,13,13,NA,6,6,1,2,0,2,36,2,4,6,NA +71819,7,2,2,25,NA,1,1,1,NA,NA,2,NA,2,2,3,NA,4,1,2,2,2,2,1,2,2,1,2,1,2,51600.2972,52672.714014,1,101,9,9,2.88,3,3,1,0,0,1,36,2,2,1,4 +71820,7,2,1,47,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,138834.18124,139448.476692,1,100,15,15,5,5,5,0,3,0,1,47,1,5,1,5 +71821,7,2,2,50,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,NA,NA,NA,NA,16181.169973,16286.716901,2,100,6,6,2.04,2,2,0,0,0,2,50,1,2,1,3 +71822,7,2,2,19,NA,4,4,1,19,229,2,NA,1,1,NA,15,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,18163.985724,18749.311901,2,101,2,1,0.32,2,1,0,0,0,2,19,1,4,NA,NA +71823,7,2,2,4,NA,3,3,1,4,51,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,87448.870731,96516.512941,2,94,14,14,4.71,3,3,1,0,0,1,35,1,5,1,5 +71824,7,2,1,48,NA,2,2,2,NA,NA,2,NA,2,2,3,NA,5,1,NA,2,2,2,1,2,2,2,2,2,2,44123.284536,45145.647683,2,91,3,3,0.73,3,3,0,0,0,2,22,2,2,5,NA +71825,7,2,2,53,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,102322.335011,107871.941405,2,100,10,10,3.13,4,4,0,0,1,2,53,1,2,1,2 +71826,7,2,2,77,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,2,2,NA,1,2,2,1,2,2,1,2,2,NA,30880.887565,31700.101057,1,98,1,1,0.04,1,1,0,0,1,2,77,1,2,2,NA +71827,7,2,1,14,NA,5,6,1,14,169,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7669.677276,8194.5967,2,92,15,15,4.59,4,4,0,2,0,2,48,1,5,1,5 +71828,7,2,2,49,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,34954.173075,38933.293222,2,98,7,7,1.97,4,4,0,1,0,1,40,1,3,1,3 +71829,7,2,1,57,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,4,NA,1,2,2,1,2,2,1,2,2,1,23857.322871,24256.958876,2,103,2,2,0.46,2,2,0,0,0,1,57,1,2,4,NA +71830,7,2,2,34,NA,1,1,1,NA,NA,2,NA,2,2,3,NA,3,6,2,2,2,2,2,2,2,NA,NA,NA,NA,34898.504426,34609.253559,1,100,8,3,0.68,6,3,1,0,0,1,33,2,3,6,NA +71831,7,2,2,41,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,3,1,2,1,2,2,1,2,2,1,2,2,1,33767.584626,40865.10406,2,102,14,14,2.44,7,7,0,2,1,2,71,1,3,3,NA +71832,7,2,2,49,NA,1,1,2,NA,NA,2,NA,2,1,6,NA,1,3,NA,2,2,2,1,2,2,2,2,2,2,40880.818805,41857.641766,1,101,5,5,0.51,7,7,0,3,2,1,75,2,1,1,1 +71833,7,2,2,30,NA,5,6,2,NA,NA,2,NA,2,2,2,NA,5,1,2,1,2,1,1,2,2,1,2,2,1,20963.809917,22126.306943,1,93,10,10,4.76,2,2,0,0,0,1,29,2,5,1,5 +71834,7,2,2,0,5,4,4,2,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,3861.876549,4016.370213,1,96,8,8,1.61,6,6,3,0,0,1,33,2,5,1,4 +71835,7,2,2,17,NA,4,4,2,17,207,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,11133.192774,11654.909373,3,91,2,2,0.25,4,4,0,2,0,2,35,1,3,5,NA +71836,7,2,1,65,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,6036.688933,6083.909812,2,99,15,15,5,2,2,0,0,2,1,65,1,4,1,5 +71837,7,2,2,13,NA,2,2,2,13,161,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13824.001771,14551.102227,2,90,12,12,NA,4,4,0,2,0,2,38,2,4,1,4 +71838,7,2,2,10,NA,4,4,2,10,126,NA,NA,1,1,NA,4,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,7814.742747,8106.808519,2,95,4,4,0.65,4,4,1,2,0,2,27,1,3,5,NA +71839,7,2,2,57,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,160743.928829,165029.101567,1,95,8,6,2.04,4,2,0,1,0,2,57,1,5,5,NA +71840,7,2,2,11,NA,2,2,2,11,134,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,13450.921832,14026.252281,1,90,6,6,0.81,6,6,0,3,0,2,45,1,4,1,2 +71841,7,2,1,45,NA,2,2,1,NA,NA,2,NA,2,1,8,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,28726.575428,29281.498535,2,100,14,14,3.36,4,4,1,1,0,1,45,2,5,1,2 +71842,7,2,1,6,NA,2,2,2,7,84,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,18107.947773,18211.90239,1,97,7,7,2.2,3,3,0,1,0,1,34,2,3,1,4 +71843,7,2,1,28,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,NA,NA,NA,1,2,2,1,11507.810748,11454.924313,2,99,13,13,NA,6,6,2,1,0,2,31,1,4,6,NA +71844,7,2,2,43,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,1,1,2,1,2,2,1,2,2,1,2,2,1,19943.783243,19397.969296,2,95,2,2,0.4,2,2,0,0,0,2,43,1,1,1,NA +71845,7,2,1,8,NA,5,7,2,8,97,NA,NA,1,1,NA,1,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,8246.426933,10295.491756,1,99,10,10,3.99,3,3,0,1,0,1,36,2,2,6,NA +71846,7,2,1,72,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,NA,15429.860615,16015.253437,1,98,12,12,NA,3,3,0,0,2,1,72,1,5,1,3 +71847,7,2,1,37,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,94644.050918,104631.781207,2,91,15,15,5,3,3,1,0,0,1,37,1,5,1,5 +71848,7,2,1,26,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,10559.047286,11105.574109,2,92,8,6,2.75,2,1,0,0,0,1,26,2,5,5,NA +71849,7,2,2,56,NA,2,2,2,NA,NA,2,NA,2,1,7,NA,3,4,NA,2,2,2,2,2,2,1,2,2,2,21097.069797,24201.517172,2,90,3,3,1.1,1,1,0,0,0,2,56,2,3,4,NA +71850,7,2,2,6,NA,4,4,1,7,84,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8437.316833,8584.499702,2,96,4,4,0.4,7,7,3,2,0,2,25,1,2,5,NA +71851,7,2,1,17,NA,1,1,1,17,213,2,NA,2,2,3,11,NA,NA,NA,2,2,2,2,2,2,1,2,2,1,29234.272259,28953.402615,3,92,4,4,0.67,4,4,0,3,0,2,36,2,1,5,NA +71852,7,2,1,19,NA,5,7,1,19,232,2,NA,1,1,NA,13,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,24231.355333,25219.610889,2,100,5,5,1.3,3,3,0,1,0,2,46,1,3,2,NA +71853,7,2,1,14,NA,4,4,1,14,169,NA,NA,1,1,NA,7,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,12046.265019,11945.683979,1,102,7,7,1.57,4,4,0,2,0,2,33,1,4,1,4 +71854,7,2,2,0,7,4,4,2,NA,8,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,3756.765605,3760.183196,1,99,4,4,0.53,7,7,3,1,0,2,26,1,1,5,NA +71855,7,2,2,62,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,1,60351.409248,61337.452183,2,101,3,3,0.98,2,2,0,0,2,1,62,1,4,1,3 +71856,7,2,2,32,NA,5,6,2,NA,NA,2,NA,2,2,3,NA,5,1,2,1,2,2,1,2,2,1,2,2,1,16369.916397,16695.550655,1,101,10,10,3.67,3,3,1,0,0,1,36,2,5,1,5 +71857,7,2,1,39,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,78529.577822,81088.445647,1,98,15,15,5,5,5,0,3,0,2,41,1,5,6,NA +71858,7,2,1,27,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,NA,NA,NA,1,2,2,1,33510.443506,34234.256724,1,98,4,4,0.89,3,3,0,0,1,2,55,1,5,1,NA +71859,7,2,2,0,9,4,4,2,NA,10,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,NA,NA,NA,NA,NA,NA,NA,3516.231705,3777.543312,2,99,2,2,0.19,7,7,3,1,0,2,43,1,2,4,NA +71860,7,2,1,28,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,16436.212192,16355.203111,1,99,12,12,NA,2,2,0,0,0,1,28,1,5,5,NA +71861,7,2,2,68,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,1,2,2,1,11862.436765,15907.964192,1,90,3,3,1.07,1,1,0,0,1,2,68,1,2,5,NA +71862,7,2,2,54,NA,5,6,1,NA,NA,2,NA,2,2,6,NA,1,4,NA,1,1,2,1,2,2,NA,NA,NA,NA,10489.35334,11245.538838,3,91,14,14,2.5,6,6,1,1,1,2,37,2,2,1,5 +71863,7,2,1,38,NA,3,3,2,NA,NA,1,2,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,67281.364849,72381.052566,2,100,15,15,5,3,3,0,1,0,1,38,1,4,1,4 +71864,7,2,1,18,NA,2,2,2,18,221,2,NA,1,1,NA,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,16033.31661,16386.200415,2,90,8,8,2.01,4,4,0,0,1,2,67,2,4,2,NA +71865,7,2,2,1,23,4,4,2,NA,24,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6247.52442,6810.692829,1,99,7,7,1.06,7,7,3,1,0,1,38,1,4,6,NA +71866,7,2,1,32,NA,1,1,1,NA,NA,2,NA,2,2,3,NA,4,3,NA,2,2,2,1,2,2,2,2,2,2,37080.526463,37974.333878,2,103,12,77,NA,2,1,0,0,0,1,46,2,4,1,NA +71867,7,2,2,26,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,5,5,2,1,2,2,1,2,2,1,2,2,1,11696.173591,12753.148801,1,93,10,10,3.09,4,4,0,0,1,2,41,NA,NA,1,NA +71868,7,2,1,43,NA,1,1,1,NA,NA,2,NA,2,1,6,NA,3,1,NA,2,2,2,2,2,2,1,2,2,2,35406.972937,38657.357615,3,92,9,9,2.46,4,4,0,2,0,1,43,2,3,1,4 +71869,7,2,1,69,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,130234.912635,128905.524968,1,95,8,8,2.7,3,3,0,1,2,1,69,1,5,1,3 +71870,7,2,2,41,NA,3,3,1,NA,NA,2,NA,2,1,5,NA,2,3,2,1,2,2,1,2,2,1,2,2,1,26595.398371,26621.513872,1,94,3,3,0.93,2,2,0,0,0,2,41,2,2,3,NA +71871,7,2,2,43,NA,5,6,2,NA,NA,2,NA,2,1,6,NA,3,3,2,1,2,1,1,2,1,1,2,1,NA,18255.735511,18352.270791,2,91,12,12,NA,5,5,1,1,0,1,39,NA,NA,1,NA +71872,7,2,1,77,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,NA,12468.859946,13204.521198,2,96,6,6,1.77,2,2,0,0,2,1,77,1,2,1,2 +71873,7,2,2,20,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,4,6,2,1,2,2,1,2,2,1,2,2,1,122726.905904,130163.310429,1,101,8,6,2.69,2,1,0,0,0,2,20,1,4,6,NA +71874,7,2,1,24,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,14385.653726,15564.966804,2,101,8,4,1.7,2,1,0,0,0,1,24,2,5,5,NA +71875,7,2,1,42,NA,4,4,2,NA,NA,2,NA,2,2,5,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,23766.023166,23781.059132,1,91,15,15,5,6,6,1,2,0,2,42,2,5,1,5 +71876,7,2,1,14,NA,1,1,1,14,177,NA,NA,1,1,NA,8,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,22621.505951,24307.488585,1,92,4,4,0.65,4,4,0,1,0,1,47,2,2,1,3 +71877,7,2,1,72,NA,2,2,1,NA,NA,2,NA,2,2,2,NA,2,1,NA,2,2,2,2,2,2,1,2,1,NA,14336.984082,15039.787037,2,100,99,99,NA,6,6,1,1,2,1,37,2,3,1,3 +71878,7,2,1,35,NA,2,2,1,NA,NA,2,NA,2,1,3,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,39943.378263,40565.140919,2,93,7,7,1.56,4,4,1,1,0,1,35,2,4,1,4 +71879,7,2,1,24,NA,4,4,1,NA,NA,2,NA,1,1,NA,NA,4,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,25815.880139,26556.735732,2,101,2,2,0.51,2,1,0,0,0,1,24,1,4,5,NA +71880,7,2,1,46,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,21158.364877,21285.812242,1,96,12,12,NA,2,2,0,0,0,1,46,1,4,1,5 +71881,7,2,1,20,NA,5,6,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,13370.868197,14159.618266,1,97,15,15,5,4,4,0,0,0,1,51,2,5,1,5 +71882,7,2,2,60,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,2,1,NA,1,2,2,1,2,2,1,2,2,1,12331.419303,13379.957577,2,95,3,3,0.75,2,2,0,0,2,1,60,1,2,1,2 +71883,7,2,1,42,NA,5,6,2,NA,NA,2,NA,2,2,5,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,17210.953493,17934.928395,1,91,77,77,NA,4,4,1,1,0,1,42,2,5,1,5 +71884,7,2,1,49,NA,5,6,1,NA,NA,2,NA,2,2,5,NA,1,1,NA,1,2,1,1,2,1,NA,NA,NA,NA,11601.882948,11708.549693,2,92,77,77,NA,4,4,0,0,0,1,27,2,2,5,NA +71885,7,2,1,35,NA,1,1,2,NA,NA,2,NA,2,2,5,NA,2,6,NA,2,2,2,1,2,2,2,2,2,2,31045.881083,33019.807379,2,97,4,4,0.6,6,6,2,2,0,1,35,2,2,6,NA +71886,7,2,1,61,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,5,NA,1,2,2,1,2,2,1,2,2,1,6612.194774,6870.810722,2,99,6,6,2.28,1,1,0,0,1,1,61,1,3,5,NA +71887,7,2,2,68,NA,2,2,2,NA,NA,2,NA,2,1,8,NA,1,1,NA,1,2,2,NA,NA,NA,1,2,2,1,12689.611047,13462.268549,1,90,4,4,1.12,2,2,0,0,2,1,68,2,4,1,1 +71888,7,2,2,67,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,3,3,NA,1,2,2,1,2,2,1,2,2,1,10346.035773,10764.448363,1,99,2,2,0.31,4,4,1,0,1,2,67,1,3,3,NA +71889,7,2,2,5,NA,5,7,1,5,61,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7483.230909,8143.441843,2,96,15,15,5,4,4,1,1,0,2,35,2,5,1,5 +71890,7,1,2,31,NA,3,3,NA,NA,NA,2,NA,1,1,NA,NA,3,5,3,1,2,2,1,2,2,NA,NA,NA,NA,76271.00266,0,3,91,8,8,3.4,2,2,1,0,0,2,31,1,3,5,NA +71891,7,2,2,54,NA,1,1,1,NA,NA,2,NA,2,1,7,NA,4,1,NA,2,2,2,2,2,2,2,2,2,2,30976.631116,32561.666417,2,102,9,9,3.24,3,3,0,0,0,1,54,2,4,1,4 +71892,7,2,1,0,3,4,4,2,NA,5,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,6327.979262,6425.104835,1,90,6,6,1.92,2,2,1,0,0,2,51,2,1,5,NA +71893,7,2,2,3,NA,5,7,2,3,40,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,8173.816615,8894.95474,1,97,15,15,5,3,3,1,0,0,1,40,1,3,1,5 +71894,7,2,1,11,NA,2,2,2,11,143,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,11113.498573,11364.131177,1,94,14,14,3.4,5,5,0,3,0,2,41,1,4,1,4 +71895,7,2,1,31,NA,5,6,1,NA,NA,2,NA,2,2,2,NA,5,1,NA,1,2,2,1,2,2,1,2,2,3,17165.91562,17929.203991,2,96,15,6,2.3,3,1,0,0,0,1,31,2,5,1,NA +71896,7,2,1,4,NA,4,4,2,4,59,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,9304.437652,9588.632035,2,97,14,14,3.91,4,4,1,1,0,1,38,1,4,1,5 +71897,7,2,2,68,NA,4,4,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,12331.419303,12882.003985,2,95,77,77,NA,2,2,0,0,2,1,68,1,4,1,4 +71898,7,2,2,65,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,15207.312407,15896.113669,1,92,9,9,3.97,2,2,0,0,2,2,65,1,4,1,4 +71899,7,2,2,3,NA,3,3,1,3,37,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,66833.888628,73763.947124,2,98,7,7,1.61,4,4,1,1,0,1,43,NA,NA,6,NA +71900,7,1,2,26,NA,2,2,NA,NA,NA,2,NA,1,1,NA,NA,5,5,3,1,2,2,1,2,2,NA,NA,NA,NA,55675.708832,0,1,93,3,2,0.46,2,1,0,0,0,2,26,1,5,5,NA +71901,7,2,2,48,NA,5,7,2,NA,NA,2,NA,1,1,NA,NA,4,1,NA,1,2,2,1,2,2,1,2,2,1,30442.30641,31779.541767,1,101,3,3,0.88,2,2,0,0,0,1,56,1,2,1,4 +71902,7,2,2,67,NA,5,6,2,NA,NA,2,NA,2,1,8,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,11494.286549,11937.924974,2,94,8,8,3.4,2,2,0,0,2,1,80,1,3,1,5 +71903,7,2,2,6,NA,4,4,1,6,73,NA,NA,1,1,NA,0,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,11076.064101,11514.984987,2,102,2,2,0.36,4,4,1,2,0,2,36,1,3,5,NA +71904,7,2,2,30,NA,5,6,1,NA,NA,2,NA,2,1,6,NA,4,5,2,1,2,2,1,2,1,NA,NA,NA,NA,11032.714892,11055.242776,2,92,5,5,0.64,7,7,1,2,1,1,66,2,1,1,3 +71905,7,1,2,8,NA,5,6,NA,NA,NA,NA,NA,1,1,NA,3,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,7405.452085,0,1,95,6,6,1.34,4,4,0,2,0,2,32,2,3,2,NA +71906,7,2,2,4,NA,5,6,2,4,54,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,3788.132941,4021.443194,3,90,77,77,NA,7,7,1,2,0,1,41,2,3,6,NA +71907,7,2,1,80,NA,3,3,2,NA,NA,1,1,1,1,NA,NA,3,1,NA,1,2,2,1,2,2,1,2,2,NA,47098.572584,50542.386793,1,95,9,9,4.08,2,2,0,0,2,1,80,1,3,1,NA +71908,7,2,2,66,NA,3,3,1,NA,NA,2,NA,1,1,NA,NA,5,2,NA,1,2,2,1,2,2,1,2,2,1,93265.413087,94789.216803,2,98,10,10,4.55,2,2,0,0,1,2,66,1,5,2,NA +71909,7,2,1,28,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,2,5,NA,1,2,2,1,2,2,NA,NA,NA,NA,37911.437415,38428.199561,2,103,2,2,0.46,2,2,0,0,0,1,57,1,2,4,NA +71910,7,2,2,0,5,3,3,2,NA,6,NA,NA,1,1,NA,NA,NA,NA,NA,1,1,2,1,2,2,NA,NA,NA,NA,17151.556324,17621.071345,1,98,14,14,3.37,5,5,1,2,0,1,27,1,5,1,5 +71911,7,2,1,27,NA,1,1,1,NA,NA,2,NA,1,1,NA,NA,5,1,NA,1,2,2,1,2,2,1,2,2,1,42165.369652,43039.787442,2,102,14,14,3.25,5,5,2,0,0,1,27,1,5,1,5 +71912,7,2,1,40,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,1,1,NA,1,2,2,1,2,2,1,2,2,1,19633.637051,20770.138122,1,98,6,6,1.73,3,3,0,1,0,2,39,1,4,1,1 +71913,7,2,2,18,NA,5,6,1,18,226,2,NA,2,1,4,11,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,7382.152016,8028.485773,1,94,14,14,2.78,6,5,0,2,1,1,61,1,4,1,5 +71914,7,2,2,10,NA,3,3,2,10,131,NA,NA,1,1,NA,5,NA,NA,NA,1,1,2,1,2,2,1,2,2,1,60197.256541,63931.531988,2,94,14,14,2.63,6,6,1,3,0,1,39,1,4,1,4 +71915,7,2,1,60,NA,3,3,2,NA,NA,2,NA,1,1,NA,NA,5,5,NA,1,2,2,1,2,2,1,2,2,1,88961.259215,91446.591982,3,90,10,10,5,1,1,0,0,1,1,60,1,5,5,NA +71916,7,2,1,16,NA,3,3,1,16,198,NA,NA,1,1,NA,9,NA,NA,NA,1,2,2,1,2,2,1,2,2,1,24446.632088,24751.360191,1,94,4,4,0.79,3,3,0,1,0,1,49,1,2,3,NA diff --git a/pandas/io/tests/data/DRXFCD_G.XPT b/pandas/io/tests/data/DRXFCD_G.XPT new file mode 100644 index 0000000000000000000000000000000000000000..15de11e8f9f4960bf4b2ed96c90c497ce02e8b32 GIT binary patch literal 2195200 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

    u5W(- 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≤=f=|1Hn!PrVwRWS`tyVGrfzOpa#Sx%vGE_4w&xH0w@|jFgd*6S6Z;!?^ zjP4U^ojt{Ypc7KLGpqk%XzLGEzy8$~`0Q3TH{sRciwg3u!WwUOtL1L%QDd!HH8B}7 zF?Eb>hIadhhj8imEh>bs)i|6DPG)0je_&zdVPYbgyBQ+n=jRM2KU>?C_KsJ*Hcf0C znoMd)@fxvoi+~$-UDgH}w$%}_y~_Bw@zA)%Z4SK-+b#DC?fr}4 z$e1unZ0{ocimk#|HS6>y09u7@|UL=G!R`M@R5oh!Yw!x3{VWh|i_UhpSiS+mU>@dSz~JRSlHy z3~wyJXBUf$U3h;)DVwcQt7c}nsa*_E_u>5!1#FIc<1;Hmd#m~=_`K$T_|yRi!xJ;k zSTVvq*4me|Ay(Foy%lMg?T+jY*)+$Np0#uM;>Q=R*${s#ZhI@_^Qpii_=uQHA3pr8 zxc#yD*zR{fKK!k??X8l}!r?=cA7AOAHKfP|mcJaq zhq9g!KL$WffU68;@Voa2K9uu>h%o?i0$gP%gI{~AdJTNO%7FZEgCnLtV%nVku4spX zV!||>GP^nrK3}sS{i5yD-3I*c9g_!$8|7B1v}?4RmAYBnxn)~!EW~1&jW%r)-ygx_ zKGktpmyE#YJq1U8gv~*8FRj8#w5!}KkzbKTPRWl&J`wVx8XZ2O_a-bj?7TEo$cAFAas9>qR;^osMjwQ07I(G;JO!$(Id&Tm6}7A`)_1;k@jk?Uo96p^2V=Lt-;!-tJu zuJFQJVys897pB#;{X<)=_=8#QSnE5d2e0lk@cF%h%7^gWvZ>sHp2_VVv8Ip5$-{@1 z7i=5MlbMrya|AyBFm|^bKFt33&3|%8WBE5BK9_O$sN?*)5lJfspXKp=-N+p?@cH8d z7av={Sf!E#1C|H9!^gHicBK-X))v&I@}1FZfJd4CNEf1kniG7vDyNGc2qAwud{hr& z?*s{jq;QJ9g*1|bw}{UoHXor_$fJue(Gh&q5iEyV<@_+TkL zG#d2tZitA_B8U&7!c(AO!WP8`A>nyP!}>PPJ zz~?U=sC-DT(ETX3KRHgf#10dk9-#OI2D=Y$M_Y0WU1bEaFFy^Fw1YJ3OQGoSrfhV%uQkO2ZjxhTcc;wjQ{sca4MutgU`m5%7=v?@))Ts3MTo`*e(MwwNfqi`+(1#c_1H*X10!Dy}_2PaV5x~ z&$4P^#lf6Id6gvML;fFWe_Zktzz1pIQQnVKd~)am0iU-U!Fi|G;i zRXkAnc+ykS4)K!Da+G{tRmpcefc$I$kE356K8}XPwLJW5g7_?3Am7`{&5Ok6vG{yq zSe}G@a%gkZABXrX!ucc`w?x~a@{{WkOZ0&MOMG4lWn@Hn< zOEGd`YTsR${ILGp3wOpS$D#y24+$=8aWZV4nA6=K;&bW4hibN{5_64w+`lFc+X+C#4;&60+Cn}TJ|?<{y})L;K!MLU z9R%><9-o^Cn>Xvb+uargwcg&r@zh(5$gHOj`C)wSjjiGRd$TbMYlSwQ;#lhA(Mj%h zDWIAJ#%NB6czMb}F5y!$BaL z9{D*MAfJ*sR+SyqF`^M6IuB0!(;S`*BK7M73ojo+;V=rY?BOqa_z((*QTRu5^)BS+ zg9R@iE+d%;dH8S{(U1`MeCW!}XUU5}zA{mdHSUk=;j^?x71dbdwzsP5z~}o8z^7)` zE5!!<8(3oPluGTA^o%9(8alnGS;PL(2>uNiT~-@FE3cu`5AgYZ;0fX5ad|jXMyC;< zXTf}yc6glmqE9=keu?-jqWGlP!HD3axG+{tApHBm=fedzA1v3Ys+LF1_HM&1M8{jL z6D>q*hKFk^eB@I77MmG*)Gg=Y1U|of1wP{3l=e=E`*|`Nq4sok?;h2CJng{=rmqnK zpO4L>`EVly@rh}Ej0iqCml{Xsz~@(tSbUNhp*VbWFhbz-{{l~dei`aMp&>VVVhs5K ze3%8YT^XW`Caav8*PssY`87ZJfkN3?Ji>>_jvjObFXEY(4^t>Rk4KN4FWy1$`K<#V z`2inxbmh(4Sd%iNO@GE`<;zDsm5~{4ewO8uF^XXSFyAiUdG1q5emV`fcdFG&9TRA> zG;;dvnI6Wyx6TNzoxz|#!~~k`jGR8_8HP{ih)**CpSU|b@%iM@>*IhTK9?Roo|&PT z50Y}JJI_udKF?G>o*5yD6J>;HVTOp$D{ek+Jd%zZ&U(Z~VLCqflO^!^v;#LEdu73F zv9dLI(~vb5eB{OZQhYvg`N7ZSc^>Dk^iReJZRi=tq6mYx^@sO2_xa_lAfS9?a z^%e()V`wTk*{KuZWKF;)UqC$QiO<5r$2ES%md+dEaou8M$=g-W;`J|Gd5I$N-5cs_Iz{AHU_AvIi zE`E8Hk63T!KUTuYB%xz~i#dUOs6AD2$Iz0t7yvvj879ovAixdBM#OJcwC1 z6{#4>U@)Tfg>8RaYj+__d1nPaUwlA(b{c!ecDF8b-C>n!97`D9~J(o~gkVeVF)Ms(fx^tG%_G`EJ~N&PU_>nVVcm1K`s;aPwiOR%X2! zHy?ITW!5HF@_F#N2Ry<)!v%)<4?Cd9;HNwADpHBhZ6dKzi%w@VJojpx8&x-)?Jy}Th)il zcgF9$0v}iYAQgi~2rCWr>qhg87U{b4(ilfG4dV#8K zxqX07{{VbyX3=cHy+H$fr&~uVA>*>fUdJ1#UPotQn0PPNSYNY_tTDVBc6#M(X!&wk zW7pwA)Usm-V@zkmSnWS7pyfN054!kZyIquIV{;*j)l6|Sk`DsFML{<1c;+WLrD$>` zA0a+-Ren@HtTq4(B!h#)+$tdx12J|@v$%`XXSR%5<>|nCj^G3L2BoFk8;{O#IM~sB z965tr$^Hw0?XBt!;zRitQomF_w{2fy+)a0-6Onv0sdh|!UJl};%1_B`??Z@+MrXen zL*XL%l&r~xfvb$^#d)sn^W=lH|L!Y4Dj!?FY6c}|&|x9Ankh1)K8@t#=ofM`W=Bvj zIxi%5x(50AX5jJXbKBN0IH74wQ~MwFJc1AN)nlx(qS{&Y`@|=P{IEF0B(ugid~}#K zg3q@E%a7dZAvCD1*`lMbHoL7d&R|BMbQAvsJmT`f!QSKExkdR;Y%trg&JJhe6CA_5 z(;J-QpA`>k#HSEPzZx}4Nsax8!^ckQiQVQZE(D)%ohy89FHa6#38-=NPvh_j%ClSr zhoJ8SpKmi1K9oW!5jo=*vp-1=BaFjGkMjp7A39L^IExBOQQ@A}Ah;o~$KfNqLRf;> zhZTi1xT3cpKR;gpA6DOnEl#CGeZ4PfzQ7+ zTzt&dW}|Ml%=B#Nr%?G=X)_!x%5M_Ip1R7l)WR`T)sDfmzUBzyl$qOvWuJ+F?}-m0!5K9`C3P_>(A zZ*+V4df#=3PcC^YSixKD6#`egw zq<1VXlGcyf$7WX9GHQqs=OGF-FI-1y?8zysYp75CsA=;GeAMxsi%{FFnp-TV(x{pH z30(8+R}=b0_L+;Q$~_P#q$#;`6%LnNC{a=d+t{DNuIyZ`0oQ|%-t6ob#8e{woS zoIPGPMSMMA+rp4@7((3+Ds*NlqvRA1*&R zr$l@T;e7atY(J6s#E~DiFuTaN_|W+ER5OAP1c)tKlOT#MKRKsFd=4V`nDu=gHP+Z> zkx|>NQYlKBV(_ts7d&`ubdSYG-5d9EQF6mI>n1+)U_N{B@RI^gz`BWTZjBu&!CUz=5@$V`yh%> zihR^iJ{qN?f=>r{g4P$@{xJO_zgT=j6v~I`7x~5VZ-|J`B8rc2{Unh3P(C8?Cqa9w zx)gl6g=jvBvoIp~^m@7WYB;|J_zVuh_}FDQoKM7i7Rrb1p~h=x)mMSfXbwKy=hG>5 zTIMs)P?gB77SahSPp>yyrKU-aSL_|`nK&XO-W~J(!D(+gwqAUZRf#+vUr?~F641-M zWDhJH5fZP>Ra^x=f1Bio$7CAK?$#C#edoE|6gsxsEtjehzGlDst|Ofid2i>l4E3T{3kHlaVzt&9Trd~g9i?MAIs$F@6s&ZJ2k*Sb+f zA-^tas?*4h_<827k5zx7Jv!?ld6In2d`%%Y2?r=`hzZAu6)jKkT0!TIXmF+dNjjk|sm$+xr&rxdNY7g`{M=RViW5 zB6U=+(>juGAtLw2{T}UE*cDfux3zf&KL6ps%jX(OLb&)`Lwl10<%* zX^WJ&_}GcL{iFM^NqRkq&%%dKEF&D!)nz{Uw7(%;U~hrX|6TCmleGxYG9Nu_0D;fP zu6+2UaA~-Hie)|;IW?4?fX}bY!Dp+xyV=;S7zoMilp6FLe`FZzw`TVbNB8^G-n2KO z=lDazvA%p~_S#GEX?NQ@*H#<}{M)n1srJQ@&=2r=-GRcVK`~J%`h*ZxUgPFAO`31Z z6CM=N3w>(yLA<;Z5ycMzu}j^o;VpLF12$OYSq~`|dZBlb{Y~)sEZ`CHgOUAO`LK~) zXF|kh;pKyXUM4;nf>>?&@$lg#YIQ1>1U~;&!ON%AF*i|he%)v_s#UmtDp&AFA7$E8nQDvwp^`MvgxL@LPrSPFZUfc38E94~eB-3S;k6m4hnIA{jlC`(0 ztHI~9=L(-(O3^KQg)RwT&Rqoy(nTnPul@D`dB(>Bz5w-H2=RfTLd}#enjvss7 zCCW#ctybe1RynE(ERFc%3(XI?n@HS>>oE6mJy2{f8w_;Pbi#$xo-d zy$$=a#A&NhgF71K#f^4nzZ#>m4Zm}7e$#lF)7Iz=4r!CKdt?&pL zYy2YRnq11ypPiHZ*cA^2r)Ia*>NH54l1h#(KlUJgZgbM9W}PYtke|O`5T8c3xxcJk zyojCIZZyq?f$fagR;WFionII}+T{ak&76$Rt&xF(WaoLaLg4fI12-S+dZB2qYOOI} zY&JTm-$HXDLKba`6h7GWLiq@{wPq8=^U>6rj(Rxg$_JYIBd+i{_`G2OKFlt|&Q!?< zjU{{wH?6AJnpv$io<#8z7W>T!P)3p>k#HCPNOT}1U_#y zz^C0Q?b*W@7ZGEPkL~4drEP8{7}g^ZRV)79r-0pe%R`3^4zSCJq#ZeTH}nUZsrj-%FZkt z_mwv>0-vob@L@YU%s#u}khUcj9#Gn*ot;SWA>GTd@Sq>yvuh~wbGK5e)7;1GwoxO~ z&58=JVuzKc*gIx~Bsuc)e7}b*9m-#xph{+xAYsRqCfui1P9zC@SbVRTH=~Yk9S$)M zAgMO7pE!I_$#;mXuTVg-n|2QrTzE#L)Rz%5fo@H2kcC5^jPY|y$!x5lBe>S^z8GdGL1NL3~teA0s=D z2T$vCR)l`DKfb`Y&RvMQIh~b$fX|m-3HgD@@PaMM1u368_J0QA8 z-m`ecF(Q_%#ns>iA69>Z2w<;kr_!N+SUD{mQiLt|Hr8VXc6#VY2Xku+VuomiVgs>e zpc(ui{lZ??X@5%p^rxrTBpuUnsBNsrP-m27EL+FN5HrLo9E}ibmdi8^;WxHb7_=ZhbjZbUG&M9p!}Q{Rn z!sq(*i}TS?zdA+)pX<>thmU6Z)w%TLgY)ECjZRt>^RYj)+cniq#bAHB2jP5DsaOaf ztyBzr?gEeB_%7rp;mn5*VG(?^Q8D7PSmHxvj?MPX3@WzFM^2rObW$|%*()sZq4_gg zTF^pXQc9v|aro$ISzJDOS2XZ>dcMTxHb2~<)V7}(n`Rp;FZ<9L*P2Yu znB7m7`S8N(IOlW?EBf2Wy09y)A6gUI1hkOT{Am8>kKnU!gz&-AlpXx#0_0XSHyHb` zw0!cWbHwLznU9SnK!BVP&6f?mn1xTCbPjx;IauOD_Ib;M2eFJ&Y;_8ymnj)8<>J=J z57IK9V{3fhI6)1zp)2Jn=ME3>`OCoLGyie(!93cnRm=p%F`v{vxvb* z%8#R4(og1TlKq*8Po5OY(;4u2XJLsCwwA^0S&U@s#+z=VPB#8D+C`7w!_y}Hxy;9& z7AogCERAKi@;8_*jK>d;-}}+o|M-_&j_S5-5ECB|cY6e3bd2ty*j-yU7Q#+x7%8 zc=QV4vu*?^mn(wG?E_iiyb*j3=W+S0+khxdj!JZd01A|!YvA)R)ewA+jM#kSNpeI8 z(Tc%_nJU;UuRep#MAFkrCp|6h1=V9qdOdLy>fzPx4 zd{8H#Q>ms>E?++Od6jyomE=Txn!fTQ`6L&fa6UPlCEn_Ek%DQHm^ZaG5AN}LwuEkD#J;PZ`h zDL}EG_fVHoo`$2TSr3mk-yu>*SL+og?{~XX1kc zv3wqBNyzXMJbe5NHT7odE&~L)OM?Xjdn?ecOpm+qZ9H zosv$e)K?{`^|(bfnYd0>scxySN|N=s*VU}x%32{z07E-4LkNUu5g1mI$*ktF?8yKb zE&KqCAsrr>0ESgy#=)=#%p`U)u_w&`+xtBBc|WASI=j_t_0@Bi&QITKfBW0tw(B!p zZY*Db1}r{GLVl|A7$4hSY;dDegU2l#X~GEKK!hqi+K4{U~)N$Ohb{jnpt;1$er;xQ5S!H63du-4%?qQeLbT&Ud zwdyz~O7$WGpYQR@&vkqMm+a@QjF1&bhuI$b8A9b}4fVYba!N~l7yya>TGINmwYn1y zC_(+RT;F2a=QZ$okYEAKX!eu9qw4}+%x?OED%q^=RxX;``1hUh~(!g1)n5r=&vW`lQVbj0|!1oXz^jC zR^!>Oj?;;JZ%h3I@nOf4(L3fnoKBSbZVx+?2@ zy>V|mro)?fi6+i-nn~|b;V$_6B*~AP4=-Wmq2Z$$IR)~WkWf*DraGX&=cg{i`4l)F zoP3eCk$5Pd0*8acFQzJp57qztG?Vy<7@72ICGlYvAF*m`>X(}G^V7>vKAFWQoR50) z^K*yb!=!5qs{x#{GeDx}NbiH460WGYjx3S6dzP_>{GLm2!VFGtW<1%Xpg_ zr1IoDKko{Bc52$~1~pmdf@B?Gnf+Vs42*lD333|T=2%BqW*=`;p9G(WStuWv>C&#Q zx6=oV!FtaBO3Jj<f*fjQe$tsS{GZIw_CbaPT;!uZ^q{rCpb`fn$L4lk_s01 zyyeQ`L$h|R3PNeK8UDY<`S5UXV)VgCjckVhI>6^`%;Hmq_~@<9bsVycs$J09X?3f? z^#}fu+|LO4f%x<$Glpi*I9J&)H^QGz=6z+-h~V>V(d2`yp?p4(m{^$A^Cc+Pp09X5 zdAaY|`Ub@lem>LD zh1|zb5ltgLi)4IKX<7n4N@yDR+%6{PlUUOd^2xoXfzJu>nEGYakMa86HN=Om`Y~1G z!;?ieKDNGv+n-c?a;a~SpI$LLpP2YCHJ{w+8}YdcL4NMAI6jHJmh*Rn{|e!gJ1ug)xAz|LSqAc1M|>#rQ8qq2I}GHbVX?~- zK?m!a7de0ImmeP=B{U84(+8e__$QD~VogiPC-<5LKI2Q9kDNagow3dG1b+OED~Bk~ zC?bgpy!qp2xij{$GO;4~yn|)rW2svZpcVP#M)!!%G8-Sl6B8fG`R7#fLws_fd*CxU z4C7<&EZ|!#!^6cO@d?OpIDB|Hha%x3_)LK(ApheWIw{&);+S$oa!{#E0_y%kf_Yrc`|Rt<096bbKr&^D?K$ zLccQe$&J22e!g{?jZcF3a3wyuaBJZ6ZHHlelEsJBwDKdzKY6db1D|gPo`CuLI^x4% z`H}hLMv;PkWIRWF7Ag7Ij*E^Hp>n){Ta^9r^2voF1zZC?1wQXC#_-7=9|p^hV)5a- zuhR3eTvzBcEJ}U?_~cg2AV1%6nT<~<8xw+q+3idI^ht>yFP2j5j>#8$;~g=^1xVu|I{K^rvT;#E-9fi(fG(>h>{7TbX=73jc5D=d1H@v8CwI*je3 zKN5<1hbQ;@$7k4}(jN@021&H}y}-txH=Cf~4#mHxkg9^~=tjafq22PEzJbrfmw|i| zf(W^Q2tLk4j63>VUXDMNupmQR0S?x=2U-EyedzA?++87n%34Tb&WO^m>2yh%n|ksvaNDe?_j4v z<2k)f-6m>@>}k!I8h3_WfzLm^bofBO1f54MHU(>IE~XTZ)-^}8qU9%^kF!OWCs*On&8@n*k~Z-9=ZD~9 zdviz0(wZEXY~JqO>CKFz0eVDQN~VIjaa{vF0H1$x1wPMpOQqdvz3Sk}WR~smpPL^a zpY?}*2ahr)*}evo&&Po0p*;;P53%*%aoUb1rSV(V;CsfgF&TjmMZ%{4%9Y|+Uo_@l z$j`?a_-yO?4%pNijWW7Lk((C=NDgx>V$UUT^V_}NDQ7brjZV-lN@_qRtg|BAh|dyy z&>x^eRESf7p^KDzy|mWYhkfRK6wDq9Xd=*hu7C+Xf}?;N_AlQ#L+iRe&97XH_y*?w zkcp|PdrQV(bRWjrvD}-t*x>W~!1ItKI55=#gd%D90o7%(k!DM z69$r>R-e@W zDS`hA@Hw2MoUM~U(tH4>j?ARjN3bWx%sKMo&-rlqz+2A{zt_+T@4wNa}UOy6~Fr&_D& zW$x$c)In~V?HNY``Dq#V`jXGOCKAwQA5B@ma_rj)68M~x{IseSaKQXx<;Yo}Z}smO zGn!v`#Yd62*%Bb|86Jkp579!n2%jc8m2B-imoSGIDL;0+$Y&s;UrAmJvIWNc7koww z@Y&Pq)l!4}JCKMJkfU7b%`@9GhW+Ca<`-5}sHld4&twTcB@K~Itp*JXGC}F>Psu=> zGZ;X_)CL4T7r^sS4RtDA%Kz9J)z-Bg%;xRD*|yG!99a!*qvn+V;r7Q?s43T|Y0o&t z{ET8}z5@Yo8uqNPIbR+heEwGkKD^&yLBMg=N6k#M*VQNRUrpW((hWz>1*zie!RNOY z;KTDjdL21Lw2snNm{^#0jpu)QL*x+AH_A|MT47sh@cHeck52*p>v(q?K5a$!%$-&h zP1^X()tZP!=jYvg$OiQXeP(V-5vzZb-sz-|i3Ojz=4L`+lM#2o=XVal$J8W8g3?V# zJ)<&K58m=@u-n1W4otQ_b3)!AocTCZ;W0;)XueZR*bKXBnFP@tNOofhdB>olmoF0&PC8*>yWh|@q$C!}Ra$Ww)# zVs;38{@@UNnp(Z2-6B2~smy4&o;8i(v2hpcIy4_eu)|>~#zyGZkG>2%549WJrpS8o z%Uk(>?a_R^&hb|MLKz3BJo%&lwg^6AeFtk>Yr-VfcTjSmI41D<=q32@^_{iR5%tgN z(;@%$V_(d`XIpF4^aE3Vb{l&-g62}SiC*h`W{*rFDp;w(@xirD;~Kiy-i|)=VcVFX zbk`(wHahR2;rwxbjH0d@=UtF7wuAz(Vz0KFE2B{$Ud?oO>`Ly?S9gE5P z{Fpr)28Mqd-43I5umaQCR6^eF9Mqx+x%f=)_j*`0=Cf5SH`BkP`HYDLFl|aDgPk&qi&j#ofz?CSuZdeP!j?(Q`y5frXw ziE(j0C-d|1fcl3EGaaC2xyMC(t}H&1kq$6HiP;c*&WGmd3bUc>0H3xkKQ8@}2+Svl!3Eb3jqS3L0CT zkn{Lr__$9evcTlfn}N@Jmf&Mr8ywu!=Iv^a#b?hRz$S%G#dE)!DUiD!O?Rg2vj0Ifk^TdBvzjM@xRN!2WO&n zw0g%%(DQ9PLD!x1x#|$7oepPaRA|mklYTfy?*pH2IRqb(n%`@*J2h+SzS1FbVtwa) zG@T8ssk@R#$Pu5HLil7j7S{gdgZTLNE!pqR?;Y^@9~R&fs9z{2(<|8QgfjZ-UX${N zmKl$|pg{fN3HsihJJ?fjHtC;_$75Bz0S692md~{s+Zp% z(GIvF+qyp*;@`(q_444u>wlzdp>XQSe>D#e&eS!lUI|sJWxPKw0aB)8@uA;$|LJo_y~oiBG%H)L2_Dp@~!(?S9CeJyu|Qy>~i^npEWm z?a|m^)7~+fNS$Es8_Cg1<86ix$i2R*Hnq1 z5I88`ZeV=K`Lu}-c2DkL3+2d1``o}w++-6$5hA&x=uJV9{x0!ZT6`=tOsjNJAAFf}3q_wb>QYf081tRTm%actg z=pr2b0wiOCPBuc(>@1>R+j2<=d_Hw)@d27nqt(IIFQ4pK&vVPgHyABZEahegWB%2u0PWX=HY$T z>Mv0+`vB1VoRalN=&OJ|rpD0)qb(S)`E7>sR?6ScaFR7DUnppNem?BupB&u4=hF=G z6Uzs1(tO>-d~7UfMt^YcB|gg}e3A-|`PCEi$&aW6LIWyS6MLpxuOiEl;AZcCw;Y(&Eg{f}<<|&-58r2~x&Nk_4B z?HbIrO$*D(jgDTeo1LYim23|kTiA4dG@bQl^BI*r_fWPvxW>JhjSDNvqgk&%6kVjy z=9h0Mj2`*HzFN7Ve^n8DN?J|ZYoI-L9a(2>f8{SxG6u%^2<@?l$T}PMR~~Ou1Ax!d z41BQPw257&-6}O110UW`w2KLu`~sTxMDIFvuA+ke&)8o&?^8E1wfR(m$Hm7f#uS?? z`6LN@3Ofz+JiYdQ2W^ua7yzWUFp*=l(irIIich4@y zJvKVEUwZ)IB;@CrVl1C-9Z0a@fcM;LYNcBNMBGnB^N~ncEw{$T@#d>F+}A*lh|g6l zA2c7URV%x&;0G}=~;g?M6N>>n^d{6^SPHU`El_L&)i^`T0BMyp^iL!4IwjeEt^6kIje9 ztb+DXEdsSnLQaf2XC`%9wg%gLgrVV;2X?~#w`E^P<;Lz`W#CiOF}uj(sO*v4 zcWOP%F4S>T?k_Jr0-x&A;=`I%T0E`sJ%rMmGTh~S*tp;0N6XM2LN#yT^YI1osqP`a zvyPdm;85$IW74illoS5jRc=&&kb#c~3D-xc!2?3|2@#*A%|{BEE$jSDmyVK2H0P3k z1&fapF$+b5PaCU*BfN{cy2yZx$(@%;e)9b z8by}17NyDjX$~uRZqcf6^v#l=bL8WV31!LD%yNLwJD^^s{fXg|Lf4Y;Q9;v)&mt+G z6lsnmd~!9B2vG;{nOr61Q%=5=nuO1ZS+EiE)pGH4<;JbAxC9?;E~w}=6xFRM1nN+} zXMmzQ#X}(Q`HRfr1G8)fiFSJ4GS_C#47K7~r`_Gt;_~#I5A3q)L1N{`fBz%IN6H^^ zD@@0u=#%Mp=)%E9M6Fweokn$Vc4Aa_HZ+eE!7}Iymd%YJ>2c^V~_$&kYz=ex7 zi=9SmFZH$f`PhYGr=!Vv>hU)90r2^WVjv$YfZj&eY_y`Mj0gOehOnqb8xdk|em++G ze1xvqbQUU>d*Hwf#6{Q;Ka3e}V=sfxF9!258;fqC&lYm@V%fPY>Yw>KPqYQ{^Dz&! z*g~HzWa!1R^NA>*;yab2$J-R3%8kEy1o091A7+}K)l`dLipX!6rbkWH;@3fZ7G6H9 znPxv9HBGa{XL#x51=Es&d!x)un0KECwvS#9n`zm}VinsYC@4)FQ?g^v%4pi$6Ts&@Byn*O>OCSFfA zH}&)3MbO8_;J80OXS}S(%GYC4My}_p;Pa<``B`ml>gS{8+*HWV;pahoJoZ`eL1fqH zP@imR{!X7sa&zmK;8Vbk+!^)BmgetC#@gh2DmM`Fl8Lh30w;y1 zMHy@Kw+`mx*E5#$d()idW^&!4uh01u z*a>auGRHHf(>ant^Pwo&OgG*GMB@5W;B&mNY^~RJBg#4WM--+(( zNRe?)Y|DIXsv1r&nw_EZ4=weak0yL;&g={oiz6HiiX$!W+^`SzHpXb&F{1P0PjG-d z{uvu%;{shP#yx`$ljnCP^beM7t&_mVllhQd!ZQD~Kb&UzLBQv92|oM`b6b8anMnyn zdb>uamD}=T$&B;{Mec%6|0i5vKw1CK|3 zgvH^RWB0x|vH2o;YaG9BHy>*^ioFnKZ93u0sM3au-0X|9emw9Q7DM?Y-;ZLAXZ;(@ zM&=? z<$S35<5hVKD+s>YN5S+RJG9H z^Vl+iPgV;Z#z!>^4L*P6FoI833mwKsH46o_}?8mF&3yTJKhgL&_$ zhqH4jz!$R%+vcfs2YkL4c+h`-jc@<}=Xa|Q2iE~UzqKU!(dzh*?bL9HE=iESdw^>2 zPTI0nTQs(fA^u~h13E+(64X1pKsoqKm9ka)I>6`mNPbK{YYTu(KFS9`m8YKiZ;Rkl z!nxh(&%YkyL;8htyV0LtZR5lB>#66K#0PZNX`f4=^XjnAPkk@RPZ_qxR=PFZDZ|#R zVVI2%QF-cShva9ciaz{nnp@CC?ex)w-^{M6n;j$nb@Lm5$HiyWxrLXHs&fmv4)FOK z#SlJO=N4gnRGV8^e6B+HWSv`t@lkDVVe)x5@H|vIpth^l)M86K3MAMAsxVE5n}W?ted_OO2ty9X7Xd5P-)pYOT?pQhH- z4$xJ7U4WYA`jqN`Do;KANRjyHT4{HU9==KIcCP{t4?ch4(#L0Y5AWuqu7?MoFJFf8 z$?oBU`KagN!RIRuL-}O)@WFi4^YGyF3#R%Nf74@!IG8la?l z6!yNRRi~tQ3=KZJOOl@&?X_q%(7L#-)vR^qu&a-MzB!nmqjGD6ro~fZfF{|B2GZd3 zEnI$DUFuD;whUR5YTI4~4h($WeM$1;;^T8*TDgp+o)m7(&Brp(D%MAR-FGZQ`DAxs z!F<$nV342hJPhTN-GK%3QO|)@o_gCh$qzbbwQ+{7b8bPYTCdZI57$Z!zKm+VA!&B2 zC2DHp4SCMr0Y0TehYz+3ivGQ;er=Nvwh8h^;j0d}vCo6gHv$j#H|XqP(Y zJKVhXJ+}PN0gO2OBBRT4Ni5edI`NdBvSYifJRGUx`krwQAV2@$(vcsNkLp7`CjJZlgVYd#&z>i%4NB(1AKnK=EE=ps~{rWpLQnX3EdFe|(pk(JFfbpMN6pS%c&V6eb^q zB}ZIG<>uqB75ZiF|60=w)!x6O_zV?%9zNvyW%4oeV^Rc^aem4-^xOF{DFU*cy%R|1 zd4Br%7XXj5f6&jzIn}d(W)n`zEYhaf^5c&XC1;=W!##0@ke@GDMDsz{@LgTIjZX9_ z;^+uI=o)_3Gwz`iy#i4*`0({*d;h6leo~wY;)qlcvlqXz8@DUA>6gl7ueBQq!yx9-eQ6*NLWG6OxN*tu~spNtZY=UDy+dk=j6^h)A` z4XAa!O@wextjNZfwA<*{R&DPV%KKVtr?7)btlo;bE{jj;3`nL#NX>I%D>tt{bSd#^ zQF=^BPqkjEb;~+4rDzW=qRUCe$I&lpKjxAibkc%hioyF}g(TvyfzNB0m(Lnzsh0dq zh>yavRPcH2p~QzL5F>adeaYg(6Rb%;l*9Ld&%+Ce52@BV5@Z%1QZ1DQ2z*|5<>Ry6 zs8W_}g`1nt(WtLzmJEEpj7fa9wN6KGT`O0cO|sOPEs@3N$e7J~lWQma@mNVq1U?tU z2km-0SRn0E*t6Gd-`c}rg!RWHH&337KZ(_!op!AIDWQ1+7DeY2_MFeBch7Mc;Sl4g z=H|iY2No_qBs7iZ^g7$x)@rqQ62VI7@FD9ndZ9ODTSvxVkgbbl@ZWe4&w|en6*-@l zwzu7=X>6=9%a0YZPsU2d#5g}14Ggw5of#9pu&ki?V19A^M-D^znAM29WpBDh ze<6IVLTF_c#K7l$3(lwA*0wdv#AFv7Q|L?R)@vLYjN2Xc%#N+P;PYuleC+;FsMFNi zG!1LmZ_04T=^uqUO=F5aK*LdnVK)Ae%FQRHZa(cs7dz#|JPdQxj5mkRbTr3KLO#z> z&3WP4!Dn`8$Qdxjz_CS9K+C;4@zY@)5m_t*WuK z7w6|AdK+7nVrj?Q)ce8b!j>Q2+)vUkv6hiy)yuhxK>f13m$U-rd?KIsz~__9k{`im zA5ES;fwN=1`N>xaLTHK4{az3IACz^c?#Vx1ZC^Ph`}`P8bF-A zy^a_t?#B5j8WYOb20niRJVJi_e588AG|{2if7Q=Nnt7=Z9a4Pw#y?qv^GOvG%G^Wb zM~RqFz7FvDe~N++HWv5=C{ytv{s8!3V}W0Q04V=Kp#-RM^RIpE5_~Extx1jNVWOq& zP1$#OS0=_-oK1G0k7wX4v=LKpmpAzQ9+UX!D1kyRvN|I)1+9#*#!t3&mv!eEwAt zd~Q|utD-l;dH~((-|vfd32Fl(K3Cvl_2*xg0kZn@t8Re6=L44#pTHTIDE+}wM)DnU z7N5Wwm^k4ROBwm!AqPIc&A?~3QP&U3`u@5KfObd2-o;7pzUl=)m78z+oJ9biRcjC} zK5ADV(){90-$3$Xo`10}^TW*ZFH|=_oX^tXWA#s1Im$5kybAg!yyH@+0wCiwsG8l$N2& z%{O;ReysC%)@7ir^LJD?(BQMbkoZ(ux?Z;v_1U%F;&W$$iZMG;pMAVdeG+{5`IVOZ ztSf%D_^2O0zxlg_{IuKEMtyBl)FyHo{n1eQDJtaWml^4oINxer=7-L|p!2O%H$U)S zZ~k|O4j;dI*(>l?W1IN3cd`{GAHRC3kd&8<9r*k@@L2NW=OZQM)2zUU@=+lv@8PqE z;^WS)N}r6r8_LI>U5y?j2d_eYexn$}M^t4Z{j;Z+tKGdsS)eFBVgVlMpYz^He}10p zED-UzisF;1D%1JFL-{CCmFZju_5Lo7M~SLT=Q_ZL*N2<_U8KdN3XU{A z)tymo|0Rkur3wz!8q|UhuMhX|k-V0C)yeOh@?-IlyjJot^6*aLBiSEIepYT!>*1r! zeq8Tw0zSMx+?1cS7|$ zz2Kw#^pyDA1|IW#SU(@h(WjZ7n&*4^`ACjli2`xrvxwl6ae5lcN3rQC$v-Z(*zzDA92E`)EU4Z1jV*ch~(oBf^yp}oA@l^_+$uzBKas31cA@9#RPoP z20?LrR0)EJ&s7|s3_(yNABBP-@M*I+J{f|bNInV$LE!Tt&ZpMhTWkJjFh75F$wwjAZt;1UMexbs+9UZWF6<0M+3jLgh9>GdGF4|7#jR^8FiPzz-LK(TD#qCt+l-t zHYAv>v-y!RIZ{4E1fLHb%6x)D#1x$qxY{~=6b})>=VyV(ksm)FDMS?4p5*_w{P_7u zA!3q|Hv1mpvxw%CDMXCmqg03pK0jBC<&!={jOL?Gh)8^{qWNSB5hM606(WMq{{=jb z{jn;@vQFGhb7AwbD(n=>$;%cGd_GW@S)x$; z={dQwuFChf(YvMZG_YHFJbCN~dB1W~|EWuvk8PhBZJ$>g??Ez={}%ZCF(W=T zG?kZyNPbg>``ZKK_%1a7vVz_Le2oZ`vt!JPMJQ`|fwKHQlcdieyK z=Qis!Y>A57#q8pvu6ZUtQ{aL9k>tnE$IOu>FA5tbGo)sL_QpHDF2(>Q4B_4Q5Qw?`M#-cbDseC1~4b-?50 zv+@MY!$;W(82I!q!KZ}U1Y3GwM>QTT^JJnoS`1cH&$A`eCfL$r+hydUtzKjW=cql; zM|1TMd`_8{&l(cYEKyM&kq65 zLuhSmtJfODhn0KxZS_)Ed=NiZzmoXuc1yQvYs_%$&X4a7UIiHr@Oh4bPpwgr4D{*} zR2$uq479ou1U~N~`Em1E*}XG2A7$M;>DT{B^0U{it=0bQ%?Ga%`}0iu5`0=(yD0&>x z@@e5j^A+njTzn?9V4J2z^8NQlb^T%DE9bM=H}yf@V2SWc>n}HUEuNP*XjXK93RP4 z=Q;o)J_|pepa3ZO;c-xfI6eq~@_%?7t^<5{eT&=vSPm?E0OaPQZU97l{PJV*$sPa& z^O3Y_Gv+q+Uj?68(WhS)pX@Fyn2&lc41B&Fcpf@vbnBHh#yhSFV< zwLW-pZG@HPJ3Th(4f<1@$TJ_B!BD#KHuY}s`L!kV%i&{XTCqy1bxV52FXr%>n3SL9ghd+M_K0B>$wF4qG4LPx$mfqf_3>oHR1-7MseW}Ju)lRG1ehjI< z1}nGPm6$KQGnw~iY-$V)_;t;GU#vYE? z3En%U*Ya@#pN}kJ_*Cob<nz2MzXV4{d$t5#&dc-!%r#X=Xi8{ zcV_elBs=H*ciM;PW*BfoAA$V5d}zy$#m7E?5S-+8qfUxGZiedSV-@{4H9xAP=)vdT z0FP;ZBtHHWeVX(JT<^soK39q4CtVwkc==JI z4F~xADoeyCU8lBqK5BGotK2+(ZPDgq#?Q^iTaUAL=b)w|c&_s&HCEP1_c~fkVWt_U z2tH=~+?@9&vk_}S;gB|*T?~3`Yp?&#*?iJtB3SHA*%6wR4UK65{WQnM1>F%dH{9vX zjvs#vUuDS0GuTOw)OKb}+00bq-Za_QN*zU2Zr*!810Su~1PzXY7B0$|VYI9D3geZl zU9j2LYUM_2N4zEe%V^^6hKW`@rWzMT-x@W)Q0CWk+mET1!LQ z62|4L9WOW5C2&6QR-n*V`2aBDa|J%!t%J{Q1LbsRf(Q?PTSuLgb-ii-<@N`B&PFJw zLoXM2_NHpj^NzY14ki9UchK18gq_?sCZ}d(Q(ysMP~!16 z^+xddTo%ZO!l2TwuD8*!Ha#gn9}xx}pY?jvo;s|+=jI{jW9OgQ7E;V+x|tWbP*U27 z7?b^yQv4jAa5hU`C`s+)ohj95T#SZ8qd(nzHXnSR1|H$x&G?xoni<5O?c%UZQ{V1o+!?kV^T zN5d1NKe^!6oIuS+<8fYAFu>>Qie5f${X%2J_U@imt2OqM&MuglUlsGO&;=c#Uucv# zJv%oBgVFu`%`}M5m6s1$X0hBw_NUn`b6pD(lhEf}@)Ne8BlwKxCwwt1bgWIj06uTK z^zyOg$1yx1y%97)yD{PYxQXoYW;o9}!d z1D{G)D`|TTz**0&GB=Km^O4$cfP(le!Kbv_?bP*y^}xX>rL*~L*t=NUc$*ria`WO% zBtLe2omE3tYM=^Ht7XkV+x2x;4cYMsRfxtwwG1@){3!9U&le6@1IzN;+2>a(z6Msg z`NCgcf)7k{lgh;?3$%_~do&+YxfoR;s(h>5{Ki2Md;}S>#*TxWtjf9q{5voA-KlA} z;p!9Lgnt)n>^R8Ds;sjXjoInIxCb|%`y27OisEB}5uU!Yi%hghEc((y`Iulvv$NiW z&CakOZx%>LkGH8;!Dn(A#;3rL^TC>GO|*$b%^{Wdc9IYZ<>Ty!yzz-AzJ>{ppZ?oPeAv;TM+X)0@r1`uKi;N3 z0Y3LGgZc2qE_>dQl2-s9?yru`zM2<`@B*KI%D_j|*OjVe|w#i`o*+xC%5-%u$MpK4tfK7MsJ#NEjss>?>m&l}zkJP$RU^WWE^WYYQX zN-J6A>Bnv?h!3w{U61T=`Qi1eYRit0pT`c0;A8i{`@|Ip@PFtzPh7kG&6g%=}M#uYp8!RY$dIwSJ3lEf9$zq~?Y0HR`nkUf{}05W}Ns zF+ZK2kB}in>huI>4Wonaxq+=)e4cvBS2mEL7k7jrj)sE^wna@8cs=5HGCG+b&rs*F zxm)GwxBf=a=2O>89a_9tJpm;64132jTD(|&yiF0RJbmL!82D&Sl*wZsa)D)>D0=NR}j zb*;3!Mn27+aeVfw;B!-75Fe4>SeN@^W`09y+d~RgdHU(sFwRHLZ>)~Vo!?Lw6Zm`+ z=c8+_HL4ebeobBl>IM1vx=#@w)JL`2jV9ZIBdco^4L!CJF4RX&rlT>&n`0+4^^SN< zNnDkupa1wJ_}oT*tO5~Q*X?$H*t-J}QvFtW+yD2`BKYuWXaQSuw-44bUE=ev0=DKJ zU9i*92+PZA&cTS!mBj~mFgfMx%Hl+a+trS?hqEtAf*jjvG_Ww=X_U(~tg}Yl#Qc<3 z*75neIMLx=e`cJc9}>os$jwG4Cxe`>vx3j>UV@LOf7G510+1w^p@cc_H~~JtzXTuAf5cL-BoY!OJ&f`7Wwh>*faF%P| zzYgNF2;`GlwW9c_q*@lAPBD;AX4Q(~qmpV_e5k#Rq+e*oW+v;~L8?X@E}w~x4QXIU zzjz}yL!|574qpX72K{<@5yvNkswLs0g0g|nzbVG?$)IXU_^6<4#OKP*2iv>FYLBd6 zmIz%>$V%eF=UsOX>d=koxOfCr@MfB@e z4}E;lcdUhmZMK4?7a%Vm^c|aEkC)qlDIh?wKfeY%vVW)UKOR2m1t<|81q6urEMob< zl3F5^&_E~Rqkw^~yzNgPIRqceV>t;i3y5r0lHV8g3CgLH?*hSRkL1VXL;K=HstjQ? z)>KkcwvzcU`<@Vd1Rk86 zf;6gq7?>0R<=;Sq&xe6WtiL-B3zk7^BN6WqNtidZK=Ji=kGoR9+*n`V{+IYH{Crk3 zJ{UcSPyVIF#$w+ApI<2Y`J{K~_K4z65FZ8Hx#ucSp8!5rem*NNUmi3vi0HmZpCCReS|7n@>E*Ms^$FsmqV?f?zVOh?XJzXX z#79Nz!}(NzN9^Cp8Z7&)KKRi79hCy*fNP+qD#h2l_7Z%8Cl%QZwV0oVOeqvH)!_3v zER;`nLmkOSAyZ9!mZ5yI8|p|t3Ylu~(SV2MU#&LH*{yx3E3AEy-XcDnm@{@1`S1z6 zk_*kmXA#9Gql(4xQANeTXS*21C!>nR@li#^D#gF>)4(JAm)IjHG>epEg&Vg&Vr!+O zS1Sy-p^p-ug_jRy=(Sp@+TF{{%Ed>j&_u7g1!y(#5%p2m#Mza6 zbGw@2L-yyZfycBzVizIr1h5u9W4?<}aXxP-I((ciCF|kibSY6+ey&}D&-ye=*eI#L zmZD_L>nMKt4d8i5teLvP9_q~|`qXBSB^UN ziKxNnotNNaHU(dYY3732fM>tcQ`W89flQ_N6@TpTxhA&ptRajRe6AT(xuJ3xT`B&> z$00sEKjxZO&{jd4V){Fj-%wwAD1QE`?;<`zaN7I2-eJu~N9#1M30>aVMdQ{oO)*%;sz) zF$IC?tbgZ>*_*xDcreFW$H@sIN;AL67Z$gzw`}lO)JpOC4-ubct-EJ0FK1siwZ*?V zn4i0smlawxwXcHw*YzJ-c==>p(~*W{em<(K=*U;W`TTIv%O~TSjy$rTk18uV@>K{v zS2CYETDQuTbHRIQP8jVbNQjnPn(=pL+k9};5gya z3r>Nrn`_)7QQso0@yM8+tW%5cvG# zqMy&I;=_XYC@4N;pFeu(@Cm4pl11ryg3bU!j!ZtH08!xzDe(C%7Re`@hmYr@hOs6- z%V<8CbS<8b8rlXvzkMk2(QwcX`SyL<9_MaAmWq?iha}}bZI5#|AX5TRrMUY#;4$+X z=K1ey@M0prVV?i4uoojfi!eSb1c~8%)UZ2Nv;sa~TnyurN~5e1#lPWvlu#@CV!-Fm zGn-Gl+idB3INm{Tw{6?pacM()T*0S3A5VJcINqT*o%R&UI@_0l_-FUO zIRqcRzGJ52y?C;y8DHNqlkov~l$pST&zD|-kGXy!FuBAhQ~OLaerA0ARB=9RNqlNu zoxAik$G_?VTerN%Z6V?+~Q zvAC1nft9GA%>_Fi9pUs`oG@cA2NtlHn#)e2j!l;Dfluucd_?7;2ah~86}@{CcTqrn z0?sc8!lPD}1AO*a7@sVT%Y+}!N4fZLZyClXyLyTK5`prglzJilsXn{_AJe}#yXA7V zUa{;?b^#LeQ#PKTob-oxT=qvP0RkUh-)r(&hwI`RX7W+lb@A%}pKpfvSpMs_R%FBZo~6)y%p1L7m%!?l@b)4wZkp5fo0dDnvYSo_{r zn|9ge+c|&PpZifJxq+(zpKm7l5$DI*i48vgvM)Bn9dUk~pG}6LHu@3p`RPmW>2y1t z>NUPUrBijg_e>tFGoQ`+*G}ma*jYc&y{qBDz~^5vnGY~|@nmse@qEd4!m+dT& z{l2{40iVBH1RvA0)AFgF% zsRog+Ux)@b$7lWHyS9myIVsn&tx|gLYl+YPZndMEJHHU{>?B?&wFJiV@BUeT z)-!j0tz$gT@DJ=E_}sYk@j-nH-kfE2W=#Bk*|Sr%a_k&BlINZ|OLYk#>5w^ireV z?o<(ICpm-A&F6$lf5xNxCp|d(0wWHS-tlNSo%Lt)8T@~4Z#456&F9FtOI+MSl4`t7y%~J|*;3|H5NtRaj-`N!Qm4UaH=#K6lg|5WG;T$I z<8VG)f%u%xm@;fjrA>um?-vgKJRXhiBA*{U_Je#CeE#`iG#?^ELgb=@MUKd?8Ow*T zke=li4Zl9{`Cov?u|E_Tl5$A`Z|I*cXalXEr%2z>sq)51T?~uv5isDuI=GQlV2E`EW)-HB3{I5jXRmO6gyJ^`(ao zFf^()GSHTD=jK8jXh7PQ;3o3{gi(J$23mIQYM3DKc|A+O$8Ch-0VUz1f(ar%%Y=M{ zfsSWG??}og?~H9-^M+EFKKn0^j@GY9IV|aQzKS;6<%m&-G#= zKJhvwLtBMUp7acS4uQvGe_9Q#jWh;#E9tmcjNE)CBV&p*MtRl+SbZiJ4M>FJ?q`ayi>FuqpW;$jtx8`*6PD+p}WMzpoh_oF>*k6 z=KZO0VoXzv?tK4O`X2FFfR6yf8ui)%76==Af{)mBP_DLj(VHXHttoo4jfR5@bkQ80 zyZM~+?wTk4=^3Fzm*0CAd?``18b2PLk4MAaa5hC2c08I;0(ROP8xy3aG28>afzNLj z9X9YOO)mf+<3^ijJD`$R&{p#pi(jhTh|e;NPj?4t)$;XLwb`V9 zOUSg|s_BV%1@eK-;c3K4pW3n_T*PYOF_Nu!;mmRh4SfFm!o#QF2vE6Og4d6mj0OmU z%%|W8&|}fqW)C6lKnjXLBmK zQ{x6cUkN-e|0UTUhYz_kZi%jogjvkx#quF{=2#=%{?B|YQe`pYKd6_9&mtKg%Nixp zwgh}EYm{qk1E0UllJVi|&Pji_1blM7aw@JAe7?E}K4#DGZLJM0;Rt*-oVQOpFQ9Swm;o^TdO51hw_abC_nSz z)EMNt9Ljec;L|4gk>?k-eYW^;+ng>^jO63C&A#uHrzgON@BfndSmAT6TG{O&ACyIi zWIk5-JV00M84@@u2@&{wnDoock2Nvng5g283B9df+reJl)RB+)^-cRT#*_<&2j`^q zroC&Y*sH5d;}R><;072znM&ztFWf8mfvmC`5P<>h15 zNAWaA$mimomibuqQ9R8N_raXKUMc2{)IR4wp@&o&WvQ(>n4CWb04r!?{r zjo@>!g#3i?sdjcvV;zsg^^OQW!dScBo!Q@3pNqqAK76iD0+jX^!pB^!AQ4jI zRw;k^?_T=&AgNkMyArJF&{DHq8pT%+@mhQL`cCV)$P0AyK~i;yb|qNTq4iRy28tF| z@!Ir^GWA$Xe4&@OR3i9%jK%PAuoTc;L2qK4d^Jw>qWJJdRgR^ArgptC=a$oiBJuIA ze-$VxFUgP0r*Rt_c@kuTlJXhdgUIAK6GVKL$>gW;9BtbrKse_c;ZbJ&GUbP~2}@x4 z1_VC8cNoiO4-)m9P%hjFB;`X3J4Xh#qQ;K6nKuxht0a7? zwJPtfK#8*iUo`=r{-B@#c?S4smr41M;NS$%dICTR`H^j39;zIZ-T8SU`#^WAVzQ`7h(EE6pqf9LLd^A9QwDvCBZZ-Df4RHt|4<7?l ztfR^3J_179q07?@+!xW}grS!JLw#$=xDWbi@Zsn0xc&RC&4=b1sP^TP(lp;KoR5Pg z&3K!7FYyV`FFzleU8MMuv3znkR}Z>8@Zsn0#K;dCaxfH&2aOQ?TnwLlDN*nx@Mpp2 zccbKoig{B9&lowJk4n)q#m|4~%iz9T`DbhW3uwIk0TN_>#E&8KvDUvh8RNv=AAr1m zPIEtWCE)X>Vjv%q9J6Zzr@}pbVo^%R$MpI+oRfi1`x1Q2^>^M`g2;FU$5FFK6V1R@ z;ghF1S*830Ki|P^pZDOu`1ZlfeYRviR6vKFI<$Q-^LRpQAN>EpXODUGi|1FV8;ON! zPb=#rRD0E0Oxqv(0^EF@n8#t|l=z)P=&bJ@XgUuNx;eu36GnRa>O zXKtT)lRwLod93pWBqJ1w>jmPo@bTf(^x8R|5AV!YNyWea?oMIWC~{j#J-uSB=^^UP1<^vjW+-klsZKZFbs zpR1I73XJeXt5|^iMA#qBr@#nK&QuJ1p1t((@z@{gz~PFav2q&Y%L4eA6&sd?rsj|y zD@{c%Ioo;(J}u_s6QN&b8=xRtCO;RzCsKZfqS2^4L@w@w&jIjw{ClafhaJmk2yNyK z{jO{u9cx<=R}jF5+C~g|=n8En4}+#+_t8RP5;5!pe+hivUi9&C$&X!?z^AA2s>QD% zfR9Ul>{SdtInAMBnZE?_x$^Px+8^r#u;hdS_;~D(8ic^-!_3F0sdYLBY^z!?)w)P+ zn8~wJtMP1C?{xG8jc(k0#>Q;+fE%x@NfRsOH||{e`Or3=mHvW<4{hUFX}nE+7<}IE z=ObDiqiqW~Q67;uJGL8%^EJ>;qlq)ILZd`CAG4i}*{wICd**C39_On+Hu${kl^=nJ z)1kECb{9I;y1u8iaPTMmJEs-%gQnwSwFBZS97j0%2~G?)``nn^G0>l5gVi07pARrE zAG1ZaB|l(f&b)LwJ0uaI75GTgv6vs>0lZ9nmNFl+|GdP;oT_`ZEc(l>z$aG|c<}k) zp^J}ScmN31V-JuIRhH%C20kAG9w&ab`p-)OghH3nqh`JbjiU-l6l?|gK^@HT@yK0# zx3N89#AgxCr_7giaLxmxQyp4+XsngY0Ik6194A09I_rV2V{D9!5Mc26`K5~woL9L( zz6)reSfv7qPeF)}IMu*(^pP5{0w3o*tQ-hZrTo`k3p|c~iT=;x{1kWmlj;za1bn;) zh2$>wApsyhO)sCQ_=g8S@u-sX$#3jq@mYBJ_+6Nlc{ZKcE5;{Rv5(1zpTF#`PjJsK z$VQv?N5szYcs%*%!1;x#UoQE{RqSK&xr&z`R|u2+~77ayN)?Ll516|oN*)zVRN2?Qvkea=H6X!NHWOb#ZvEaEfv@wqPOSZm5PT3${^DV7g! zMurS(&M6U}rI!x{%v^jdKt$(S=b%Xos_oF6y!>;-@^Q#qn_Y~1)U*wfc7h$<(>x{U z!RLQ_#LLHv$CRHmgkt%4Ho9CGh!|z~k{>9`jS}XtgSuV<$B}N#v(GGX{Nh#?GC^aSIUfq5PQJ zzkB#VfYKsLC_lNUM0^%;e6;!j7Rm#;jF^~LEwHR&Kp(vUnpL$)Z zCTc1nU8b9lRA-p?fKa*yx=Vb5T6V&vpp#8gz@ppPfo*T`%;L{VGy6x5urUKzZ1qM_W_~%GRXeC`K2H} zS%PM1>@Yrxgw6JqfX~+gk1IapX&)yb)Z6WdLOOdS_nk04xeo~4mqGILwap+t8DeI6 z=rBG)e$=5vd=^1`GQ`YD_$U%K+m}))8|>2I)70uE)Na@>XTD>~&)66q8+Y@aLXEse z@Oj%3eCmzXzFwh8dQIPHqhYu?Va0yR8g0l;3$8wz-0$6?33{z}Iz_wiu{iLPZ+08d zHf}Z0fzR84$Fk4OZn>P^7zg|Umi)|5PV$s44fv+fPl3-rx&$BJ`MG=g*YopFGajMq zJ3n`?_fEx*&gJ01X8}ACA0+2HjlF`&$Abr*`|AuZV|P>ZaljrvVu@!qIyYt`Y5^Td z3+?=ejK8-R{YRpI`n9|YJ|A`SL4h3(6Xuh54uT$~zeVy%KitMXQ7K=1>m>kL`NKxH z$+uVFRO(K{%yV3~wl&3Vij%IwihoA)F&_`-P~&uJDbGPYNw9?=cN^lQYoNQ}^KHz_ zhtIuOV@Ir?CU4pzjqTziDs@Mv@M1V{+Mu3?yb>YLja$rXAwEklpJq#MYSa!Ad7usL^a*>t@z50A8a5G-;2?T_y!ANS zYB!o1PAp)}n%2?kjWmdw12jc9uuFi%2II|p6WHgL90IjRV*}?Gu<^i{8N*SU(bHYy zD(|k8-}6&Nk{^=~$}<~P9Ev76G2We)nyKTQ>clfMix0|qMty!3wY?wr4pwqRZ`wZU z5^{b6pP#vO@iCkE;d0>MGqIsdcKGlHhmwz13J>h_dp^a$M}Y835pTgCdzM3x2voR` zKy|p5Az~I{6!g|yKLftg}Th*4cRYD5_mFzxex~ zIs_k~UmhtEULH)yyVGQ>+iIXycC{1l>VGu7~%gTe)K5yz&0X_U5)I;#$^*=J7)W#;@%ewg}Vr+u0qx{`B4k15H9Jowp zQM)<8fdzaf$x}`2GoiDnMT98i2vKy92dm7{fn+pg_j;3)-ju-%^>E(hQ4f19H!ot9 z^7p=O0X`+I-PUeHwGO%^jcvmkm9)p4gLE+)6B$>nTn5FM=5+vAGNx1Gp24;*=Env* zf;T%hFrIagu02`hT{BNkK$1EF;F#TA0UTfI z;v}?ILhQs!D_15ibIhpMtaXK*0z1k#VAB<<< zuss~YbFY7rFIy9!2CzTh|Km%+2YvkNusp&b<9=7KHQKbiLx9povf#sx=EIPXd3!#b z_XdcWvAi<`uC${EUCAr+T&4Vv{%`?4$bi+Wddra-tGDQZ*6mca)ECe(hQodjc^*@0 zUYT$I%8yzpFTRg~Pf4%ot*VCZV&>f4X}(HJg<7+kT({_3mwJQVq;DLn4hVdHo#dxX zClb;5+;ZlbdeiPt$>e;l0xwLjiSs)CaBSf7 zo0s6z(OM0&^)O_4~r~^Jh zg_&^r#x%7zc;(1~&##jFgz>=@pkc3>oKBIKPRgf0JRZz>2{2Z9gvaAk5jK@3DE!ce z3yP@tbWY^l5LCL7|5LX03UCIWUt{XhQ+66EVA7w2N@mYrR z$!vi__$X(Az^8H;%|}=u>d)V3+)BFnGJ=m%76^R4wFo|?U9E+p`87m7!oHQxjLC_@ zc1K(Vx6dzLI(&R~M+gt8S-P9aM_IdLT`lD2JzRCE@Dl2IVS&`1eBnAOqy_D3Z?dqtT~l>JE&QTyd5!2T!@QA2+AnlhhY`;&r9Qv0I-9ASU<4#WA__9rbM zzx=r3AJQ)+0FnHR!}v({XH9%$`=bb-55A^Id@z+*+vF5-S)xwhuZsNG2S5MP;j^B} zsl&&be0hws^DysvRw;k*^I!Dyk*23K7a$LxPQy(3vG~Zrp*nE5eg5F*zZAm9G(VXD z1@WsLDI3Faf~mnwjuUq40qRYv8vUaO+}?0Smq%BcA64f<#_t9Fqc z_`Dx@0{Hk`y$~VNwgfjnAInrbrYP^RGhHU}Sw!;5;=LI5r+DSZ;-ixH;(R_(jOCNo z`o!^3#rhDR4^4pQAsy|JZet$`N}$nI^q|1>b_pfX*auIIA<+=KTG!ElU#aY}^;dMXs1f2~*&Vg)vUMHc^DY+1C!1Zi#`W`2%Pw2jL41~>eA3%x zYusQy>eyxLI>6`h(9MSqgGIB1)ov0WbZ$9ElLR$y;PaVF@Ufz1UsRZ>`UifI`qLr- z?YBNERsV4R{+Sm8_{bAfSk}~YR4*Sn0i=?pCiz)}^JzTC9a(BTKKXI2eklZq_`DRx z$C|)r5THQ$u_o|p@%bzZ;Dbx>Cdg9dSiO84Bx)s~AwQpeB7l!cWh83ZVhk7a)p5+IVFWdNT5`;#h|_VNj^KS~7C z#OLJzK3@Bi3JyYLFCVY{Q34KK2l!lt^KtA?N$L;CbklMqQ%TmEB0AvYh{yE~DP8ta2UdxHh@;l4d9pg=x~?QNnT zo#f|vVUn3vOyDKF?#Ajjg39~lk7Iw7 z0YvgM4&o!(pEdE3?T<=)-gyZ=HEnOZ{cKljb(|*atJJvEjPs-EJLbk@<}_L7iG{Fx{b{HS8 z{mC^PTnF*FisNJ3pX77Z7(R~u$vGh6^T}vFlKoi|AKCuop3l#{;SzkBja$0Cby=Ex zr8~9TiG`Y@yFGjBvVZcG-wB0t3H)BA{Bv6@j8Dp#M;*NIAm|t)DQm?E#strjLo??WKY%955Eq`&p#viX*a8N zt+cx)I*hf){h@JurZ^q0Uq1>w4j;)j+ljFZM%w1%x6Mjzkc0gE=pzyz|HKp#Z_3z^ z1k=Yy4h)?jI`@8z_^?nu84_b$Ys2{{lNd9vgZMlV!Y5N=ERv5E7^)*c#AhM#u@hss zgjF`k`Si;{qDEp&lAo6(K7RX?ElBk7k?oH{aU#jjGL(-!F-@NMiPSGZ;_dm>0YrRW z4&ftBOxMK6vOh}k`LUwJC(8b$nQHj-E5QD!Fx7zk{8&@s6KsFdkP!;z| z5TCdry0t}veWD0W7%o7_$(bh>`}|il(cqR=M7jhDZXW&(Z&}& zSh<-wHm1`a_0-HX;D$Z~`FY=!#0PD%F@^7RP$O=U%Jj{e#=yACn#Qo#n@~sEwqe|{ z9&T09yw(^#mTBMz{2}mpzgK>$rCY42YdDT4!@`C6{oV4@KfXKe8EA({i61fXdcfD2 z_0NIN#~?lrVRJ!)T9Vw>fyG(_bEj65Z!W->>7Y9;wIsRMlbS@TlNPgaR?0vB)tAI) zx7zL?E?gI)&RKstgQ-y+5%>%^pKhyOZ3b1iWLrh;%qPSCIHJNukyTXU^CHQQi;q8x zh%`kiV-&(ijuM^Bhi#PlL*CM)KfGfL_=fKgpG6EG9wVj%6wOCOi7EghJ}*V`F=NCv z^0A^sMfjXEA0KB|L9i=}7y1zSagZpoiVFETf5OMdZ-3mbJ~JQL{wU$?iBB3x<4QtI_DtRQ^_3bm+G>c?(A5?jvt5`C&X?I2ny*(q!IaikyeJnr%RSE*^>F zBj@UI9Z3+y^N~$aPT>gq!~2uC=BHlyvDZ{ZN0)LL$E(ChP+~qgpNf(EJdsF#V26_9 zVF~$IrYN@pM0^%;eDLj^C@5Kw7|+K+lIN)y@p&nZkIViv5+#D-`N;MszmYWYStjJe z51UDbC#ik`QoajXiOhvGxo{;Z9U*Z$-Xj);F=I84Zg>`y{GN%c#%Ke+@%@-t4vhufc|c#`sw?N46$ zysPNtgK3vmuanuSHTGFu6LDdibsCB07Bn$)*&j5bH-^LBNr4SU_fb-I(x0CPHK)(j z%!{sq=QrMU70svJC|A3CLbZ|whZr{npWON`lh5U4az2SO94YzaQnyS#A1i{-zJ|u4 zW)sbIZ1CPU&{!1Zs#9b%RNmkX`}_%#ADK_^npdjw4JPxkN;Gq=NF*!)w@UfLr^IKw z+JOM=>9t0^u-j;%bPNpx+Pj5kx*feB?z0*dzfi&q=T(y@soJ}sK#&CAlJD;E1&mNhF z8*#z_IK6M2j~`gy(n|R^-?Ak6X*EivMyPtNnH(k1Y_;8QFH@_|0c`b8!>sd8atKc4{o%I&Pn zp+tNrf9SYwdv?)k>>+cgBT!776?4Y*^YQAJ0&s9S#OE-IPnx8mgC{_KOg@f&DFKN1 zTm|y+=vT@uPJa3E=$9f}oQTgS1Nq4QDd=>YlV$K}7ceyIQm^0UnX`S|sVx8q2nT!Hcvq+h(BLVlG?$j|l@fqXprl?F~A zAHV;iRxY`QWAZ6R@v-$Q9iSxom4E5s@$)+t5+AIbTKl@UXwHG9(?+9Q&$W~Oc-%YT0&_a){mOxY_D3o zRbab~J)O1mQnjgD1q`gw!ZSfvYVn~4H{${uPkLix0xH6>_Xl?i>}+)2W0T%-e@wE( z3mB-A0JQDo;@WI<4NGPBHr{Iid_GzX=0jD`d|5T<`s1F9hhC9jDlF%e5@WnX~ZZ;lq%)__-ha!Y5kp6xu8=J9?Z6?d(EJ$kAKcte`iON(dc2teXC32hY7Fpck^Gdk)~##&@Jd>4-#K8n z^@`rnw$XBeEVgNpdGI*Oy93?*X%vxBQwxi|{fQPJP~9}Ycy3YbLHw6Z8l=$6qaiNm|r(yDEgyYLs| zB3zkI0h7>yp-M#Pwshe0|1LuKz=dheCX~wkkwlMz_;8zJjK@%`L}TRPO%?rpPhQG= ztmQ9H`UekFtq|IL)GlvL#z(R87S89TP(D@}{kr&AW%TL@5aj1AEQk*-!CRh?s4&wssy_K~kf>DtL-O;M zCxZCM_J=HU8aQ$GN1gH?&Zii`N7$eAfPC`fTHa9y5Xnz7l#gY9*2TxNKWgz=2Js27 zKPk$i{Qf<_{-{vkLh|!+5FfAoNdqT|{ZRpqh=1O46~V``Kj{F)+aEOmk^Fozl#gtG z*1<=%Kg#fV>tPTdkNx4RrzzHXeDdS5KdPK$0Qq_AIEasIf6~HMPlWQZ?9aORSoTLPK8qke9{ZEF zLfj`mp7@97>aDf;JfFV<`FSabk8FR^!ilp#s=zVr&oY9Kus`Vm`Q*nH|EL3q?9a=g zd@TF3E98SHgQ~&sQ$JJT^yss7r+#mq7t8R03SL0Neu_W;O8SR zz$*d=*Fk(P!}(-Q|Ag}q3-HPSB0evM@v*|63<4A)KUM&w5})UR$7g@6G8b5lOb1-~ z`KVb41o?UXkqADr9U@jqJ$*PI*$z22JFkHv@nP|Nq((Q%0-;zwiWCA7pC{t@Sav9d z0LAdJ>`?9ni1;ib_z)8NfSD9EF5!F}Bq|gF5ucYL_{jDrO%+EtAKCuoe$`Ii+RdhJh+;fVRy-NSf3miv0Qcz(gpA56k0@#HHpA97#079Yz0 z3?&@x7fG<|@61;|hC-8=EQcM1DrCRQ2tzjYdWXab$Ej}7Tk(9K-mVQB9>8=X@V z=xL5uk%O*4JO@7C4?HFxR@$vLvB|QWsi%beSIqqU@mYV2O_nDLb(D~=g7T~X`Zmdr z*()54BSPBKT5+QAUu23RZ%xq~Jm{1QJ}u3^Wfqr5d|nLVBL{|d5SB+ z)l$aPK&xI!N>%>q-hbSPxN)zM#3w+q)biM(e}zbNSQeA*=fS-sKC=E4Sl192PV+Bs ze7b3rKkN~=LHhHclEH`TPjNtLe8OpI**m{;M8v0+%17wWy7&nF(Z_&@&pe4wg8nE@ z-5K}=`$^EBa?iX%`+1ziC$2w5;Na2=eB}72{L@kn2mdAexz6Ad>Q6C1X?#Nc(ZPB+ zpI1`($ojJmKC=Gk!si$N&K3AnQPF10eBLxRIxVw_&Q^v$BYRp*$pVv8dQwG2n*;Yn z7uUOR r+1)q`OdVHl-=`y$eL$>vc-+CR|4^@Mt@{pLrx1MP~v;5oh{mVctNGcDB zIecsCjj+to?!$=6T1{*5e!=G#_Q6N)|Ajm|(fTW>#>#jt{(9;wk^Wy)Wz{#Iu->R1 z#BA%g<}>2MTcV*3TNCDka${(a=Jyrm`(Ips5D4Av^lY=83da9NhqXf6L|MOc>LWL~ zq#~JT=#EBRKEtsd>#NlAY*7?OeXAzB51~j3Lg8cvTP`mPg4A|X@FY!3<-RGW?zxdQw3}&pAR&td^i?9a`5@j zR|$MpE%TSiN5fiww)NXzF-zdHWd?2E;aP>{$4KOJ;6Bt$o-x1p?Z0kh@L5uxGx=yF z&y3GJolj9&4*WOEel(J2;`2B5v-uQ}WpzG!$TRV&0M9~vDD+3__>QupEHYFIfwJt! z_pkT_6=g`v7bk+xS6@kd{P`CtaupIC*hA4LoR64(QILEHaV~n5+y8m+dA}j?5%UXX zKU75AueVhpuUjzNQ1;o&Q;&%^$JRyL?E$#6O` zXdu&L2m_xt7z%s}xEA}2WB!%MM+5gVh|gS+kD_Z8;#2k^41B&YjSo$~xOcHYvCu%4 zWIufR#eIu~ijovXwtPwi4Sc?6KgE91`Q&?BQ9fn$HSpO4p7{KN>2o%pY;RkJPl?PX z7$?E!aFGx4Hnx}P${1WWHhy8t{YamljNx4%zXg1*V)jFJv(xU?@?vE9I`QYS{cznm z9!>j`_>YzT-{A8-vlt)Iol=T=I(uz2Nh|P>`H1e6Qp7X99O=EfE2D#h93c+!|Me;%k^BA z?j*pJn$?y}b1OKxOD z`5ceD^TSixE!3#>Ap3yqo!5WzY=O_7RmZ`1p2NCaes7e|r8gK1A4M}V^~m$Jcm9jN zOMLkGWxu;Qt5;_@JGdd0KIciE;GfUs-OX9GI%9aOVV`sG`R|R84{P_{rW&KX54;ko z3_h%o@rY`SYD&u9dGC{CKm5?Ug}m@pGwV35E<5z@Aun9Rq&n#X2OkG`BtEQ3^~#t+ zKCDT#wwUalfA(V3ene((>;PEs&xY0Ab+#qMiBCg5qOMK2LKr;&f97G$zO>DUiO)+B z`w@KP17HQ=fY>4*`2bkJs@!mJAH?V7bUxyMQ(-_Ue8d4KZ2*DK`>rB<0u=mU_g0&) zwI+H|`imi-0L3x$tAi2S>q-C3a(##RMD0iRt0m#!7DGO=Uugyh_W?d1Fe3KTjvU+Z zs{<6S=MwT6MN`6gbpUPZxe%Xwi+p4wT52*M<0Bi9R+D+~`J<@)#Pp|wlb3a;RiyV9 zDM-jCra$9D7jv--9eRJ!eGs3h{m7=XB%BBz*>p66!}xsoORggR6}O+R^`NNnMEJz* zXW~85#dv%^>El;tIXDqM5&O{#j?d?D#D186iMViSK%xFHJ|Zq0>juc)`Eaii;Umz5 zl_7z#@FV0S&|rZKiyTM&=~>~6-Qq8R&(w(U@#pVi8WxcwW24rr*4eu2_S2c~I^^Te z-xH^)nU^TVH;GSl{EG1jhck6JxU*C~p&XUs{`1}h@tG&tPpekFj~v9j-%tBK=d)?} z)^pK6e25Ihw4W~T>)`Waz$2}XvH8Wy1tLTHVe<=Z3q;yGzxq3&{j9IQ73cFY(BEq3 zSO3j*U_YGCrm@=CMcyLw*);SVyXZdbonQMr;PL&-x1Xw0z27x!b^3uNA2J^lv^jh@ zar=WMuXUTh20rdA^S$k6bR!Yy?~7dbjnv z;PXFLlK8M?vgO~^0w1;zwEXpM>o>vYd#}NVjbE62wc%D&ZHy0R%R^%Rg{jvFZbfwt z`EaHmBzxx%KJkk9v`l-~>URC$2h&p21gKk`CDVHiRHZ#R^(GTP_`#$UH30_Rczj!i zu;kwbpHHeR@-Z+43uf|2N)(cPr_tr9eipA`1s4GZL3bT)!8a)4_N${G0Esy?dPnH^1R!hzmL2D)mGQ{0Y2YI z_OoTSx2$Rp=L$?L{H%UITkhz7hXodb8QhbTw+d_VCCw!GHl zUsbW?rM-Xs`)|AkpH|OmcO3&qn@k+)w#<&xtTk;uZ0%wzqv#{r&B1fW!}I?62_Lpj zv5}$6!`}JB`F;kUy9UvDN(^Mm)|JPHMs)6W&jXPDdmR1X9DvP_VbkC+;3x_NAL-<4|z2t!lm|*_zWM8u+t;> zgz3*A1&;N_{{V96duDA`IKIWz~}dYCybw~y=t$qWw9-0bK8JH;ru)N?YUah zQs_G#dIKathZw#@ClJ6-1v+w94FuMs{$&KMic9-%?V2);BzR;zn-d1o@bGxkO= zlyhkse2y0Er`E*oV6$sb=Biv{>#o6AWrFd)8R64E$L`?y#P5QdKuhI{xAQaLb2f|H zk2r!F&4QLm)w;W!6|<{^w;tgmj-W=fpySoZN@-W%GoBaWqbNs9@Hy)b9wv~!-Iu`U z$_V+e;}(1n3q`1aTLm}c^I?ZA_#md0TLt$4J|DS?@o75FHj;k)M7<-KBbi9;FAWQzi5Pf*5O+0+CCqhU5niZ_`LZl;+)X4|xT@URsvhu^RY(~1QvE{jFCL=r7#&~#nK(AsdaW*|aDSS!!@;CMze2xVl*iNV0M)uRD z;TPFj-js+BY-ca_;4qn5`Ke6Bv9LH`W7QTkyC?gMW48Qc2=h5h{F&Taz;PYKG;?s7jRc8lo; z;PXA#j86|Oo9dmYMh9kA_{kQ=^szS>M>V?eWp4c!z~@KEeyZlymT4pUSy`F+Emhrv z1NQ{ck6++VR|^84SAZwvgE9e49QIn(#{xdpQ*5P=0ZLCowte+X#C})>j@9)i;KM3# z=*fmW0el*BWD6oN8@|A2I_T>^e8GOcXM^$a(+b1OByRHJeu5*y`1{R+VOU-5u}z+#47N)4_qR z(k%FxWIs4dS*x#w47)7OpN=UPOn37k`?2TXgJB)Vw>hBDzx)@M@vqbV3;K8eV*d5) zHSs}lq-MA6tjmO|D2{YK84YzeA=pn7c%Irl~H zdqm*#6t^Fr&lbwf(*e{KL!p4r7K+W&@l#EQdE#@;{LAOlFq@7^mbKa=;B)4l58c(S zb(_BpK3_1C`IzmV-K(#>2^R2iN7Iw(K-*0)@Nt3XiAL>BR8HMQiCVryzv5^fZoYpr#EA{I2P9DrFC5=V&HRE=F@Vvune^NGOOTo zF+9LBkiN^T;PYS4CHuk2+x9y7biC0>b3Q%bf&Os+f;_J!XIa<}u(sKLjbE%I48izCKI+bj<7`6b{9{A;(x1$L4wbL zdyfC<8wT0-_dQAW(>AwJ7<+XtLLb`h5ej4L%SGG=_`H+x>7gm3X|KU@_?6pJv}ANo zG`1XmAK>#tbJ!0`_ClGrxd8=HA;m(~T`Q*-wO}oO?RYMf`AB;M0-q1;6Q8E@0CNmu zgZ|TUwx3?n)jH?HM;Dl57#sMnaWOo?1$CT?fzQta&l8+*?e6AAsNC8mbZO`|rl-*iWnS;go=$hth+u#3* zGw{KxPqWrq-d<$wq37M{=)8ZSpS{HI1AKlKc>ML}-~_7Q5_ZGs?xGY~cNd4Bc!g*c z+o8X~*Pp}V-K@2+u@Ss5HinZ^)Fhjn;>6R0^$AhEbo>@x)qjJ}&sV^Qr(!PCDL47; z@%&7E`s60x1+D-5;J+k3{Co=QeM(yx5AIgYFyR+NJf+lcnN{o@KDCWzDxJI<+5CJ8 z>wQW^>v)|=Ip_EA)MIJ&2kznU+&JjdX&F=jtB9%j_|1?!@&n%owJ^uG%}e>BVH z6ZUTs%#3^&%it6CZxYPP=2Q|c;`3OA&t06ow0E&M?b}rjBPBkA{>dqpr+v#RB_;6r z5A$q3DBn`+n)MpS`0aKlzjXnluf(S|aR+^j?qsH(U1HRw2v0P#VK7TUL<72j32!`&q%^KonY(ul* zT~@Kh=c#;nDD7TcARMBA`7TwibNdLH5kRvryHtQ|`yahN-+o#+v&$g)Z1QFobiOi0 ze>j5+9NJ}!%E(0iw87_-Dxv+LZvj?#EIPl;<`|n)oGm{Zl&{F2`+RUcaekT2G0Ki( z;YPsc&(DdEf4;KQ?d|L!(+*hptaRZw)LszhE60=R@i8*(_ym>BN!2b;lAi*fF9n|9 z{0>!`w`>cW8K}V8#F2weZ>e`G&hPMQ^4^Ju?F`glJ;$Mg@pP#x-p((9&vO--kMCCD zqzh$gF#N?vPbeR2oQzelPPV6$@>0+@&nk< zx9rFHQ1s03EN??e{>Au2ji~fK20lL}*$+IcR>!EtJdEvk6$uInxc>R-X~=qO;XTaN@FI?m?x6DKWdEZ2Ro(;Ewl#cYbH! zUIu-wHU|92rN5*Y2GlNA=+6%N=k5eYT4*TGNBGucwE#C_orXC8sja)Mf?u<{NpRwPu1DlS{oc( zygEEM&>jx%!?u6oxB@=mECK;?2eS*rJ$`?y;Gac$R6i${G$08<$K1)~1?j~QWuf79 z!OOJtT-HW}#OFGPPto3$WSa_nH0fXY6DPB5KBCuop&pise9CGz^bxZM?B{P2AG2jML{3nCqfoE*& zjJ)&1Q(SOSpNAvV?k}fY6Q7sJezN)S94RD5Aw^mVkpdr{CxzrFq)C?(4s?O|Tq*N$ zo>#`*}r`4-0^l@GPZ2CFOIqFZ1zt;A>68sns(>oXl?q_Tw+d z_p$QcA7uVYDZdH(`E}rt`=g2V9>i~a8L`;Rl;5V*A5E+IX#7JWK2Ij|ktLZTXtjaM z{{snpH?e7OD; z1(aYvKA$iiJV))eGR8bIB=WDv8GMBPtc#D(A6*Oxd_Gc1=98d53KLTweuDiZ=ug?L zhmG$aX(jWC>yJ7dHT@|+9NY)l&weJKP=AU5O0b^={m}ss@wv$0BkRvP_{jRB2cMt( z>>2oMq1A=s7@b|mp+2!<4i=SVOj_w1Drr+&?%Ba`XpB#XEXP~S!E}-3UEIhHOj9DM%7$57^@K9^VHQ~tR;@wunSM~r1E2BgAA zjAdmuAmVeC&xerk{1(MzyBt0tl9JEmiO5r22VE*N~ zRFGxRrzVYy^9yD_vi_8q&weGwCy*aMAVeWwqvLGXdJW37Q<{FI@^R7D8)q+2%hwnW zkNVTnCiePsOW4o;bpbwVqgT59B=9No@I~`4*1sTa{4&uNetT20AT@a|Vn4*EtnNj8 zzEkqAPPdKKuY{y|ls$BC{#{Xh0{ap=`uS~z@s|IYnTf0FpHNku_C!oO1Z#MU)R42bMU8s8WB@JU5cJehpN zxUPc%5ufW6`@#DU7FB)cQk;FQqCe%@btXQqr0_}BA2mcv>QA}gaQ*o%;1TQdi~a>j z{LoG@3(Dq`u0Lf11pE1}C$sp(^heElQvEA3uSn9LGV+G5t}(lV(3YpJe?hBOtP$m$Uf9 z^+yd)CZDwUr=)z|Z7lNf+wUZ8FRM+#V*cf~-_dS+ndYbOzL(1~vDxWY_GuMce_=MX#r3FNMUQy#C z^he2n6!-}JDYXHC&v)6s5|Ikz-rp? zU1g4i1Um1LVm}Gnr=b>=Wz9#vH|Wn5@QC%*WIjqGmVDKP^)aE(34BUDd{KOOMS%SM z<#ax|9<>Ue(z+M%`DMv|#QMBwznrwdq2y#S{}Sz&wOimIK2L`Blg39L;2{|Kh;sPI z6O2*|5b-gT`S?q%`FP^%8*%&5W`TqF+*9Nu26z<%Qn4Q~z?a#8h|g6%AKb!H`ST(_ zA#Oh*l9DfQ5TBRx`9$__NN$@%F(T~eS6caeWc^V>l*31ke@eZ;L45X=`H=o7 z;VG;?<+L8QzVRy;ihQ6ys(6(6$of-WKJWXCna{`QwAxNjKK>ra4xSWS;UNDq#up>B zslqV>?WSG9WZSmi_Zcsx@{wf+h!lN`E}qOsmYq5uR)EdY`I%v1R!_?JrXoN7M_{#Dk2-8UiP^Ej1H+`kmzr1Fu+uTqE2 zfrAmBSF-uY{-q2^(Z5P=JrqB`uM0fbzp!F~p?{82bWI75RVp#s@;to*!_dFFPcHJ2 z9V-+e#ko6OI>twKtWbo?92iP`j8r~B!eK${N#hgCd)7dL$iMET@DakZi~%Ltj~Li> zG9cn}wa6z#!t|$5=)){C#wSFgOW-W|*UO81Wc?`)CtH8Chzor@Z2X$1@(B}uauW{4 z1^urv`|ExtKG2b4)y@0ti$4-#kGH{Kbd$V%x zw|CmTS~qa7s4f?+A3pNjqvO%EKMB1{KkH%f&tw+kv%{L4a~)aszgrTYV~v}fLw~+z z&iFXhs!^7b*>iBu6E4G-Qppib$_EY$*;$X>q^z$&- z&({JE^k>n2mN1*Z9n<+}6Z!~!{`MK;)9ZAsdM76bXnWh*W?3!)h?FN=qv?3;4aU0X z0KtB~{iRGk@=^yWk{Y6PKJrpW`KMyU=Sqc-`q2w!QMr6H+3EqG?=Uj?;4?0q{e$>W z)xSzE*~I5wCLh_qq9a<0^r+d7H$LU{M9aNWPkbsWd_-!m;zmZg{phuoL44+!e8MO( z*eX<5?MUYnYI3kuSmGg{_&mcQtn z=ESGh-gc_@gULG!0z<7)o_7h&-kOe%hKCQssaMIzDe=DJU%}@Wf#->;xwU257WnMe znpTINpi>-5hcCB0Z&clb1NX$kWlsC&-WX5xoTCz-t4u!XW4g>fosV9I1U|o1$>pOc zIuf94J|!Noq71+W%JR;yBMD)@Py-6o5rlw#x8Qkz`sW1ReFwHbRY1q=2a@6 zWxXqnk8a+@_&AkJKFfGl79X9wi}88KOy<)upL6zB_prdf#_kKlOMN{I{`F2HgU_-a zmc~an4VAY4iDI6nK-NVT=@#L}|aUqRe^Z=jl z*k|?=<+H3`@vD+PNBQXHSK>av=kEd!;-5u6%lMVJZW14z{7T#h`1~B_)2r9~?RPmm z^s6EjIoi!GU3I5}e){%1TUym&E=GKwWcHK5M_yXR&5+Nj+EgMRd1+M#IQXQAkCDSC zI0aS!P!=Cewg#CW5TARQd_)#>F#}5HBeJ0NFd*V{mBxpV1e-eHVzkh%tgnfDLL|Y~ zPPumnxqrQ!#z)qlf&+dcA6b7i8Su$|<~e-AQyA(tl*K39+9|vBaQk_j$w%l?(=v~7ih8zDYVF7S~j7ML_GfhfvHUf2jGVdaMd zO2o%V;}a~b76+8bC$_Mv10dpaFPV>+SO^1R$zP#l2PT;KB!Q2ZSZHNH#OG>(4{jl< zKfErs`tn#Y{VB0*6Q7qC_$291F+>UW<1cK)&8Nh0eEpfH@rmkBAwY?IlJ%$5fXIFx zC-YgNqj}AwngMt6@L2)&ie&{ZT~} z<&zcvlo$@zpW1#JpCtWJ1eC}pU4KeyJuE(~T_p2K)}Q71Wa&?t`P?@GKF|qyLnrtr zi=Q!VMG=#R(dq8hEuq6{U%CC{=*}UEbetLE$>qRHyUuOD4*j_w>JQT$$!<8T;&jCP zl<7{I-Dp6E`B!~Eu%B(J+#;4YR{H3;{Txx{7O}js()DiZmtjB6O28+pt*7eDi{A<7 zlhal&bidLL@WdzduQ;FBI9~u!GM~h8zSILe@d^Dag- zNw3$!XF;#a&gVK`e+W#0)eSLz<>(KADR~MI+0QGfd}RG8hA7j&G^xEoBMtaCz~isa zC;As4J#S(0z7U{HK3sn^upZ9m$!tDCf7ZoE=#MshW~qD-po9smiZibQ@lTnBncoKU zua{E!#PvrVQKo+d`cv9zsZWRd*Hs>$P=AyGW%3F2r}ThGpI^@ABkRvP_{jRB1D`kU zFYpN#Hn{o}Sl1AS8MU8qqQ%x%wV1i{JAwVYaZ!Jm?g+bCf=)a>jI48LM2G258|D*< ze~hP$2fMYdl*bW_WAsGnl#^^fhI@WwJUZ=9q)d*OMTP$?*-Rex(~ieKi+tp9Obt;U zA6;hh#K*|BAD@q3BT~hJ6#0~XCQp3ssqujxsi!C?@ew0gX}yc<&s8oT@+o!%qbXIS z7eiIz*E~KUl5!sfBm0TRKRNoNgeZ@XtUqO*h!LN8uKmdRqlCxLZ{h1dN#mE#Cyb;^ zx(-Bq9;@-;`lE(NjgQcu5*rZsbSk-g0{u}Lx|km2`B#Gelya^?d|J7D}Ta^dk{-=`_XjL9^3`z^HLfgdDx;MUTI~6Up$eIJZOaje92ZcBsh2qeePc6@L6K} z-H#7r_7e%3^#DYCUe4qrWT=<{rQ45?A#M2dj5I#D1v%Z0{7ZEcK9Ns|q}-Es$;Dtl zy?beVWc?`u2iH&JBkNCz=UfsV(jV4;nUC+W@yq8EZhxs-Pd1-0XfElbT>?aWTAB7E z^rx5srQ46tA3Y3+_{`JzBWd>$AbXS>#G6im;I>|fvjMgkvg;-9wwPb7Z>2UJW{yTL&fw9}37DXPy| z_CtKM(C6`-`1Gp1#uj=DqnN}heVc^eRi}s3vje?*3)8*8zb5;Me2UE{1Q+pjk&hn! zB;LRH3O-ZdNw6Q{qwY`Qdg5y`pYr>Yc>m%n_>uoGdw>w z#@_hAJ@31l#`vvMms;rJ2L}BCDoK{pzTjW)nSqaOw(GU37~KByt|_Z9OhpicTojsOQYfvzW!Wi@)7z|2#=Efl;3)|f4!2yN7kPrgcAHKlBGcUqY0l+m`i*%5%bjO zpt9ITWnRYWBGRy={1AL_y>Z`_S{X1(tS+MRwQlnVp+8%|^MrH1jYJIr1yUMJO^eOD z#JxBVM_7bE91b5+fykINhyN_S6%n5&7x>81Oss-cAaVP-U!#1qoSL$GBtAwOpXH{e z?7E43^qQImeC{Rl5z@Sr0VVJep`k|J#m29#s|7xUBxqS#Y+~ViUX)LWBnS<4m|Wmq z$iH4*;3Ml#(U}DY6y+o9k1jI{ejmhVp2kOnhD%sbA|Jh`rVJ4Ad7R8g=+9CHl)y*m zk5&c*KGn(spNRex37ff5;=fTo3HqZ$@QnK)KCJ~las4TdD9R_UKbpYt`Ru3h5&Bac zPt1ONKB4|-1BmSBBAJh@KZOY;*pI9~I`Od#@TptfZm%kptc$90!QExUsC$#i^iV2T zr}GCbkCJ>1pEys{q7d4G70&E+$9G95`~6dTFHf0lG6 zPkdg=;3JP@#7cE0pT7dfYr;^V{M2gBY)f_%yq*(HG4&pP<-~)e%Cn+e! ziphK^8+`0eCtkv$G+9&m!balrID=2zzm(v>^%VHTU9Eg@`1tj;*ZF*ef2rarz$bLI zG6I7AeBHjpr)A-wffP9N;mg>lHLG=_Rjb~wTibW5PW67*tks`R*Jxos7ak58gn@Hp z_)7on@_dK*u=%MUKgall?o|*`3ZKxY%7Y;Doe-Z{y8ZZkoaYPT3H&Q&KRzGwsm!-k znr{*xd47>(KUnA}iYJo~U+5?eg3LDpK7R}56UKaD*p5Pv-FnRfyM8*xt6b*;F+hJ=32QKA{Me91d=e_*~`j z!3XZAD=4o634K;Epfb-hh|kM;d?NOvhA5MdY(Qm(!|mtmD|vhZ`%zy0DWX5+oLKnM z0sHy-RvsVOeiRX@>QAZRaQpd&xx{DN+TGi3n_UR-N)MmUk#~A|G;$~2(Mngly|%1!4Nf>28)m1|YgpnuHyhbArWBEzXt{$k;}nyNNpQl+*l@?=>6w>$ zl3VrKkw5e*{{wv9dBym&J9R5Kz`PP0ddn?$G#+@t0cI`P(0zc7RT7mKK zK&NAL9luBk=}v(M@j35b1jbYTNGJK`h>x(JD4!y$sf*WM%+6-jd2n~9X4SXvZq?1|eQVF!qy^{g_TFao{`RH_ zgXn9Xx3xT%`PL&$;PK?R?+uO&{+yNMa1S4PmmYh?*q}9NmJ%&(vEq-oV`DNjj&Jp} zD)FKDy9yseii7ePt;|P`u|rljK7%DbR|WZCu{95mu`WKhy^%Yb3wx1Bmt!}gupL>dYWclH<_;l@GnUAbLw-_1_pGq-4 zBtLn0*5qG+gq7;stZhPkX#TFEKg@oZ{N&rcVu)m>!-w>zARYz%(E||i zxya;$fQRW%F+%C~BlJffKG$h{67)wkK{Jt0g8tl2)R*B>jgdu z?PUTj;*3bGvmQ}C3GH`6Eh_u`qB>LIQ*8K(`BwrTJ%%sRpKU{xkGgxQ@hQK15udj+ zJ~i8Nng&~jmh*a-o?rA&yy3aOqb!c)hCZd!{NnBR$bORe#K(8l$rp|9Nqpktd&$p! zk-n1sv@-d~aOy<+3zJt=i z6z*MWL1A!Jnt%EJHKL=YivyS*-o^C!14b&JWxXqnk8a+@`OGuW0hY-}qYW_P^EjK22%rlYPzE0nKx<(@;Pca!R6c}+Rd4YV#uS|kcA3m4 zM54__O276wFou2cC0`cq(J=aYt495!sy14 z+kZGbmrlUxGJgHZz8arG{-wxA1ONKamjKTb?Oxa1GVN#&l_l2>$)(!UiF@FlB=%4# z?P5lP7TETOzT_&A51EVleop+-i+r?jr}%APed9x4T1n-jIN4gbYLfjBpVGV2!kvK6 z)BvB3S?|<#_Kc0^EZc&s)lma_uhX^KOA2(y9gO?Om&V2m-iZfS8=waC<#^(aG!tm> z`7z)DpPto5QS2W2FJl(4g7WZ>pyN)x5sG3@rT)v|>_Q(?B0g7fK1C*?3l^EqM@Iz$ zpMO$`@hLQr7v!Ux0)fx_;(Ww}qV5oIL{*`>K`rtC=qbd@e@bg^MIa<57QdYK(`M z)Bxkq%lzdMeG`1Xq$2ZKNX-m2r%02ufRDbZne0;{KG#Wn2urxUS_BQd?gF3EM>@$y z3qD^uOXI`G@xpBAFD3FRvk)ia!Tjr|&l#UL_DtIULc!jK)sAF92N{}078N^how~ID zg@V0j-Y6*pT7$_um=T|s$bM4z$k7kY#8fjh)A-22PZ%hcab<%W6!E#r=fh?f1@IU- zeDs*S`}Xs49v`uwSipcX`G^b!4GakOGc+>z5Rzct6^>^qY8Jkn#wSFg!QuwDpCJX% zG5y)I>UHOV;k1MEV5r}V`m`2lcy#CwnaIy#d@jAgVEBmIqa~LF@<_|e7y^*}R2KOJ zCwP2)7PBv93ySdxPVo5p98SKt1U@r@{xkIreUlyd8ML@x5i*yXXa9llHne67nwfN5JR8Jvl`$_xY5o ziEgir_A-%mA35#`!XQ;G>P|;!zmp_7daU~h3nD&GCh(Etp2Bc&@i-qj?g{6p%%kpYqYTqW=cd@7uGDbL-BeVk8- zM2~eJ*?wM5;3Ml#foZ$A>;fNIe{>kP#Ep>s%+vXZc~>FZp=-zON4Iq!na|@iKJvV) zAfZG)LVq+eAlT18t|ahD&>zK_DJLK2lb}B(pPBOeAU>@GK5_ji1Sj3Uf^}vs;NU)p z&we@|p+80O4g>P%~f^E+~YoGYkngpm})g8plJPF9ys5Pr~K&!D6yZ-mO zj%_w`TLC}lpA(=nZ!kpvE}jIW4HW5(g3lKM&l7v-@7d)*dfS$<)wUj3?JwvU?Dbq4 z(gppeduZ#avDpMS1U|J&z{h%1w{2FtMh97T=C*G?bfU0P>sp&e!)((N6vMMy}=UF3_&r>+d+)b3{Aizv{lFWx9p$h~++Q>8M&$IJXJ{Z4R zn3y?+Z(dOaNGOWcZb!1&)LJ~+uVa8X^|PhN#{-4zL} z1|Rsj6{%hEc76(cIm6s*%J7xtUxE)s z&1D_7f{z}2jw`8r&3^9_bNALT_LWj-aIyOTE% zpSda@Mcbk47UEN4mA36)G_SzNvh7ygY<3NdPFV6WI#sMU`);*NqNa6naxrkvCkB!b z`GOBW*R4fRNFT8O0H3d!fe&kICDaEC&?4;d5rvkcG`hnsN1jLR<5(9SwgN4Nb$Lcn zV#5je{L&@yY1G~XLB>`^$JijP-efEFY~9ChZ()I~YEmggs3|2(0U!~}cr^NNLrs97 z_~F>tpcQ(5!Tx~Hz4#gsI}j$OV{9qk9gT*QapDsGjVE{7_Agyt$$WTm$ZSeTUO>xO zVwDPMt$ZTMLpM9%5ucZf@)3DK8HCo)M{M5TIG+~{nNPCiMBNLv!w33w2U{zj5Xp@v zFT#FatjK%{_*WLAwepGh*Ubh@#HUr1PvBqagx1eT_}9(znag~V{VO(pZ9cf0F3rs8 z*2*WrziuirAp5zN`KbFBW^3t?*2-tWzix^S%`blG#aD{*5&o4yX#IR-|GH5=Uo%hO zgULlolk@Fu1d{27;}2=;;j>WKmPK9e7*iHjP2kn%1pArotMlQ4tdOnws`0s5c_#n* zTHp!i7ry=^+YgzI0vy=TtIFrqH=7`^v+e(VJOdw^Y593k!Mr_OQB}){3NDH#E$puc ziBaLCJsgR2SbWBPfX~E8<)iFQG8*1a4SlMMm|P-X#U0gE7^XQ8pU$?XyRkw^S2D}sj~JL9agosX}0`?sKCW! z6Y_U37JW*7rOMi0jQy&;=kA4AftR;0G^oM>KHpFg_9LewWT8Qdw9F#ud7#gFrPD3k z3h{YK@G+a)Qo>a2J)<~ek{dW}2jBLIuZZ3n?^Ekv*(X$^xJE2WUK~ z^8YWO?tG63Bpcx=d|ZUTSiPP z(3bI$F}b|(jE(;J;b3}%BTsS~J9vu-}O6>8h|FMnQz^MMjKwrWkYivw}~(Pbq4+%>lEqX;xLsseh`z)Q{!`seNhhvH=aIuu@YFdE{}?x4R(%hi-%f8>rH-r-q61J6CaloEl? zhawB@rhJb0To>k(zijqu^SP$a}%)v_`JbL;sa+|-n)!YpQHZe zy-kc?$^KO?=YmoYpLsz(`QG&^^SQxF_2Bc={t|q$z3V3U+=O?L{rt;!0T0DLD5PFP z!9%BAvzlGAjzeF2b!)Rqb1tP!9@Cu@cCvwVdR37xas;8xc(MB=Z;j#gk2u zpie(B9rTaUgM^wzU9jQ22un~rB zuzIb&XSBPW&8=suz4rFzgJ-I{tOi$h6`*I`KCU-BfA|GsV`n%#GB%`rut9%tX<$!m z0?VLWdgE|9!a3Eb>Ws7hK;Dh5>HFYwH3uIY<2I{X7D`A3Csp`L8CE?ujjdW2)wlct zTUNK4|JGZWQXC$56Jx^@Csks_Ne=oGsR9@Ku-9}?>%5F@|6e~y_7lwC4V=V4v22{) z;hijb4KjAJ8Q#`wVwKVA#YB_$#jI#O3O}`w*A|k3iz1qZmqiO+^0e|oo;Vu z2T6vjJj~Ige|S24NM&rslj-p>POIqn0H3izd{76VZQ4EHp=gJ-v|{4Sk6Dsb`y#E@ z@6#NktEYQ11)gxK%}xg}O$IHfGV{2IG?xw`@wpe}BbOFk8j-}u&t7JwMfHM%PmB0e z68SjKTT}^=2KXgxXps*ut*#p&;?qjtBeI{@#Ybd!YslwEuD~Z!->=p{%`rBH#kDAu zp`50}{`q&R@3(36&rorUjbYkp5$xwjUQXwephZ$NouQ^Fe6-Ud;xo_X6VW0iK-qls z(IVpWIEPP6i&o~NlNN!`k5AE84f=ktmY@`=?y43x(Y6P2Wyse|udvHGGh+0h_ag#Em7FO|>I;g7JN z7#~@7G=RhP=aotxpW@+9HXnV$AJXSnr12}}U(9}%34gNq2-(rXfQZjL)qbMkkNW79 zRv%If?=c-Ju|N}_$Ju;j5h^;q$Mi?=k#(rVaD4r_R^n4A{7Lbz7$2@fr3OUy^NIqW zg5i$}AE85K=kuR{N6ar``rLWms_yp8<{iEl&&mSiWhSujCx=hxMep!*>Ym^6H{x$I z!;rtlSlu{Rh~>!#t95;bBmvoM~V>)iIYi4W7~IG+S%F7jR%`6Nkm zkt^QL&k~<`lKuF6BxNr222=S&rMb{GZ{vr-=XVV7shV3`rcE_z{SD<6-%Qm#IB-vp z)uM?XrQNP=|IP{L)2r8Z>JGZopc$LvSqlb}6C z5k>guDLnz7N(vuIdy3*QlK5yQJprFqBA?i@VL?KReBx1In#Y&xb@H!yoX?g?>6mx6 zYps?=`QgZ@FPd!^;d9_pD(0P|KB{FSPxW}z*CyKze7^6B_^{KZYa70dDmz1}{qTkL z`QQ0)h4}2&>Q={STR6bnq~vfuRNdL36U{}92QE@Q?GL=MG4gPL`Fx1*nWq`vIi?fM z$c7dZvt=!-P(>>=@191nbc)=1*xgP{dy3w1Zp5|!s?D!$7FK0X+}Sm;rS3F?Z< z)8Cw4ZCGq@Q~ z7eDI{9%f$oX1_^%E*AL66O82$Mfu1R42|I6qaZ%BG(P^8;4&7J$Vb`_WYc#?iKimQ(s~fUukjyyA=J2 zFox?pxnTbFyR5#1;A3FYNX`E*9)ZLps+z@=m4$ceLI+d3CM^ zKCC`Kz$b{8F{R+W-A>H*XK;Ivp z4o2<)4(aN>01ZCxxdI=N7r*+>7ytMgVb$JPaHtnA;`4Hpj~pB>ZA=m$IXKh{4nAt) zGf(6bNm?!J(~Ep`Tz%$z9w+dLtv;{JM+Aqu84&E}suJb1j^o{iWItl5urT8?`~va0 zmiVkIewO%X9YBN6hsb`M`)zYwZ0K`$9*%JERBJTMe8J}<2Jva4s^7W>cj9x7dVW}z z*LrZreGs2}5}&mU?h+rZ2X~*(T<|g4Sa0S=#Fr0a8--gYRu}IoZ5J~8F-EAgx@bf( zuRCzD20{zeW!yI;`=Rlj`Iq1$8&SAvQGkx`UxJTpL^{Fo?dLj$4=o=qiHGY?j1P|x z^#WwuzxO#;;Dcq2PP5j6b1glk0PXP6a!2Fy{so*%w}>#j2YLoRUsfSLmWg$Yy1B$w za`b}!ztGIQ%`tMMtPgn_HH67x7e5D>kFHA_0iSumN7{dvbtrl;SE)c7w;!=T7@LJL$v*Q}V9R|jgY1XmXRbej zkE}yWzybLvA6bVqf`j`YKG$h{xDG7^D3On}|E`Dia6Ydj^AS3(3H!^7Tg#I9z|;GE3vb^=BzSQTy@rS<)X} z0FnK?l*~uy&${?T^hYB;?*^WQ{&8E#I^3pIM7AmhLo4|3`+tr7_Hq3DGA$CaLi{P2 zy?iCH;9q)me;oGn?yGb@l;;~RktwaL^7k9>kERBwd@HQr^WBvMK2r8i=wAhr=;M5X z?4L-(Jt>F&)ir~quTFffbNRGusFhGCA1IZNpMN;&A9_0E1A))~Fw5m5pQ}{+DDwD} zyDD~gkKpt7jRZci2(j>DP@GRJLeyq4i1^$~;3G$fh2a2yoR2(1)dmjkgZNa^`7FIs zmcmE7l``VfO5-CU#3c+Uk&lQFH8LRLGf&{-A7cuIs^GIYpYaeq9yIKQ3O?_tfDg*4 z^X{x(c(zXFq|@(!!j=M>}Db_*^XTSwWZ+ z`DiH2A)oJ`gO3=Zs=Mu4r|YzKYfT)yXg$+@#@MLtntM*yGEAdxQu;!}%s;JCrPF~( z>p46f^~aOp1$v$1;6-cdjV42*-3KthT60DjDdUVzcI)&2pI>42v+Fzn5Hw%JiUt}v zwTw>B+Cz&o9DYaP0NR^(@PE!WRS{5lR8NPGK%;+7Yd&b?bYYCA-X#v20uTxZU~e90 zzt7P)jj9Ng_yInDQsMT)`s!u%U&ca5$Jx8HWp=E*_62GEVZ;9BLCd_bhh={MWw!M( z9$wx#aK~_7cDVP|g-d*{llUz3&yCQ@-9ruiE7G5OmHxRm4+rRN`=hV9;(V;GxmAZ{ zpi$a=_>;fF%In(D@%T;j8*V$@O&d#!mf6f!(U8v=jnW>%pG2*M4atUB5rM#xXtj*@ zK|MfI!m{)q{OIdu5k6h3(dxC$70ou}Gx5$YrXzR7>)qC`!+t(-&iTmt)A7%sQj6-K z|9iO5%G$tZzU7dQC22NnQ6pAI}> z{If~@m3JXQcPM2O743Rr2V--iW!`t%=F^)B`xt@!KzVrGC<9|Xs{I^3ymNuvO|){I zj{Nf(o5se4`*1jNpDtf*De(F8l|}nWaWD0C=zveOYpyKLq9<wo~2oP3XbhtsW~dwPgIW9{V|%vZ7QsF!^G9{_yp4&PV8v)7V;^ zrOHmmyTp_Ar9Tq=YfbSXYYLzKr`P%&+y28pwV%!>AxKoAlj2|N7{6{34oHK~Cj(Cy zAF^3S;9kMxf;tspezBT=t;v2O4n~vOSCJXmuRw=j#OUtsk`QQf#dK27?zHm}*cANSc;#K)BC z^RK~(BK5;HHX`u(YZb=F?|MiO;pnr%g%W!hm?3*m*$8{1i67u$JgI63LV3fX|3ZX6kD|;PYiOna}-N z1Iw$%2EMYA;ZI}3XAj#x1s?&Q`~5Sls^WV6GZbC-yr(rW9RGg7=PUMQJ}6|@MRzOI z$~NoWWh&3}3kQ5~5N?9*R;ZQj4klWKKI}%o=Xrzp^s2qa7HVU2*Fq??jmrE5jYj(M z>hy4WcHp6EI135cD*a#}{eUJSlej*>H#!G+7i+qrwsYS)r z=q-cKTYx9Qzxb#X{b}`oCGdHKmV4?KD9KNP&wo1uA5ot+9NSlWgQ7mI&SN_f0H3ck zz-QNKqnfd~y{`Gi?r?-^#_rL_!2IGX=iuWH>tgs4`=?kHx&&@{X6%ga0dMsJc!S_ zu9y1jRcdck@HrT`hh^$l zrS|T_pCUfj5+7ziVRyao2MazEeEf|;ZELK9PtyP&nm)8F^gC^6QPUmiY8pMa0Qz`UaQNas`Z+!qx04?c~#%qO%TzE(y_c6JR*XSHSx8yu>NkzhaKPipnm z-u?LBy9OU#pClN)R=x*bza<#GR=(bCUBKS`giovxpHA<-)o_}Qlo7>8`sLPxy5s3X z?`(KJlrp0DNMGu501F=j_&hxWpXYm3T3<&0%JodZo}V5f?dKf*EB*Lq;VmU6hoVkRcVC zwS7l{jt6EJ3n5t#bBxBh?#Xm)Aa5f|s$;lg1EFKAYd7k2JaQ+<7%J5Rd~73&kDyZU zU8nQ8714I*1sA^IC*aco9^{9!{AXW%cAbWW zK)PCMp@q4DIax6!?^VXlM5UK3^~cAKQGs zWg^pXT_2w9zIfrHZr!@BcU#v1AJYJzx@Fx@v>yr!*|ehAJFI)&Lj`p%cF|k-Y4G{r z417d>ozH0Hv=otF=QCRQdbfav{Ymio5ZO2(Esv%9SCFru#qt>PTR!V&W-=dOz(REOKC%$w;j}O!mEk_HALd!CuAhgJ&#|?{ zsF#&-tqgqrnIZFuL&53>J7w?;IodNU|3wUEcQd>#;1fq8N{I&tF??Susa+ADxiX(x zuMuidrWqCHQ&Lj`pMQR}$ftqkXuKQqHdZ~56QmR@NIw+g!^DQQGC0Dj2Xca>A1(D$ z@cG%wA|HSJ63$h85R35%$FDU1irPx=h|Nlh95n;yoa!CM#U~1(jCvfs z3(C*@?AKIcd{Ba;SzWP=i_B+dzukTFg7b)<@SFWe7<%@e0cuq+7S8qtJ)(1pZ{!t z&w~D#%_d9t4YCtxgOE?S;ycYrpYnqKxaa3A-8W&~r_4Le_U;=#?ka)Ls$+bdkFH}p z_`K#ife&jV=g+-14S$^s)6*ndNqQ}p&!!QslqFrDB(H(b>-Q7*NSo|Sz0)`!X_I}a z>)qBbfzO}5j_~0nX#H`1X-pv>UV_#i=e5HGJ}(lV2GvIBww)##6tM)vpfZWG%~pL1 zW&t(OFK#>;4bM^NkS!X<*TXc)0s^16&yx5oZ8_W%7WimqIs87r=c|n*KHOg9t({y; z7?wdtmY{4tqyC{7!!qcURf520HjD5H^v7Vitb|MC_$I2gk(g5z+E1WAJYk-2i5%bL z9p+L^$H3?7_9J}6?rDl0VRJB?rFM6cY=>S8`G~z!J?#j5zP=LSL*XGe9YM-Z;%HcJ zs=?!Uy<<6xHHlHkhr&Z{I)ap+!qM>F7WNsAWU(3>o#BORv|TLgqln^dX5JH@>j??~1I@~;EHgvb$O*=go@`>nkaui)+KLekix{B}#^hY+4?85{J1{CrM^e1W} z3BOaum%!)!QTvhjB#&R2`|jc%6Zs^MU!~qA1fLJgxc#6jt{*v5f(CapoMv8bB9_31 zix79WF^%V}tx(CW3Vc3jB=OUSNOcsecmkVg0Gu@(+%qHc_XSDv?GiO8zvDZvU_YG}dU{r&$L!<t zdf*;h8pp#So?_wN#rnMtedNIByRN~9+Q3#(q!xh8HVzeZ(2t0>qZXu|?KNxISyp^( zjfRJZ!vX4V9P&Qh1~r=G&7~u(zG{k0ypk17knYjmeeciAz{jT|U<6t7f&BnY5kl3V zdwFO!L5g!=KLAsHJ}f^x#wWlcp)B+?iBEu~(3NiYhhaY~KRm{#h^ZvrKoXyln@Zw+ zfX|2buhi1RD9y^<-M51XEHoG!m0SYUoF-5?cE>xIN%Zb164+*CT8uc zjb1q4EvfQ_=c0<8uH)AavGtA48+#^Aw>X!T<=N=Gb?Q>zL5Yfv@{IY{53%))D4&(( zIf;*s^33?m;a^ccE6Z~dA06eH_XDolM$bJHlL-OERT;aP6j^TUCHLN)HF4Zk1lgn@cBQ0=Ls%6OoeEU z8VP@v8OQ9Ahk6MIq(Ur6OdRPoa58)M*Z-Ws?8oZ*(cm&T78Gd<^)vO01{ZDv^NU}9 zX$C%gS`k~Emq#wXO0OCovifz&i}SjST$~m7d>h$MBA=y3E`D8_UnKLUd3e30dWECon)h$(ofz@lqWK4tYf;xjMCN6G7o@+qs=fzLP3z(-z{ zUt!n^lnwP0qQiSx9VmFm$xp!NTZ|Z=6^5#&# zl+}TPcbxnLeBQAiKDtb}V)tS1{>EPeo+sinu2mVek`|mbWMuFD!4os^ z36fSRv4!XM78uQA(DBb8KZ;LJc~-9!@8}{&;PW?_{a{xaWRM2*pegZLym7@>$iLXc z9fwgKof|PeiWe!tkJ+_Pd1%P?Ly*j>v+5pLU_Ts^dpOi{4-9<%5!p|eHAbfl#M1Nf zBfXrTKpC2m#b;fd3-${>zcq{7k3?wMSTSZlaYEWei{SIyMh2f{EhvYNHWoyD<{5mJ zjTLkFXcH~kwNHHtc!K;@$g_W}ay1PS`Kvrb;S}ANJuL+qe5?xiME93hrxe{k)t3_Z z9L>Ndhz}Rh$P%r%Iwr-3sc7_&Xz=ljY(7g#bX0%*lgkY^IIH2c!Sw`h6;KL59o&Sxp#qU&b!(I)(1eCFwVmh!E9 zK6>~T-3RRFU+sgBSpT6TaQxg32C~4>iYL^I^&e4L!t=%+8_MFYR`N9=@cFHIgb$U` z@(EGCW_a+46iFFWDj%$O_y?aPJt{9GyY^{cX@HL$|J2RKmJsM=1t_XN1NZD8BGB3h z5cvG+EXD`D&hJ||JGeN6DTjwKeV$B5553C>Ax(xb@cFg4{Y3dJXF*Z>N#LW21reWl zru{58gyr(lWC*is?_m0~)2>mepKfnw2Vcc#hI&8Gw4X6H+E%@8HJy%ut|2WGC*yNV z7VV7sIDb2yOplN8HOwAsO}!C%celgJNVvK;7o@?wJzG1cQ%R52K}qo#^Sw?#@I8SH5*Pd=N|a@B}R1Pc+{VucR9A4lK=rG zJP-@|J|N@L_$v2oc%Jh&Zi0|q`!>@E_=vS1qg6vuHf}pqN5P_l@C3-gk$9zd?eh^O zwJ!Q7x{-vY<)Rb^9g8P4LmZG-y82C!;eW%fz31Ovfe+8mY}L(X7xOF@CAQ7#{W|i* zk?X=qHJlx%X{+(!`I#33_k4n*?tYXwat|L4kSU&GMvdX|@cg7)gzVbYZ|#Fm8?CyH z08ijz!iH*26aOpl*|yQD+X(PvyH^XXXz;%RSHDU7`JO*T_7mm9dJoDzRs)_w??1}t zj2d{S`&b`%3SIps`TW4g8{ktlJ00^mlT~d&EAPOkxcXR3p7(lHQ}s5g?s)9J;2K_)74Z>~PZxb1YB=*AS0J-q zHCw$l3UKAeKJ-a+{K#j5z7BnydCyiLb8zThOh+ikbsG$lEr-8q*M8^|_Q5BOiyZ#! znZ0gJ(Zjk*T;#y#(w$EFrSmYm_9I_@1wO5w)$Tf!xq%98f#_@m&)`oDv!e(H=p$-F zb)&oiWM)Ii5xLHpJ1!lL1yizX@Bfd)NBCFO+}bj21cwkF8pXKqV1mIyL&KkF;FNRI zKuSZ?O4DoMUx)6&fqR1BFzBG0tT}CuMTf?S&ovC>dr)PZb1&@=EZoVf^MYObz+bpd z20&Z*p%&WFu8cs@|)k`(|vLSegt)F9bJkcwEm_+^F(z4wep z|8#t5G`zv_bg(w6;PaPe;A7b~iw+H1Gi2cpjrdmEsTVBl=YNdW$q9=N84VWx9Ad=x zMnk>I*J1tn_x`Lw_QUHPVqCW#aGx?Zs!p}G?HCq)#tNWyxD-lJsOs16VNM?=FJ zV=y1C?*m`6o7uHL+9f^_eP%TwH#!*8o$9V*+%-C8lRZ^u6wzl^4RWL74i1Nhr$f3P zDm&9t_3N$qwv{huKl}Ep8TiQS&pYj2t&3_}REQpDF`C<(UwrT08~6*G(Cyuty=y#& zAE|DBkzs9`Nq;Q5K6X5s_9qDPs1*GH)_PE*ja`zx;%oP5|K!wop+9lYFrTer?lwgN zb5`-M#6O$#R#tk=Zanw};6eODwKI2Uz-sPfmo`-TdtDbCjAIIs*K$3j zKl&>C5cvF?3ixdGXiaQ=H?uXR^|19_?^U>UrAyk4H+}L<;?wD(w>eIrn)Pn+qKDF7 z6nw@Lq(-6Qp*xspQSVT?1@;ttKE;suJlL(ZT2vmg+ry-Ec}#-OqtpJy1(k=KOtAx| zA12~6PvWzpAuaIH)R4gE&&YgyEWPIPro-$~@bR%s&-F7M;a`7tKgoWWe=Uzm@QM1D zewbiCe-3zp@hi}u6%A>DkEVtMK3_BkpE_c`t|3PG6~zaZSx2-tF%JAuUQ_YGeSpvA zej1{k#KsLVdnduiZy~M)dSFF-u)qivm7(2K|TV&xocw zE@r9PX%YPE9Z#n7VQt{CWVq+py*Ad)lzFA_VQt{qR?p?|WIDp?S;>ik&pRtJAAeW_9~J@|a9 zk|k(@EP>qI_;BA>$2WTeCFwVmLBU<_-HrQgU`1CPulpt^eR~jALd^= zNf7b5O6L>R>H=Pt!Y8WL8h9D_e0wFG57%d^Ep8QSa+Sh|>oe6}_cZBm)p*mt$gm&k zFI+Y2o5o+o1~c1TRUFY$_=x_(hwfmA69}7zi@s?Sc6GMbTDtKK_VX`ZPPHF_N6?9d z(_qDCDU1JIlFwp%eapna=YPxaF99gDAH^BQl6*=x+W?=RGg9pb`EywAL^ z#OGRtPr;c+E+0*18sPI=WItj4m{Y6Y;roQEtdfQKW5fR74&Nu#ag~htT<7sA=v!p7 znS3?vH_5h#X1)gmG3izlSQl|YZ@F}lB*^RwF zZGaC~oIAlbs-L*3zThl?`(Jtf#+@^0eC8Q^)Ga1@{WL!1wUp@l z7ykmEH%NRij2Rffxb=viS>~(H=LJ!q-@q`&ZD^UR-QMqjk98H;59Sj%g;BK{Ruh{! z2oCR1aEN2w54KtIFPfaUEu7uybo1UZ=Y!)oIE8WOoq6Zj%0X~=hk`>K8H_!WL?tqXOXhMB7LKZ6>?9Rhly6=O}j|0yW zbu_(L=bNje+r>JscU#v2pMOjC)7f>}SR-U@<4}4A^(1hbPztKsIQYaYO!19&PKP6` z5wf;%K`9$ajYc?2!7NPidbjms;PW5mF+L%d<=>UeC&aS+^=|7o?Z#U{Cu%>%EG7A! z%Y5{(l;ryWpT9zU>|I*Ks6vKnJ5=e$pP?rIlESO@DJ^0g4v=GaOqFg9SSG8&FP7{_ z?8Y};&xnuNuGgyAC+*?T*BTzSI~w#4u}?b1kuQxO;PV@E@Tps<=@YDLtWK%!p?*)W zuAwg_yYYAa(iQmZqOuQ;=9;w*lA~6~W9*`q585xgeUv@a*@(dBFVDaSCrq~=)T+Dw zn%K%7ffJ@jkNStF{+igz*SoC?fY0X|;L|nR_`kK74!f1EJDRv7txbpB2l1JM55hy7 zb~mX2z*->f4o5ic?$XhJts#NW=k0?}%jzItUWf8|dLh#vfsvKceaCU4QFc`AWC@gLdOxA4hz4ou;+7 za#R@J%kJ>pyVN!+4DZ8ky!09ae9UcU%b~5nPSr6sYRzih;4f9%HRYmy;bjf;Xm~KB zt-$f&PyV_+XBKB3Y>J<7$fve13Sw_;kD2m#`4@ti{Eu!^vcL zKK2mwXzgO)^Ye4?*{PdvS|1(5*crHQ)1MCWuipcnC!BiiIX057NlcwV{{>HP(_tj+ zX5$NI;Di3l>m0re^soF_7`~v-joKW1+9qbGLVbAr9BMTRto2Yv+$>PSx9wh_BZ%(m zL;ls++Xo*X##2Ve+1r9Gt*X*hK5WqlHXdFcz?$@QHt>1NEZ~EKOgNR)j&I8n{ zU1mVzd~lG-hr>Wk&yNSgN7#ASXGjB|KJZ|Db!P<{i=y6fkF{g5co)pSet_(!V|C2N z8V9hBH+IiH1_m(L&;QHpXFakLd;}exMJKomW)xxhG4YfFY_u(_}`SdyXJTU8PjSnBVgO8E;u=)8j;>5G#bno?gIMbR6eHyJ~&!xZX>VG>U4OH)DBua>>$;SeWQ4uUB?}`N64%5 z#$%o%Mb|q;}97^NLCOgRq%SZ_2b|(o)aIF zO6~_RHg=tEk?o3wx4-35efR*z#_4df()AYpzzw|sJ}&}~&*v#*Wj0J~GzXxTeH)w) zML(0_nTxIF0M)Wryq(_zpYI?(RTC2oN_^%5{r`7&E{~#PO|q-rnA>g)x9T=ot3?Q{jG1U^{wx* z_RSPcY%s|2St#hW+uK$H;PZhg@j;;iqoTA0A)3S1yQ3ls6^wf3Q`re=y7JK^KR8*g z!8-~Xx~Mc2ltn`cqIG0xZ)o-59R&?tG{+{2qM_Q5jIsnimoxAY{t4BV0WT?U9h6>% zgnz>2WCSlMZyl7ry={FHe7>6G2iDU{8D>LAXn28{L*&zhV=F2#CpM9lNoZg+bc7~{ zayzKG!&8qvL0U~D*W}d*vTi8@pP!n7PgOb6Yc+DuB<~-s1xM(${$y42deHBadnS4R zoKN5gy;ghM`m&}MK7!=O&!=34G&NCjaE+Vt^XXoqs>K*Z2G?kBTVDmAeUhI>3mY%r z_*(aV8WU{1eB*1~_O|tX@cC;&`PpqAp_FBCKbHLNJo(ujU!#;I-rYl6TwPr=eu65s2!W4s3qJPw&PLb}So?fOYBtml@cA;} zx!2s+TNH!A%GibBpLIbsF9wqlZQsk-h2bArL4nVYPr*kd=v^BNA?J@Ho}O1)EKWBd zKM%hm4?e;9JjZxFj5Yjn!}ir4)x%h$J@Z* zshIfLhwQ6TG4b~Ue7JqyzkgqAVA+j(`!8wH@ScFr+io$w{CsTtPmZy6xe1$V8rN1o zA7Atr+TDXz$r1g~^hY0`2cOXXeO)}^ z{kyDqu>X4W)+zWb+P|j-wP^n?8z}I37s=0o4g;ch{6z<;$c2bwRK%aAc^nL2K=h8k z=pYrj5OIu(Lok^h;Pbo0CuCnuD>iP|L-tkK#K!H1reFO!@rkj2cXC0y-(B`3#{S*O z1--19t$zkSzcVHI3GcrW(U|YX-2O`n8uR@CpFfxppWyigPY%g5htGc{);n|KOIkiJ zeF*R@w{N77rKR=_iCAg+OCO#GpGEtN6ll17E!tm5gogJ6d_HOlKJ)vFv}DBao8Mo^ zMn?1ld_HalK7RYgdSpbq-u|8ErR7Bn#3yq7AACLucp~;+>rtBDe@QDpZ^(mB_}4GX!20;5#)ndj5Di4E{N9fO{1KhU>&qF z{{WvKy7BlF8hU#jw@kOcHlLH>;HivmnQlM8=Qo+hr>fK|=?p$@i{gpR=hD3D$z|{f z^+P-S#m~xne2Qf_K_e4c=&Ix|Z9bhYoS>13EO`SN`3Cs>g{jAiuaz1{wys{)>Am5kGagWKW4o9qCi@Z1 z`S||{ip-2BG_RcwuQOf@1AM*@c*OcAz=G4+Rg5}i_C@N6LPf2WY((vqGZ~kk01HlM z*Bo6@W?!V9IO$pa)663RpI@1BKE(zSts3fXK`}6qFA<|vqQgHoCY>Q_oQ|yB6LW-# ze2EyvYHwQ?X@|e`=>hr4v3<2sKq(dVVY8tWn|@Ma85HYQ=jG?Z8lIq{iuLk%Xm-Ya zU|B9VLws(y{7@hhbj>n8q6Xo{`G``4v6{W}i@@h%3O@Y&LeUf?X|pM;H^TV&g>r5p zNt@k$IY*dw_h=)*jpk=f~7&=IQ8*qNWX#2aQ<`?2yIiTbD5xN|ecNQ|>>b#jg0B|bOc1N&GRdv(%2YqaKl z751?%HtD2&yf-C$20oQM_z1&1=d<$}FTC(ZcxS>=|D0PRM10P@sA9=al^f;-AJHH; z)yMj7mN0@(bqYSkeH6f;6G2A_HTTOk##1Szy4~Uh3SiKQpfiJwFS>okQz@isZ(Cm? zKJQ%0C!H(nVm@-YvJ#)06@0|rgIB7K{byXpN9LDsPYVi`WiuKP~&wPSF3>@!pv6;|G4<)I+?DihB z6YB{oIG$%a5i9t#T=`);+>A)$D=@$!$u57>9$(ylL-O(UkO7cb|JfT+@4F((b ztijEyz57_shCUVRL$V9<4Jw{I54k}xCo8mBwf7%85UWdT*t-^$vFMA!_rqRde&!p+ z>*rSJz14S?>!d;_-VK78G4W`6mhDm*)Fb-n5i zjJfhdRd{xuT5?u*p!M_XKJ3`f$1Y?krZHPbr%=%@pDR(wQcPp=>1gozaNzOgcdnmv ztW|UT>(VU~T|Qht=h&q0_}9s`Oe8)xem*q6Ghqi}`^qDgm%TFT2#+t>$AuVyYNetq z-;KF^-1(ik#-I!HnZ>JLjjoWSBip>d=XC)-+!W?6f>`@`R#X8e=>pN^!%blxB%Xb& zV}XktOGNPb_*qzf_(2#PeQ8cB>PSVOyjqCM$3>H4@IEAS5K__i&o?tme(+lXpCSXF zG9q_0*q_~F!Zm-ojL4mH*q@!%^P0_V?d!ycTVP816 zF!UDH9Hf1QYivD)P$8;NrRXsFWckc4{?Z18eerX_(O^PV2PYi~PLt=Ql=zVR*#193 zFxaIs{(%t(NuY7t|3_9VZePIXH-P6}33bs_R2|&Z7PW-BXcnptN-H=vA>wmGd|JhW z@VG+wMcJs8;}0sAI%B0t=dtu~&>!&m&0FxPBT0e)kz)$4#A7s%)(G{kBT0hbgZ6kO zp3(SP!ccFm{ps(Wg3kkNsgBSU(m4DOe$A7f2Uf3lonx?z+54`n1y=ZEec4m+;ri!+ zQpM>hD(b0?Llqe%)&=#zyhIuaRMfMEPb_4VkQJ2He)IDrKVtrJtUi7^?liB|$@xcI zvT{BX^Os}wk(CbVpEvh`2mT2S7@d(#bbZm`;#!5{kBLgl2y&Mf4%g3b{$7$FTmLw# z=K!UgXDWla1L5%HJ#5!t^042J8o##waaPX(O2`yoCk;3i+13#e-#zPgy0CdTpJb&P zALQq!W*#5-Mqz;rOT9>!R5fG5Ey4;)&rl9o(euj&YRzTfasvm_HOkJw^b9^Qa*H6 z$VVL8@r}4uO)ehHAH+|<=lL137#M*dXLJE{!or{luHlM#P>+gV1 zKMy{|ebicp0nAZBc7_{vsA?*YbWhlkBEogBxo~GNJHrioVx3!KigZud-nK5++J*l) z1s_dCa1$b$L<$?942irFiEmG{5Zr`_CXr~vCqp8yMB?_g^#!e6{AA|i%c(A5zgZkp|8THN1V@YirydU5*^YL-y$6XMn{KGkX9Qonr z%3>jyvc>Iu4f6B)<7hrOE3DVC7vn*vN$)O_4^9iOt`MTqq2j|yTinj|;PYpJ$JNhs z@`F&YG@K&&2>GGd3Ta3YpPOhtLT-xtD$V;zACY{7+;lE1n)&5;fDg+@^WjH@sRkFi z9?6Fv6-qR?s2|{S8_h>-*zF_Lq?{u8c;ibNQsDC`)8%|pjk6Veq#0@8^9HtrPtMz6 zz-V@#!MQHh>S!^aoVUk-)fKuL9J{@pXlhm6l;YjuKBosWB>lll1A;|o>| z+tV&bw)u)qsYYGH8Dg7PJsdvv`0}4wI23HP6bWcm^LO?+@tG~+!`bj<5JE0}h*0%m z)eSD;<84)aW+9=%v&Ra2zUFulAM(`XjGQf4d=8GXL|7Y=^OAVDYde(&z$XPy;Ului28D*2ma4y zzdO2M&i3?ba(XIJ)R)%}t*!mbJop^x`hil*u?GrL0FlAjAyuUc=h$L+2lN!B!Lzw} zt;|0=8Vnxe1b*j;{()XG*#i^FfXMLdFuSB$=UkXh+{1bivBB%~%(uCXceJ+tr-)Ax z=`$&`+n%A23L5UdZ)v;*DYwdMjiLUIp%h|8rifk?kv@|`yY1Ntsi4u`1Q7=V*61RQ z6cg^^JB6;*XQ;+AGEZ>D8=B-0Gh*k1!70O~m)0A$>=gt)Z=8V-l9Q;yfw$N)nh30P z@W5NV24P~jU`0r7;Llr!dxCjI#nC#G(HMc1(RlWHKm{>EE)#RhBm%eZzR=n){tc3! zeWg_|D{RM+BU=HbzUO^&a@952PREubTLGnR&%NP0exkJx&w$6VkLC6n`lFn^9nGPR z97=x`54ejsBNt$uX_Y2}PW>8u;QJ$YZfxp2`260D zkRQ%xuUx6XCjk>W_v1xo0K~0$eyi*d6?tG5TA9er;d9pQ_27}fr*ZDTORfoiZ+i9w zHF*%io6%Hm;PZzwkB`rBOxRW38cs=!tKe?)$@=zT<@nIr$GrZRQKNEJsF%C)8}TkM z`eb)Uz1(=0XZ9+sJ$f&VFXR#}AwF(n)wodq;uP_58*6V{0Kw-2dGM*;ufEBEqCss~ zctp8bCJ5VVWfO7p)ZU0GJ=BIhWkom31Yygns)^_Y>F3dJFz^v%aK!Gi*)8hGXAE7P z>LJL$eBou_=nRn07`j@j2l1Kt`S7hL*zn@!_QFtaV0&*1*NSza(|MNkKvenQL^eskOQ`ehDS!MLr@~vjk zRXZrL~rufPEu3pFmU8ez@=KUTZo|znUxl#LWR>D2K3b!NcP&;xs%+*J zN)eZMA1z;SroE9hzXv{VXD%OiMJRI47t?bRopqZ)~L&*dYgcA>`X#&&pGNZINT zg3oinfIQII5B z4)RlokRKlUwN8bQ5TA(9FGtd{{V({OPXTDp-fFFTZsGKH&)#Y|uVwugd@fj+k5B)I z!Ij+0*XHB1$iq@Ep^GN?d^_;i^+D>YTA@=OatcrB_-qTx9xqFMWm!EsS7t&(q@Fgx4%j-`<- z@cGUu@oCkB_`r#*p;9<^3kRyGIVkq?ex$LU?@juQGa9kt&_V#WF~NcAWk#dm7Iz7J zzWW$_ns80P8j$R$8*#B~!Zl&oC6`QEKrjCNtbYPN-`2mt25tibvcII&jQ&6ddc^}A>D$eDX z_3ns=rMPRJdFA66gicQ}^JkYA_`C;rR`cO87x3udQl;&$g0zwkqbLk`bO?9E%nB9w z{PGlhv{tp$K-9l)>73N1B_PMzsfZ!RPikg3r2QALg@ed)xXx`1}I!M2s&d zL?zvwh55)KE%SXPJ~tkppoj1L<+0zf`3Q#uChB~~{&I#c1fO5bFW{3*;{-bu#YaXN zB0jespF^Z+t5lR=U(>v@`8+|IwqDOn(?T}B13tero#V5P<>vY^U^buA?vrl6JC=8YN_=J>pF%@#BdHco-?xKIe=XFNTj?tnH4c7#Ya05{y_y zXWae)J|@YJQ9~X!74cphGC{lTA?WKa{>~q)-vFNr;JH^&3P-HbB6oRiAY0c%ykMSO zv&IBI&vHM&r=JI(&v@YlrZs3-5gCz9;?wYE?ge}h$6+;u!PlPD0t7zacmqEBO65@5 zN0Q6b5h+1H`)2Qnd4USm(nX{M`vE>Tw?00uSHfD>AI2O$A+H4KP6@U4%bx%|_jrsl zm{bcepzb68s?b9aC`9G6J)#W)jkC%!_sqk0wfp6zv}mcmS|T7K7X2p`EV5- zLL;X7*isdrk8jS;poI~9J~&hcrKjWtt^ z2KW?*-I1iJM#1M(r{MFTT&+?fKQ|V|Q`91j6x0$zRLix4iW(3>KBCyeI)s9JM3R0P32E(Te;j!3*-4L_mGj!W)Edus^h(&D zKKq#4IX*ZWv@MBgm65|oWK5V#rkTN=ggc}HPar?9W8g#a@36|Zl_PEd3S5)sg=mjA zC%OIS+3RL5AL>uFT&k6|eQepuP`0Nxs%oP`ZxcYefCr?mGMRaod+h;~mtD)dK(uEL zGikSn{Cw;&@u6H}B2q96hCW$^V@||Gdm@PhnV@}OsJ)Yn;+X3P_{?MTI9c**Q|t z0-wp~u{E|VSRI?qF0X`x=g^t`|1FNf8Lc>fZj^OVzRntVkH(aBYCd{ufXJLbm++mu(vN}l2 z#&*OJJRz~p&#BlIh4-MS0SvG)TU=8iru@3rep_)0`LT1^q+Kr0{d%3JhLqmD7vt+~ zB?dmCeu{mVL%Xn4RZ~1nqJD~?gJ!!B1_^8<}!zyf@n1f#CD zmIo8$r#u56cYFovr+D&^^qD)pxZ;t~vLSj5K9yTPpAFSdarub)DbnoM!*T#V?*JZK zel~G3D1O1#JlJQ2e^IX2;PaJv;)61$P1;-dRP;KgjyejPj%n>|gOX~|?E4df&ur?+ zPoYt6HnFo<`{BsXusa@OXCdtaeEv1?IO7X@E#DHz4VM!K@<}@BiA~h;1=fs`1YLs9 z|MT-{H8IMB8uEdP?Y7|}bmV6;#wd$IO~Y;zTw#1@QUfQ$L@wT1*|(?L+DE=~^ARJQ94Jz*F$~n3<0cueY31 zX8bKXd<-hIob4^T|F-9zgU=@dk2}8h6a$udl+8_%6Vl(f!)Ff#-B|%ebEV4+DS87w ze}?(^aFgK?EQhUHaes{kki&v*G#%)5cs@44?aP?>=YnOKCe466qvv4 zysI(}Gw}I>De-A2m2z!m*=eWyEB~zz&0e=Jvu1Y3*Ovg#y*l71^*R~l$$10Lt8Zz% zg{99xRtFsO>IzF|z7|A#6S#{FSc7N%8;!3eSyXH7w|@=;pN3L4%4=1;2#Qq0?2fvD ziWhQj;lbyNNPb*C8?tY>e5AK;y#2Rsz{gMx)IYW7E!)hoV<`JdDP4S=VU3U;+@7~! z?l&*Y({83M@j>}_UTN(w{Q(9(PW}z&{dNC!@^7r$&bGf#d}iR|gFv)E(_Bg`26;i##i}aMQx@Mm4G}tFO2TXJ!>qLs5rMC z_!oSB=NNoc*fn5Sg*yT{Z1~*6y|EVf-l`WW>>7ytf-?d+Y>>5?yb<8A;ElCaO=RM8 z@cF+aKVp0#C1mrFTG_x5v(J}@*7%v#llTB$YyXx120X|Qxwp4|)(!7Z-Zan7TJC09h$pE=N1 z*SB)`cWGLE2E zys(~92_op5jkFi>6L<0!_&l11`EX-d`njEMJiv$h_{ul8Q$N7x-M|x+AI=BH)?`yU zHRnF&`5-ZggsVlZ{j-laAAA3W*c8QJO`SE5>g%{^7VZ5h+A~KC2g~E@D;eE1!RI

    kRZxd|uc23MI!JjVh$ZZV!{^dGwNP4SaLEK0q`VQt61KOk%faVIXFfh~9c!zl z98+IxDHT>%8n8)&5W9~IKt&kl{4?Nj$5*q}I4B$Y;mZ=gcK9?W!^ho`yje7f&yA0diX>W?xb(z8LSJzB zSjeh{iE9x0SelpM^W(P>e6W;GG@im84)e)nbo_+xJNz1ac>IMkf7x|nxmwP#R*lzz zS8LEXJE-|d=ZEo5?HoRKomf{b=h&prYr$K6EEsoC_w%ybd;Ix4tQq=;f>QgeXJsZ$ zH2C}k^T|(;Pg*)yKilh{c|J1Hq4o36{=_Vb4Oc}a83)8KJ_?}K#>@u@H4L%UOg)2w0FioAC1{W`p)tE=v3 zgM92GY2-Ayx+3BTmbzT^^Ben|_}nbxW3PjfNe^Q&_ykr&wxDHBiippz$KsPrfHux& zOHu?r|MnJq-2Inc+}}WXD_1{X4muYSm$xGQ{O_h=J~_tCh|o5ME;1h`9?#DF#rgQP z@@R0)HF4q=xAO(9{qH|6z{g!b*Y$QurRB11e|D#`SU2kOaqX*DgQuq!EthSxv%95_ z)!w!)0-q+t#~okX^eoWi*jrzCBjd+Bwq-TJ!Z8jXYM!6^*oM_Ct|P(c>-_R#JO32* zT2ZYv8?ZIw=m9D08Y{Y3d0Uc@?sviGUCbvx-ucBm zsU*KJFF$gU0-p~6k2}7UB3#F6Y73%MDLjJI)b00qS@d;R+`Kg{bP8DZ`&p(^`_yo00wfr#Ge!jh5 zrj2{!KKJX$#TsD_A5UQBfLwN8_BIV;oM#OA=AApkT5eeOASXk-?x2P1)Ln8OY< z#`vmTKB4uqbd-n>+2Vx-aCjWM`51?|N5X0H1$5bNS58?}$kCB#JK^%vP~jh7oKdk0O$1PCA_~EM8JSh|l{;eq26DJ)xqz@A1isr&IKOu6h@I zg#E|ICoslVHL&1wKcB!DTX20=-zGkMf4YcIN^x4qM>28J+Q0I(T>sedgQdn1bKDc$ z6*L8a;bbs|S<_8%Ylclgdw&Cr9K->K&a6 zI)JqHuYRP*N63YJ?CyDM+)r+XcJrc; zV~dReDhea>hVF8E&4ABenGzpvOU=1~ao&=-t~PYM&r4n@Z6%Iz72PQcOR5tWx4jOo z`ODz*6~`_g7Z2H=3y2p)&2t@j+k9R@F@2!JeE9O_1dep5dOjGVZnY$C(BQ-Kw^Vr~ zfp>K31Xv39@DegyP!3nud8#6kz;Eht1<5Ii&ZK6d!b4JcsD~Gk;(V}cIFm#VFX{*Q{OB~u$1g>xU08j5q|h@<`25&xIiE;1w5UDj z{iS>|sArt}4*v`J`4_MB<>R@8!{Gb~w$wlx7k@I}l?sCM@ocHEHa~+I)tAOa zl64XI7&AwHxEY?%a4`0o*$X1140is}whU4XJ|Vq5ua~kg?!f14>hSU8C!9^fgA^zD z)EQr%{DhMy1RXRoJj}r7oWez5d*dtS5@;o#mD(p8#vt(NF^A6*`Ds6&D1CyM-!No4k_l;^Vj_NS}8wSn7#P;dTA#3u-p>)v7P60wwj*f9DXC| z_{yrfhWzmQJA8i{NB?YUeqSO#S(@&_=i4AYV*c7!8wG#BprIIsve!_IT!n&~aYP^6 zTZ+rig*7~pD_k%<3~2uP_I!{}Q02s&ufh%c_ypI28J^3-eW2IG=XMnzds7iJ^$-7< z6@0Rxe4~Jb-UFZSm@ebPl|ga~;zB-IQZ6ADQ7^&gJDJ1Bo4<-mgM8_jp{k`+RR}pB zZ~fCThvrlBnvE>$RH`b3;Pc%#4xjyUp==aesepvw3;F4ubVr?uR6s)g0H5#4gAb;s zn(II2M!fTPG4;ouw%pc>gJJ)b;Xn48ADn_uK}FdV*Xhs&#NSQ>s9>RNitBXfVw3I( z)1iH0nxSUWVrP_s<+YNC{chQ3EYOp72Ei!SxSP^Ir~7 z_CvCq*#16&&o50KKJ!*XpH)owZu-Bw>^bK%zbo}^vxM*FvNp2t8TfGjUOv9&`8bEB z*tsLx+j&Lq94q4E7VvR=p^$6UEg0*(H_Re2?cs<0F&ba{N@b5nQ}QQ{qRuh?5*x1) z1HtF{tBP9HYgFc7*<;`Ao$)9){=`w#Id(zs!#DbrjV+U3z~4C=PP$|E#S`+HhTnMq zG27``mxDg4A0(eUm)%#=&%ozHj%_~o9X3m`a})?&clv`R4pQA7tI2OqsiT2)RggBOyKr z#h9F%!`(APTcm1lTVK*1e#%GPf)6%a1!xs2Zqdg78#!ASm-teVHT7D#n0v8Ru9a)5 zxMI0pD4N3)sE;ue%~Sjzy4O*|*{(Mj{yTur$FnFt!P>CpTCu{4l~w^2c}j7%8}od8 zQ+xO(GW;5RKJg}!k29HLYIkz6?jrv)%!n!_bE)a>tEleH^Ks?J4$y_tb#t*IflGhj zzH+X-s~p%-_wT$1KA&_9K7RdN)GNv^g{U|erTEvce>#Jnxl17`DcafgSBTGhBKR;7 z!h`xvEn57nJ}?b+B+Q425FXTTn$Y4W8;5_PdyaYuKA#Lc(eks#EEeX&8l1{p92UI?pHIyP_@q`j0hS)0 z?8`{t#zQZ_XXh4t{QIxHMyuT1-K!{vI`$ViZ)upo8sr~e+<3Zs)-#_Bu)oN83quL4 zLE!V;bRi$VEG6T#jE~rS5uEI^0-rY@FXSWShmwdZdwVLG#^OHa_^=51LAb%#?Do6; z^SI64`E}rv1D>Vh%g4trP)qMMA)m}DDe!rofsaafqa2kYy3NFfgcFOw! zJ~NjO@WhsorQ+k`lUdPN-U0hl$j@7k!H4o_!GB|Q;=Wj|GS)yAE%&=f>r#H;ND*;p!}04{(C>#O!x_ zcvmchRyB~3&%x&ccw9d2I7&A+Ac0Xsi!8xQa{QC=9 zL`!;niuwIM-@p6(Hy*Som!{(jWH1q2z=7#|One%mG5^wc{_gV%^Lf>AV1qN;XKcQK zjJyLrLO*-{EyZ#Zj=nYsjw!{x`uKFZ;~{+LeV9_Tx2>;$&$mxW|9E_AdTo6~K0f_H zUtUDo!_R#;=^rs~`G(e-f3Uqdhs!k^+|t*<=bLW8r>RsGcpsJ=y;FY+jsbTXDkd+Z zs3ZE6Ialbh^mNm_G~tJO>i8hmC)RL0U`Xo=fBKz<1?%CcGeFrUHny)E#A^4hF@X=^ zvE`@UsulNfL`vSf?qXU96>1p3b1e4l3HiC2^g9coZkE)VVhLdxn%uDd_EJiasu_;ED zw1l*WpZAt2_z1=9&R@=Oqkx`Nf4b28We+M5+LfxoEqzIQ_=WwOc|P{s#RCh-!IvFE zw5nxf{EK;?AwC?89auo_z3d4@>$2OA-CoR}-S}nTGrk3%VneAF)CQs^{d-i{>5F>t z0P}l=SA=&^t?pKFX!cL6A*!SK?HX7gcLtrua7yS&0t)aZfC$Oy2HZ)?H z=z7v;d#HiW-y%NIObAHfGoAypWONqG&-kLt_0Eo?fT(#wm{F~yJyc%JTt4pnWs8lM z(8Ue?M)Ah53`V_<*3Vu-7dJE>^-!a}pOyE(rwBaZ`F$xLTU9R|Zb|s$GCbC_hsDpi zb@>GJvo95GVDgHksw4EXFG^b;Weq-`J6*{qxwJ3mlf1oceFJ>HfaE8}`p1^1fGjPX z&SI>8q>v}@sSuwE7RgQcZ76UnQ$-@v6lDY)5?Q&qq9v_ut+9* zsR=hkdx_{Jnef|vcyfzAUJUxYR+F2{9e5K^PTJX!8 z)l}f~MGSmG`*(YOkH!+`4x;CGNrcANLE%9)0KQ;w2_5Nz~_g7$0t9| z394`H+%6#_Qc#wbE)LPLXg<;F=Rg9Rj4h3b&rN_2#aygl6hod;^T~qH`0fFG{!!lL z6Iee7awqUrkJzrp+N}yc0sBTEcY-Y@ncuDwpWAqR%1zIVxH6C@CLd=mTG^iOPkN_M zwTB0Pa)JCr7*~<{xB}NHrBuQg#QLyUZdIdiH-b;ZE)=Pcy;&UV!cKQ`8QtEt-X%T@ zEzWASSFuwNn2C_rqc*jd!=Xkj&6`Z{% z&EmU17$Q3)j(5CWh3DmB_Hg=+JiahT55|;=qdysAElB<@SanpG9K=QqViH^-M2wv?Xu zNXzF_W)XbIeGHjc(;W`t&mHC?_TtFJip-D7cmTUST6GP4ySg8Y2`G59Re zKUB9M@x3k8KSOd7lj8wC3h+enSu0Is1fR9q+ZIjmd2|Cl!su005W>9?6=YC4NSM0% zmfR``e7OI!($sM_xI+om1A02Gb`Uydr$cGh1ByCrgIf|H@cGBbkRK=iJn3Z~!*idj z=N(F!U2ioSN=eTNhH(9*3s&?qn17xxoxMOFTImQ?T|@@$tI2R^o(^)%)!T0H;ff!* z17_O8>6cEyC*bhYPLe4h`X<}mKC(wh>-OVz3VePHcvImd+d@EhKf2cISmzC>1e?8Az-Q|}soy(SL6L_T@!!#Y-fJVY$~8trZC ztHkFPeE9hV&kf*P|42Mw7kRQW5M# z(&W)%I~o>2SPZQ!Bp2cXv)FJnW-m=F1U$juvqYY7X3DM~LiR zQMW4YeHMCy!Ra+anA3IKuVnH%;&TN)u&gRj&A}I-j-6MKdH2WqLGy-&blM`|D zCuJ^Q;xpxZP!6Q1uMXUfU=j6J(L_0r;vl<$+fg?i@gDfR3wZ9ifw>Xaqps za)!P`d~U!;D_1M4vm(U5ajkpVLqY`UAK>%#dCsQ>t;5S$ZKO}gzsj{vbI_MACf5&u z_}mg7RCzb{bt>%O|2Xw?ZD@{07XvEnkh+a5d=Y&9))ahroM1tzR5o-|`xIn)V)l9) zYHwT35TEyh&jF%x4wOe5+PyP&U|x0~o6lr4sRsTO;PbZ`_*9h|+@oNH4t$#aMb+%X zJ!&j>aba|y_{=yTCqF=XCjM`F`2qaz%J&?6{?4)B(?pV%jdcKg#>gzcvG%sr5b=2r z@hMkzV}lVN)$ZkBWNxchoBLhx`3B$tpBm-Rs;KqNv|a7?sa|l;y4p;8+iHdQ)QOM& zpxo3qcNf*c7k81bPWlJ&xd9)&Qet}wPMP%@T))?U=sjcwFh>{Nfi$M($W9ZVUk9It zUSJLVDDs*#Z#D)e$k8vi?T7jeKJNyed&s!jJYqE@B1uDI{yUAyXnf6TNJKLKnN05x zpBKQ#fJ@5}E9u&XZr*@P%QY(vvRgSOUPp;fp7@{u7{cJn@SbOG+UI?xaR{H6HnwF2 z3T#G{oKewt`L)ZB-w4Y(DD;V3FTv*WDJXo4EoKEZ`W3 zu3FBkebF5~hJW2?AnVDp_&b8nH!<)jpvMKBY^*$uv8$p5CHrk;h(x@gxMVpVRsffi zff!+#Phz}8q>0ZAe316Y30uYhLta`+mRZJ`PgO6K_sT`3iIugn0*dcM%tn5{fk0B8Y=r8} zNc;ewzXv@2{GuD_jW56GM%vp}BjEGRdGIOf$lKf0?XXJ3sqk=1u5eNfg5m&qd&dZ> z2!stHUWJEU=Gbs@nX28p=0tpM!3XPNm7xeB+bchMw1Jy2dIO7{;}Gnu`|Q~U+S^tW z;PdyV;8Un5#RE)FhCxmW>pu!Tv-6l?mpURR1$iIfbHl&~>mRsgZjKMuKXA=_MezBS zWAG9Af9(1Np0j4^KfK5fVApq$HTg4o5Bd34;JIfYzr0dM?iTFODb@VC4+Hg2%`4Pf zW(M{c@>)5F&kgax=?)c$-PFUt=?)c$mHh!e{~!-OTDf3gd$F;H);$?vdm;UU_}qd| zRVkywPI+VfshVBZ#DB6sz~>)M!KbNWeTZ_EMyu8+8|%9%G%c(Tv9&NJ{b6?`ubTq+ zd>aEFS{lNHK_-rkJjg!^#hS>(A@zg!%!m&Tz+g5k!ig1CPvd5pU)*(V&^v_zu?Qzt z)I61~s)N@r@c9nlxmVFKsh5okSy+*8ql7@zwNB$J15E1WQIGcU$hL9H#+H=(c;a&d zK6|Z4kLdjCP_4kAy1ozn-sIUcI{$iN$$bC@KHoJ3AJp72_CaQE55-RHXiD({r>Y3f zNV?fBLn~jv0)2L7$*Y_(%)sY+Nq(H5CQ2{SP?ZH)*SvAL>RH7OY7&_xvQzJD)qRIQ z2cI99fsa!##i`#EzAowOaDAer-_OeR;PakikB?V|XU!Y5`CPhXc-CxhTVDsC_uhh! zs%bSH83H!2b?04C&(He(2WDK0g9He0{hf)1hcre$%1D=id+?oL?XfByuAZ zTFs_PDQeey;QS)TE|3o4WHKIGNWHpVb6fj1xvH(`G0r?9voIkD?W_)%))$xG1`@dG*1G2o^oS!nr62C z9qs6K_dGs4)uDIxt{jw;uA7|>2|f}fI&^M4^e_1E{KjH@6?Of9tj{|Lc4}2A;8H(O zOKBJhKApkfF3ZD*CZvrcXBhrs9Q)a4_psBEHn!H4H(+eC9)YXf}v z`jDse!*Hr>=nRAS&~WNWeue=)eEnmzjssZZL1yd`2~_6Iv?ERgU$zE2@mZk$AE|I zKO5~1`LDhb9^i97Z}ZvU@(`Y5m#>87A?zEuzdQvW5o)oyzxd(c^s)S_L(IcR-}Z$h zKWzn8)f`-0HWa_yM!H@kh#Z@;$1flK*mwH)6!d1ZqLy;3RZE!|(iTCR&&gms?pdcf zHt9>27}D;CcJyQ4KlS9t<>S&pZeuF^Mb-5Xlu_f^e0lvi=Za{byf7b^j-Ak$vi2e< zqd#!Uow|uNv*nWqK0iG3_yo&XQg+d14bnuX&ZzvrjH5=YjsPCeLegXYX*3>Y^En&B zi=LhJ%qMWwgcyY}@v7#ys52hGiHcW)7+nu1S3GvZm-*QJ;$73zj(+aT^Wal&=ykYm za5c0EEnOcDuHd@CF>Ru~ZM6YDe|-u*8l0k3rL{3Y8l0jmb0R$;@cEh<_!xRYMP}MP zbwd(l3(kGWxc5^lM*| zhy2*BDAedM0)x851w!bCZIPsHe7vloYv0(ND^U7YJczNJ)_` zMBwvfQ}9u1Myr9o`W29|uN>g5R0>G#k0wL()vtg?7v|%PbwBcN>wgn`-oacx5eg_J zB*7;_0Z9f4d}hEy=NCm4Dri#@g!7Az1r;Q_1cA>VO~L0tt&SJEYg-f(YKlBA8Kh>5| z#8D}ggiWb&g1xCuMjafLR#6Z(TM9RLn=4-tpPMiryUboH#ccm#fR9~fFJn{pN;Y(X z_UMN{o8$*kxm8N=*A$}(u0B+axuMo+UtdMNG?FT3$rEEmji}s9wujY@7)?1*KQZ|DmpltrgVqE8{6FTj2Bcz;mx`=yezn zHzq&j(clUOL}ss#SyuZW<`I4kKHr!Jp9uTUXTIRl5{Ie~qwv=kzK*c}Pk`J{;W+=Thqi{tck7z^;R*TwSDA^Xoy ze+$V^$i5-gIcoq4?cZTY!~#%4K*WdSCz6kE9f$zAMC+kQK3QA;oz6Y%-g{31Td zru4usMe>njN)Plyd-QK!3p^3_ADXQqZ9qbjR&1;1_ovumMcaVHs9Vuq;HK~J1@XB_ z#>bH=#CDY$xdj%o1bm{TDl@dSM<4idlAqwV3m%!Y7vmO;bhqlPbR6M$N_#PG!ARHM z9g0lgr-%>9PnZww#n!;%t^^%EF!0ET2lM*}{%SsgkG%w1FnR)rBVUB&$6f-ZZZGmj z?%+-0a~r{D-HwF$tlQolposhl?a_bzgemy!wNU!BxsMZf#1}BNrZzN`D{7Q$2a#V} z`R3jPrB9m|*l!`efT?|Jc#d*K3PnlRYQK-8Y`)7rc~?ef~pQC{jmvWjgs|Lv?r$sfzR$S_#p6PPgOQ2KeYkd zv&>h7{OrER$ET_{VM?s%N@+a_a`;pS;|pup89Q74w4wGC#gU@Hph!1ko!tZ%w3aByYJci%1^a==kKKB-U zc>E5Roib|d*+TT7g;dAsRzW;|hs#bEHTG;FdN4t%W4TsA;KTh750zG>>2O(NUFZzn zLvzv_J6t4O7drg_pYjy)vmv$PH2Vr5Bf0`U-2NQ3ex@)mWL$3)++N3j619Ftdjn)# zAD+Z-X6sji&v)b@KUICn`WgN#Elp|cQn*FTJ6^hehCj>X+#K#wxJAtNwsjf!eD^W< zM6I7wU~#+QtPlOuyF^&reh?qAeh#h=*I`4Ahu4QPvY~!}&-Xxl?iEqEv!FH_M@&rW zetnI^zGZe;Zn7dm-wPBCPuT*N2f*uyUPdIr)zG|VMdV7_wFQZupIF1;wWGl^KIena z_f5eka{au95Jj$^B@`m?`Jox{iCRCe!zXI}EGM6T0zCJ``VhJ6^vx_1#rp7(H5@nt zNzO$gp%OeifN&EM1U^)PhX)YKOiFw7-@bAR zKAO_h8_3QJ8-2NfD4rKvYOM%M8N%g|xz|X%N!85pU}&CNu+evih~jy1V)Z+)l(7+t z?u|zx7=A4Yy_+wC&o|}42Z!n^=aZ60_-^ZirxxcU8IN#3z~`Tk{P4s-yL%Po5H%W6 zy(uI`1@#d4w79zq#(4e8T_^Dm8w)9V$&sQH>k06kXMJ};>%;&4YU1OLFYPnu;P^#~ z_N;tuxFU6lJHDvBB||LhsY}4;6Z7EXjxRpNry&xQOm}?oDc(QGvQ8w}5AgYHk{@q; z1vN4}fEJB4SCoP+idUiWN{T{OnZ_mxB;fU%aVWQH#xnUO7VH zVMDL9D6LBripcl&dWg$Gh^a5$)aqHC@o><)M&aSnpf{nkE|K5O(wo|&|M@2t@OkSS zDZz13M>R{Ft0v4V6~PDXog-@iC1S(5sw8=(v`4@Ccc&yjEtutvidsWZ3R&p)u<9xA zl`)n1^|45ACwBPDr!>)C&*~#ki7fPISoL(zx;XXmXQdPA?Y@|s?Xx+hfzN*g9`a96 q4pD$dDWXVhfjF_{09FhF*jLR%6yPyCC=z=@oLDvitmsGhYcaj45F0?Jf&BPytrMih-;F*p&8*I7`p zo*Ku8lxSicQ>YIgAW$0PghM$*aV}BfM6@)D6Y9Ht_CC8j-*P?8`|I@|z3=aQ-`?lk zd-px}Hp}JckwJ1~kM0?1CiEnS(9hWYM)U+dhv?DY*4pSN{=fcc-5d1kzMpT!sGQcr ze$j2m4^B-@^-NIXEquqXU3Q;fCdP*j?~V`OwR?Dc59IGi`Im;gbK>(IH*(yF=obYt*e(SpRj_#e*JvE4~V=|Z+{J*|_zQmUWYqIcv0wkLX~&B>fF^QdVv=ju7rW}P@~=C7yenJ3OTa@y?gzRgj# z{c)<}|5K#3{HVA0;L#(ab{#!!c4pcfy`QW7ebLS7e9Zma_`ecejqi)!)z1?~&@7SszgcdMoIILGK3L0Phd}F~DQNKOXcMpw9#j!G9s} zMc{Ym@6Puc@Gl0w8+aMiTMqi8psxjf7W~hFUIKkR@EgEy0dE5S5_q%ErhnQF1lk5= zs`A8qearw70t(6u$dK;1#-a+GzlMZBboPs$w+R)!09^FBHUXR?cJ=Czp?NO;MZq&pSlxfWPdJ`oEPH&2nE?o4v8T`#;44l6eIi>o30^RppDbt#< zG0-+doU;dkwn3SJ340J|8zSa>nl|FJ6#{L8GCFM!YL#4#I`>7oN!Ul;hh@_xSCpIrW6&evRTa0>jGU-b3uvOaGgCyv>m z%=V$L46*sPj(K9|--!-nzMT@JYa5i=DGglq z`4?HAceYr0UUtrqPSYr}a|r$tFxPkfc-+_H31ZQ+K6ht)e|H}Ag3r5@h_wyM?3My9 z`n-FAIA((~LqnhU$PsHBl-V;u?EHI%J`b~4xn9G_DEDJng8Z6%W>^lmOzi3pPy71t zoX@|E180CkpZ5ZNucEK-o%MO26mZGseJxh{bKeB%F&a1fW`McA(-Q^KwGGN7ioj)` zN3ibl4IKp9+LSSAdmz`_gv8p0NY4^We#z%#oLJkSOtS3ruhKq`B43~>no((c5NI2e z8O8HC9-Xp6Ae7V{=@gWi8V7&Q*N;f}`Vkr65IE=akud*}3DUI<${dvg&ii~c`2tPR z939$&K--|qF_bR{*^T zT=Mxh1)q;+cJ*e^L7=TonHh0=AnTiv^?4?<^Uuta?l_b3{j=i031V%7GP4Rk&xZQ5 zS&y-QjwZh_)Sr_eoovd?C8M0r+>D=pqQ%Pda$?rkPohGSe^Ltc0x{W?IXUm^r=)%T z6rSJtPmTHdsR^Iwfj*BCWj*t<74KM)AOJgeEuEq8CI@bpEID|89B;# z_0NF((8`tl+iTpX>Jh8SR(#t+y zSpo+A>V&Ufo$~oV!M`Zx>x(#_hLyQ4OS*8*_b-P0#c|)i82x2GKc|61VmIIQ317b+ z^}Meyu~>P2mQbNU)3{j@+5@?tOJF@WFjJZ`H&R}pDViJUpu(XQDqIAHdVk1}?&|+B z^!cWgpZ_QA^UZPJe{&x6qOaeQ@bz0lpKpy3Q&8sCvd_1%-|4rpuB}a(+f(Eh4uSK) zMW6480c&C!RwfVrrB<%o-=&bhG~wqj4T-f4$}G+Kd}oT-&39+$>vzS0bHI7v0&t1g z)xWFk>vu!`e`S3CvV`wnmiGA`sJGn8mHl~n-1jdp5y!}9mP7su8kgr|MT-2I{VUSM zE`LQ9xajjr&{yU`FA!@Rlv!E!`CiU<`n{YlTmnDjuZsElsyJ|(m~6_d%J}+f$Y0HV zZEeb|&e;RGUaJc}ud!I^*EI>!HI17!DPlMOnzFAK(!O5E02he04ayWs#ID|bG#+S* z<~}+IC@6DZLiPOwy6<=NKEDseE*X7`2kH#L74}*Ud#?F^VbaNjvvhW z{s(iu{*d(nUoRGjwGGNV1^QDV=`R22EU~shnWu}s{tO8L z1!bOrde4Na??>*(GbLheL*y^}{49+Jnxc7@4l10mg4Fw48aMDCSB9GS)U3T-L-Clqn~G)4)8xw!@L1 z>pA`q_#^Vk{rM)H-0vpEZT-si74 zKgRyA6Tbd65O|F8`an$H~}_fVU*pHmGFmC!p7Y-T>ST{x;AD1Mdku9Qaqj z2N3i5BxAjxPX_%^&<_KBI_SrP9s-{Q{&PT|5Bi0mUkrR1@Rg8%EpQI}_kjK&u-^~K z*wc{z67cJgzX9|QK>yO`{{4J^|AC-y2fPpX6TkuZM+1)m9t%7X_&{RUKmAVzeID>{ zfzO5f^MSMA=liSeuuAq{1pXUASk8AH=&u032L2N8 zdf+#K>4hF>I~>hVFVqVE(+U;-6qx%-*84T-!r%B@wS}KwwH5G>!O#1dw! z54;1hwjuJzLEjbhy@0vDwH=P~_XRxx4EjiW z5ApX0y&CGl`*1)V`1$=P^%^0c_e0T#fZh%D_lGl?<-%g{uyu;F!ztP!zx+b0XpnA)o}l-hk~EKm)!cRp&zPYzo{Mx`TTt) z`TLWuZHU$f@6+lO=*JUF{yCs803G(1YQDdce--5a5g6W&)i*=^Tfl!i=>H8|06%;` zRlh)b+=l3SyiP3Zh5e@bEzma-Ya62cGU%H?=l7x1{|xlaz|em+yuZ2pnt${CHPD|m zKL>qVU@8=7JFJp5wWLdZ=-(RdSJCGT>_<|2oifz&C=Q_e*VuqwDc!@Gk@Z zYS8)lkn2?h{YA*<=Rw=yXg=6)Yj}SZ{X@zZhW)nYpQOwD{5&|Wh5oPY=lg40fCmz5 z8&tBE`&qaP^qqkB1m2ri*2C{(VR#?cPJw*xPx1c->hb$kbm+%g?munQqVs|MxAsDq zkNZRX@b^aTZQ#Efcsa4GXBFscKraG64-EZN`;A|(4)(J;*w5qddU7nr}dv>lGt$NQD=LExVZd^EAU-gW%_CHc?~b7pLH*TAHE0b%85`3Haw z{aDZaD1O+V>Zd|J>{s>2gFXwG`%mhhL%J~ZTRrq!J-i?5vygu!@FHOT_ZDr3qw9Ys z>B79f$$D0iF8nC)6OjKm&|d{!54;ib{{i|Zz@LI2z7OkRzijxipWpBkKfmFpz_7nI z)PUXq+yu=1s_n2!HtbKjyM7I0fMI`YIFxj4LzI6M@HAl94;!X~ek|~D#Il|c^eiy% zU)l~w>$w*695DQQUPGRAnGgD_VHxP$Z`uw=^Fe<#JV}1hpCXp}uwOOsekJ&4E(jvjav}A`5U(c-U_${^4oz214F+x!uz`s{yn4--q(%$!Tj8h zvR>{-;bXwh{iN-%N;b|0eIBvs@V;#fK|hmN<~tko`JgWV9rnjYejiJ{>%q_OPi=>z z_5T_4rNolY`=#&-&{sl!0rba!`F*SHa5O*kYh#K0qQ4IO7O|`c_Rq$T!O#1t)cXqZ zVgGE}#@Czr0rP(9=5P8L>DmUBZ2CF)t3a;?y$zWAU+Q;5{%+tO4jh1gG%)Ya+73tS zJrMLM!2CRj|8UTc0OsdK{QSKt=Q9`l@b`4nnV_Esd=atKyAJqf@WX!FQ~>=!;75q1 z{#wwV27Mjy3&1Y{zecQWh_3(Zpu_h<(+1FCzi#@FbZtXakN;j4hW>Bb1b*1ho4J2o zelvd$xa-l}=;t?YPb@lruS)(X(7FG_KMv|aKQ%E8;eNKj{cOpRU)Fmg4D>^W8d`bn(OU+sgeQ`Nx9)IH*4Zcos1CkG8|n`J6(! zFg)+A3qZe$Sk`kJ@EzcP2y}SfTOR@aQQ)Vb-t(Zp3i_MC?*eZGE)&c7!26>0W6-|< z{?e~Ea2sDAxE<(2fDZ=$A)u#0KM8mq@L9m;5^Eb&av*;%xbq!&0qBnWfg1^LH=&d;;9!z!s~gCE}KIt2Y3Vr@f|&+iAhK39Mro_Bo>hVMfS&%fRT`JWQI`P=#d zZwovSSOf1wOv5VKHWYXdV0hoO4F}y2%li25eQk%M`lG=Q{n|Da^rMNTUIz5vf*yj- z`;WH6(fsFw&VR2<{Yya40$&OY`&HZRq)R>CpM;@5+g3t7?oVxpqxBX@mwevOgn2&` z|8wLQegpU|;J1mT-akO+zi+f1j@ASH+6MjF_8HXU_m$M&?AISu1bW1@YjLA3G`-Q{vMV2VLxc+`=M=`O1AG$`NHFY z4*xl37vSBY-X5Uy`%l|pmF!4@ ze-to353+vf_l_yx|1~h|Umepy=YE&^r-Bas+X3&l4(>l~)1vc%{i=ii{uUkjsbd+; z$L}{;4}Y&q{#x+A0u1k~4(Nx@t;p}{cMkCLJ9h(y{i}07(0ifYWZ=WV57)o*IM8Q9 zKJQQ34y$A*-yc~&>_?q^zeHaQ^>e^Wh{b;cFx;Qcm5~1ka1nSN)LRb>-@l!I2mKwW zw-NY5;Ljm{v#)n;4ZN-I?`j2x?~N{g{zJVYIl*DFr-YgCR7e}@9}bnq0;M88McLHlS7(bnC`eftur zwq|`p^0v-y{R=(T2pJL@%Wx8gw?Zo?4YV>E!nuYf3+cv+^Eh#SN|b$BoLA6TI53k*NO9JoHaTw>YNpng*2Vcp?sL`VRH}A*$QnfC8&!!X&0q% z{%`=nmmf)}@&Ot{i7b^y9tY%n^jUTqe@?lG?9HxXu zF-0G$q#7+6rUapcckgRdIV{GAVK4$TahMVstkBxGYFh|$xJf!aIE_N!L3Ok1W;M^6 zwP0uCvK=GQ^)oeisYf=dfE;ty5jdQG}qsY$ogh*2|LWo2fx zz{*dECb5jg3QU*anYU14YSz#5H7g6&g_`GSJVpi4-?O^-HBKjWrn74i^uL+6yy-l^ zoyxn>8P%!$|1w=8ottMI0Yjf5sjXKXjr0z=imc2{V5mv6E5^` zyU_1)p}WcBhX0(vnPAh;cUGTyE;-+b6?ecRTMlb%Gc!S?d>OKoR~quwN6uqCPWl;d z(obWGM=SGs7;Dm{cHJHxPq(vz^2bW**l;#;Fg%|QTIgILK%?O2%W%cMo*$BUyflr* z6FFe7z(q=`U`+T*;J|{E#35K}1$L<=ao|2FsRA2qNfo$LN~*wSUQz`fUnNywhf-1n z9vLN7;GtJi1s+Q!Rbb~=QU#6~lvJU))C%)UtUPb4;rh0^yuH;elz)hjrZ!f{FF;AlaBVNVFJ`NYo0VI>AK%DRjE6Id;((QLUA%bFCR8jI zvk4{BOre;TlZi~BWSU(ltmq`6K04^4ZYQB+t$a33siScTgfd1WYu_f6$t>Hi)oW8QJlTw~?`TvI*kuw|HV)0I^BOIxeGRyDXhulG zka22`>ipHwGpiU7!erR%S;mX0B6Q*ng80|)Aep!~2;yH72r|w(@dlY)3!Assv>ma4KlSD zkWAbgWTpiK8E2iyAcKLiRE@_MMHbZS^YzuOt;z26!h!Hc8erAs4lOu6I||YD1yoNu z%|}{It@uk)H>Ej>4Fza4k}879_H*xkkPY!QKW#7zsOQ)Ov#C+pMC@$pJlGg(5Wyyt zY`=K!x6W+Fs%)ZmHgi1K7^@V)raamH{s(V6vl*wdS!8F^&c;$d;Cg|K`HW&TJ;D zY#c0Yo(CJ*(lYVP$+OOErl@QjEbVd+HnOE<;>X{9&za3sm5qa?MLpQamX?WseCBy) zHq)5R5^qb>!DdMjmKKSA^SL(-Htf)FfZ_W~yu) zENzho8`;t#(T`4i!->sEyq?CqEC1YFtvoj`%T~BPD~UGW@e^mzSp`s7lnOdi0hO%? zuRgYHbOxPW0EPXip!Eu!N3^os=(WbwY!t8d-S!* zuC9UbAw{l<*%6RyHztFvvHDrx*LRQey7gN(b^aTKX$cqeZDvksWEPVdXV}F2@Xv13?Zz=i4AoAMAmHS7z^XXXnhT5^Y0x=GvYf80s=B zt~Mnbq-&wH9>r8SB5q=VnTa(T^L?x!)+ZBfo!uQe)(VQCW!2E^dI-d}-w8oGAfT~E z5GH^DGvm601{|AW1tc>Z;b34i78w#ae4h$l;{a~>KNs+9?E5Ep4$t6G85}-P1t04G zZumhLaARr^5a5esaQH&SA(V}C0B3(_^jL+gmchUXTFhar>$>;#!W4R~T^1OR_FM|I~#XGzAB-?W1e}f{-B>1Jc=;%G@^frqJD9c-8 z-WQqPheO=uP~1qm0`k+QWN$i^fO}CKvo;Nmc@u!Sr774HI~HR_Bm5~|mYD4w!W)&G z!Na8b3BxgJl~p6K+yqNc2?xPYIqhq>EG$+lu`dx2n|jj8f$%OXMqmWS3uB}q6vrA( z&&z>o)1`5cx!`Dxoaxexoaxex++d)JuH+cq=H9gE@h>S%Cjff0(1E?rWtYz$($eQl zC`e-DOi7HKDT$F|hj~?h2)dhX6(JNtM{GfxQ~8BItBg%`8Jp_1&U6>Fwa{9tYz(?* z8>}OZj$?ht(_}d1MU81#HA@Tun zwGnM+XV?q7i$IH=bepiCLJ1y09e9dzIAsalDz*-P6|H)aUn#>fuuD3bUdWW?{6^EH zM40jldsmYZy+1sO?w8~;OxxHn@({LVKP27bdWT`^8vdTtZpOgE`(;gAyCv1rkxJ~< z*L8L!_v;OPOP4g3ZQT?{zB|#~+L`F$Twm^dedn%SJ>4yRU5UN0U_(&zB4S=dZ{iV! z!}!&5zX7lf@^}tTMCg&l;Nz4QMj|@1G(aDVkfb2vtx^EF)^IJ7LE&?4?lM3}(Y&M5 zoi%^Z=oo0nBpP!#4BBCd#sIwM!q~N5ZP~S672uaBh2!UVMKlU>@URb{Q^$zw8k`Bw z@i2Y-*ayGbxNA#nr=T|p`aE&|vY_-!?WxCLBWl*}z@1aU@wlFV^c7M1PH~=t((U4S zH^!S`&Fh9d%6qX!>H0z5E(=7~qy~+%2BPBlb7eW8n+x1*uyvsmo9Cm@F3$F{{|@0?vQ+ zfr}q*-d+9pye=7Zp4PAFYfW|u8TwDW5Y9gOhPDcLbfor`vd7-g za-NJS{^4uD*MP49Ujx1dd=2;-@HOCTz}JAU0bc{Y2LA6g;I;k_oO%7sP|MWn!TYfO zZ~pK}UjOq4th_Ig*Z*6P_+zjek$9i=ok;wF+hHVL+aE#Vbw98FIrjT762}9cK;rno z86-I#FdO-8yOa72En8dktCRR&Bk8@^<*4_x>uHd;rILyLy{QAaDCKCu3sqcyr$Y#i z18}^;h;|n)BZbQ-jYL5fgo6^?fbBi0J^MM1zhBh%V+qiSfA|{kHQ;N&*MP49Ujx1d zd=2;-@HOCTz}LVftpQ%g^U{~sxOgqkyZd;1qgWmDJAGd3^NuTC7W0~&*YCW?h}ZqR z#;-x*cmBN2H}^&HTA$+q{GBm>SIhq&mcN_iPs{mJYF=i~K+=(BBJurM_~rF~J<=Sc zxkwF2jYxd|6D0oikIz>F*JFDl@7UC_Wu3nfMwj({vXQGqhOzVsv z>zVt}q-+QG6h24TCFIy+l8gSue}K*NXBmpExIVXYE<{_!W>5YOf!ofzwcCYEOeuW0 t;fC7){yc_w{1nTdzpEC52R|XY8r=9pk-gY@$~{n;JWKzL_SZ@L{{?{WA}{~| literal 0 HcmV?d00001 diff --git a/pandas/io/tests/data/blank.xlsx b/pandas/io/tests/data/blank.xlsx new file mode 100755 index 0000000000000000000000000000000000000000..73f6ba6d29af3c8764f2aa9bb3291a43d0650074 GIT binary patch literal 8379 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 literal 0 HcmV?d00001 diff --git a/pandas/io/tests/data/blank_with_header.xlsx b/pandas/io/tests/data/blank_with_header.xlsx new file mode 100755 index 0000000000000000000000000000000000000000..7b30edb13be2c90d7235fa7995455d39ab3004e1 GIT binary patch literal 8773 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 literal 0 HcmV?d00001 diff --git a/pandas/io/tests/data/legacy_msgpack/0.16.2/0.16.2_AMD64_windows_2.7.10.msgpack b/pandas/io/tests/data/legacy_msgpack/0.16.2/0.16.2_AMD64_windows_2.7.10.msgpack new file mode 100644 index 0000000000000000000000000000000000000000..1e128f42a37a6b4a44277a116fb48935c9a6b6c6 GIT binary patch literal 4684 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 uCs3>x*hJqE`*Q|eJ>7SvwG?V&`^ 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 J*wAba{RaVV-4p-- literal 0 HcmV?d00001 diff --git a/pandas/io/tests/data/legacy_pickle/0.16.2/0.16.2_x86_64_darwin_2.7.10.pickle b/pandas/io/tests/data/legacy_pickle/0.16.2/0.16.2_x86_64_darwin_2.7.10.pickle new file mode 100644 index 0000000000000000000000000000000000000000..60101c2f1e95ee0b33780f298f4d82235939586f GIT binary patch literal 14893 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 literal 0 HcmV?d00001 diff --git a/pandas/io/tests/data/legacy_pickle/0.16.2/0.16.2_x86_64_linux_2.7.10.pickle b/pandas/io/tests/data/legacy_pickle/0.16.2/0.16.2_x86_64_linux_2.7.10.pickle new file mode 100644 index 0000000000000000000000000000000000000000..60101c2f1e95ee0b33780f298f4d82235939586f GIT binary patch literal 14893 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 literal 0 HcmV?d00001 diff --git a/pandas/io/tests/data/legacy_pickle/0.16.2/0.16.2_x86_64_linux_3.4.3.pickle b/pandas/io/tests/data/legacy_pickle/0.16.2/0.16.2_x86_64_linux_3.4.3.pickle new file mode 100644 index 0000000000000000000000000000000000000000..6d5451f96e20d6e8aea11a1777edb024a7a561a5 GIT binary patch literal 14116 zcmeHNdyE}b8NcuDqua-_D^-;63SFVBZ7H-umECS>sn;&WQvO?S=I)*CxzqdD-no}P zXsIN2amfJ*9f=|S(I6pF`Gbf`LNtUJpBPOvicgGxXne%*5?lz0{=V~=nLGC}_inc< zsI%GmX6~GG=A7^Qea|zWN__6UTO;B)>5TALG4Gsoc%ot+-0bkRvqmXr*rU_siaDAu z<;id}Vh z$~LFVrJQ5(RKdK{EQqHpg|U+UVG`8SVFNsoGpdHehfB5M>@hi+BE8e7RE%Q|Uzw@U zcy_f?o31)%9K4bmI(!8tFPfZj(vj27L^SK%>wLl)Nk`L((_XV=u6k_Nq>iy$x1nV^ zDqF>Q^n^1xIr*`F;Si_vO;sm5PfLksjfz9(<2cWh%Qzpd9d%4Rug&2dSj`| zHq6$si)aGu1N!wb+*~OKDwj-jt{y3Sory0-R`X>YU*i`;*09lGU{|Gl+$>G*9QQ5I z8@~tRU(RFsP5$Mu_4SL1&|)TfB9Uk`7K_In++wC<^)scBc2ldU{G(Q;Sfb5)?Agpr zg@gpiBxed`1H!#PP1c?@Dz-T)pYzrG#qCZAa+m0F#`)k$=OJ_);TL3b=8OS>W@hq* zLgr4RP&1v~rxqkC`HGBP%R)jBv>a2tlMlH44gs5(LAFqyJ_PV)MC)Ecje31Dqaftx zWWH22D3t{f+ui4iDLVvLSEJh}t_6ZqfhiINYgH&$)4 zk~eLwMT0_%zz(yTFPa+l>%RgXiH5;GO^u*2UI7_mGvW1CehqJKxt&X-Kv z-U+Sn@wc~Bt`v)$maU9LM~~>zoa;OxS9TJlQ7limv2&6W0LkLx<=6>k_EFTn=OgVA|?Zq6p5r-PFc62MI}_LHq$0}V%mV2|L9y!ve)~^B)vq@%j)FU zd^sc`;w|-T&;35tqRlc=av2+GFz*Ooh973DVlsL%=t- z?{K)=4wY^@*lq_C4lK2Cbkmm6O~NImgewto3EAJC;=xJ=9s)+TCtJ%S^ne-TNxP7r zrnrGZ1{pN)l<;1*!yd1pqqR92iCEX+ga$F$#M*{i_PxO4SUT>1{JX&8csk*K{94WA z3F9cjDweMyqRQ5?HlnWCjC3+$2{CdB+WSbWGO8Z)mD2X@7cR-?D%cbslua|_4D@hp zi1%izw(89c3gF0@Ic%Ec_~8D0>0rTZ;X&Ckb{9CoPENAB**)6lv(xizE*)j}vim$w z!|re6WL5)5h-m7aOoK(no0_?pqf6~#B9Tki{^kBR;c{jlJ^5Rr&t5xt^;@8;zVrAo zqEmO=`2Dv$S7bl~8VqW$ROwqhb*8Ium6q+-jY&G9=v6_Bw7SvSYtuvp;( zE#!U80$9XN2dq74h)W6Oh8)I zJRnoLlJ6jT0psO?cZq}KO$RwwI)w8AO^Q3|mg$nPL5J|wpuOTQ5+P4UN53QjWpp{9 z?pG;F$P+=@f0t&YtjEB~wxY3~KnnqR$%_9R=evXa*D+BI`A6xRAa6Z_D>sa-WotZ% zTnu#ruz;s#;U>yCfR_&kk{0!Z_wN%;{FuI*NB24{kd0VQv2R~OAvLLJO3@XH_9)t` zXrH3}imp_2Kv5TvqTFEC8@W?FUY}IKfgv$fSrnXD)J>NLGd0^pMWSF-^LMIzN;Mo-9Cx(9b!l1{CIFe+@F9g*-u_*OMu|OV*yNk9b?o@y*U28yv zshB@%<}$e&sseRIDwXf|B8#psG_Vbb} zQ%1N8l-X*qQWQ-m=S2SE4k!n16(ua3q5&H{zZj?0+=6q}_w9yy8xo$Mz^wju_RR-} z5b@lw`GMaPo&WY_qr;%Ty#47DMA!c*{rs?qgc@fR6RVSzums9zn^0~5LFtjmwUTU+ zyFDw2n25pM)}Ytdnk?P3z?UHL|XpER}mnG*a3dfi&x8 z2+G<;r`>eAg-&~LdeI`US**Xk20h-`BA`J}G`6VE|E;f53#CE#(Y4SZ z7F~qyc!mT1%%?Z3hoaQJN!Cv;ae%Ed*=oOY#82%uF4$GElOt>A;sp% zT7DUdz+R{7lC7}g`a;oG_u7c+=fQh2rlI0#&WUj0)alrBKH+@D6%Oy4HmVtH+)tMa zi%~T<4Ds)YgqT1qN3nB_=Avc~u|w~7@(Wd7BtF@|G|hwMN`BfXV0(DNcjwz4?#YNx zHOw4#hf|qpW15Nm{6s02FJiCOMk$7VFXyP>-}FlccOGbXmuzczVQ=){sE+|}$eZP3bF zIvT@z1?v^r7de;LaWikdfiry10*I8i^(HPGUqTiSvW~|hBG|I1INV;wo{dDfSSRH! zf}yTA0zI_~4Tgf*FIE%?hTOe9ncLn-EmSac30(`Xi{cdY&Mb&cgF(owzA7c3@#H?y zM(JM1*{^HK@Of0#ERH+YalF{o80%XQmi0B9TE@MUoVVEn4?5P!m_%VufO=7meBP$k zL~m?m{c`RjG;P&iV@wBg zI`Zx|vKH*Ho&rBzMG1Ejb-w=@5{!zkpKyg_9U+ExFDK6uE@OBd8uxV=RWt$zF}eoM z%guok6m(Fqdi#3uQM!EZ=$ND%72TxhW<{@6bc>?bDSEx4TNT}==!X@(LD3r(-LB|I zmNh$g)d#|#xge~$Uto|E-vxuo2mNuM+DhiB{S9AuV8=MHv+Uc?!aiP!ueZv(fyJ_RMmaZwxsb!`0 z>&Fi+N*V#xHtMI6o!rN0++J%cQtE(0O^4fGvS>#GEq)fEoJ#sRb(@bi%c-^d`_-A9v}7b_>jkA)WgFVTwmqhin6n+a(jzo zTU!*mb-oRgCl0Vl9BwM+cdu+)vr&AB9l{22z=(?j%Mgb<+EUcP@sWN^gvY*5YXX_# z;`OO+!{C37mE8gM86RLD@&L=@s4zI8p!KlX^b1)Zs1%0W%31?Np~y`#ew1{UA;s^+ zh;+4!REo!WXJDwBn1hm9Cf8HZurNeNRTJ6MQTqYi{+iwFoFZmv}T19M?)VRCscbYWs_WdKc5yLH4c46A)p+z9-W8X#q=G}(WW zNF>F}doB!s0w~x&&+qf~e7}&x?fqasFGPb#!0!h(4hOtAb&7m@sC0DmfAa+4lp^)K zfAErX(&iCgC#aB=2ENaD_8 zlAWg?Z0?DBUYC{LeG&8S&n6F9De=tzByr!LFbZFP zmAHELCHXyI2wg%&^ai{=izo|X515HVsN{K^B_#}tXj6+g(tK9htwRyLm#%dPo??u- zi8l2myBVD7Ni9yVI*WPmxyz@l2#z7Do%|c8eq03Sh|k1gIpfpEA5VELulWK102wEc A!2kdN literal 0 HcmV?d00001 diff --git a/pandas/io/tests/data/stata14_118.dta b/pandas/io/tests/data/stata14_118.dta new file mode 100644 index 0000000000000000000000000000000000000000..1fc65f1a6e9882d888b3400af0129aa4b40bd51a GIT binary patch literal 5556 zcmeHL&r4K69G}$G!h=zPP{g}Px8ANHY7C=knUz$eLbqjh9rfYcH_LldVHZXH13HIN z8ANmoEDXG@(T`g}(5;9Hx=DwkAFzGr*Y0W_bP<-}$`x&U|KYB&eW? zVL=HVV|18>1c%ILG-4zkZ^y2!;N*m0Jd_Ik1HITSRPlLIhp>B|;0t6o(h0j42=-}` z`Q!*19P=Uv{;A_+=K?RqhnX`BRvo2)U9E?OmuBEiIz#rgv^ys=q0t5*6RqG! zL5f}LXqsk-F^HB;p>3BgjF`O2xOCLyFKe~@`d*#W{W_mDdDj75e`fLr2X%eXh*)FSA1>Syjp?pN-64!i5bQazwBJOWq*qmk~iEYBWKc&wZb4Cxt= z(2gVqMCk7<5N87sp;#=wvsR0&_4=Gj7m8l(Y_S_c8SIx2fqpK7AXYvERD|k?#1RjL z??nQZlBY9rJ?X2_Id=0RJi@~?d^FPBQDW?rqv5gGXekq`xuevE@wU=hmTVEb_QSvu z>tAIFwU;FHmn~)Nl{OUwwiN-YX5_YZ`JZ(r*V^@=S>R6!o{03ZkU1275l=HmJ5vVvuEwteylyiM)UTpUsF}uj`jQX?~VOI zYXMBVJHEr;-kJQrvP zVGXPRxMcw4orJ~@RREMhYBsk`Zz4XN%PIh((s$van;%1Lu-r9hO0W=)m|iL(*!|~? zybL2fRKOSO=A&HDYNYpj`JC!Bd;eRJs78w4pwB>t&?JKgqz{vqd>Sxx z8AudD)$q4Lx&#IUALQc`929Dl#-AJ*>e6M@*oE$Vk?cl4^Ii1ce@M`fN^d){tGvc) znIdNfE=pULrA*gDMGYl;7a5s$7oq6}kPY3q8jNS3WWwySm0Mp`+rf~hqwJEE8OPAH zq)Dg!?81$eM=Q7C(otJ4KKlW{e$pq$LD5ieR(!u?cdeV#O^OfNI;g8;>sH=qc6(cY zaqf-Mvn-(N&e*yCg Br&0g_ literal 0 HcmV?d00001 diff --git a/pandas/io/tests/generate_legacy_pickles.py b/pandas/io/tests/generate_legacy_pickles.py deleted file mode 100644 index e1cf541fe6195..0000000000000 --- a/pandas/io/tests/generate_legacy_pickles.py +++ /dev/null @@ -1,169 +0,0 @@ -""" self-contained to write legacy pickle files """ -from __future__ import print_function - - -def _create_sp_series(): - - import numpy as np - from pandas import SparseSeries - - nan = np.nan - - # nan-based - arr = np.arange(15, dtype=np.float64) - arr[7:12] = nan - arr[-1:] = nan - - bseries = SparseSeries(arr, kind='block') - bseries.name = 'bseries' - return bseries - -def _create_sp_tsseries(): - - import numpy as np - from pandas import bdate_range, SparseTimeSeries - - nan = np.nan - - # nan-based - arr = np.arange(15, dtype=np.float64) - arr[7:12] = nan - arr[-1:] = nan - - date_index = bdate_range('1/1/2011', periods=len(arr)) - bseries = SparseTimeSeries(arr, index=date_index, kind='block') - bseries.name = 'btsseries' - return bseries - -def _create_sp_frame(): - import numpy as np - from pandas import bdate_range, SparseDataFrame - - nan = np.nan - - data = {'A': [nan, nan, nan, 0, 1, 2, 3, 4, 5, 6], - 'B': [0, 1, 2, nan, nan, nan, 3, 4, 5, 6], - 'C': np.arange(10).astype(np.int64), - 'D': [0, 1, 2, 3, 4, 5, nan, nan, nan, nan]} - - dates = bdate_range('1/1/2011', periods=10) - return SparseDataFrame(data, index=dates) - -def create_data(): - """ create the pickle data """ - - from distutils.version import LooseVersion - import numpy as np - import pandas - from pandas import (Series,TimeSeries,DataFrame,Panel, - SparseSeries,SparseTimeSeries,SparseDataFrame,SparsePanel, - Index,MultiIndex,PeriodIndex, - date_range,period_range,bdate_range,Timestamp,Categorical) - nan = np.nan - - data = { - 'A': [0., 1., 2., 3., np.nan], - 'B': [0, 1, 0, 1, 0], - 'C': ['foo1', 'foo2', 'foo3', 'foo4', 'foo5'], - 'D': date_range('1/1/2009', periods=5), - 'E' : [0., 1, Timestamp('20100101'),'foo',2.], - } - - index = dict(int = Index(np.arange(10)), - date = date_range('20130101',periods=10), - period = period_range('2013-01-01', freq='M', periods=10)) - - mi = dict(reg2 = MultiIndex.from_tuples(tuple(zip(*[['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'], - ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']])), - names=['first', 'second'])) - series = dict(float = Series(data['A']), - int = Series(data['B']), - mixed = Series(data['E']), - ts = TimeSeries(np.arange(10).astype(np.int64),index=date_range('20130101',periods=10)), - mi = Series(np.arange(5).astype(np.float64),index=MultiIndex.from_tuples(tuple(zip(*[[1,1,2,2,2], - [3,4,3,4,5]])), - names=['one','two'])), - dup=Series(np.arange(5).astype(np.float64), index=['A', 'B', 'C', 'D', 'A']), - cat=Series(Categorical(['foo', 'bar', 'baz']))) - - frame = dict(float = DataFrame(dict(A = series['float'], B = series['float'] + 1)), - int = DataFrame(dict(A = series['int'] , B = series['int'] + 1)), - mixed = DataFrame(dict([ (k,data[k]) for k in ['A','B','C','D']])), - mi = DataFrame(dict(A = np.arange(5).astype(np.float64), B = np.arange(5).astype(np.int64)), - index=MultiIndex.from_tuples(tuple(zip(*[['bar','bar','baz','baz','baz'], - ['one','two','one','two','three']])), - names=['first','second'])), - dup=DataFrame(np.arange(15).reshape(5, 3).astype(np.float64), - columns=['A', 'B', 'A']), - cat_onecol=DataFrame(dict(A=Categorical(['foo', 'bar']))), - cat_and_float=DataFrame(dict(A=Categorical(['foo', 'bar', 'baz']), - B=np.arange(3).astype(np.int64))), - ) - panel = dict(float = Panel(dict(ItemA = frame['float'], ItemB = frame['float']+1)), - dup = Panel(np.arange(30).reshape(3, 5, 2).astype(np.float64), - items=['A', 'B', 'A'])) - - if LooseVersion(pandas.__version__) >= '0.14.1': - # Pre-0.14.1 versions generated non-unpicklable mixed-type frames and - # panels if their columns/items were non-unique. - mixed_dup_df = DataFrame(data) - mixed_dup_df.columns = list("ABCDA") - - mixed_dup_panel = Panel(dict(ItemA=frame['float'], ItemB=frame['int'])) - mixed_dup_panel.items = ['ItemA', 'ItemA'] - - frame['mixed_dup'] = mixed_dup_df - panel['mixed_dup'] = mixed_dup_panel - - return dict( series = series, - frame = frame, - panel = panel, - index = index, - mi = mi, - sp_series = dict(float = _create_sp_series(), - ts = _create_sp_tsseries()), - sp_frame = dict(float = _create_sp_frame()) - ) - -def write_legacy_pickles(): - - # force our cwd to be the first searched - import sys - sys.path.insert(0,'.') - - import os, os.path - import numpy as np - import pandas - import pandas.util.testing as tm - import platform as pl - - # make sure we are < 0.13 compat (in py3) - try: - from pandas.compat import zip, cPickle as pickle - except: - import pickle - - sys_version = version = pandas.__version__ - if len(sys.argv) < 2: - exit("{0} ".format(sys.argv[0])) - - version = str(sys.argv[1]) - output_dir = str(sys.argv[2]) - - print("This script generates a pickle file for the current arch, system, and python version") - print(" system version: {0}".format(sys_version)) - print(" output version: {0}".format(version)) - print(" output dir : {0}".format(output_dir)) - - # construct a reasonable platform name - f = '_'.join([ str(version), str(pl.machine()), str(pl.system().lower()), str(pl.python_version()) ]) - pth = '{0}.pickle'.format(f) - - fh = open(os.path.join(output_dir,pth),'wb') - pickle.dump(create_data(),fh,pickle.HIGHEST_PROTOCOL) - fh.close() - - print("created pickle file: %s" % pth) - -if __name__ == '__main__': - write_legacy_pickles() diff --git a/pandas/io/tests/generate_legacy_storage_files.py b/pandas/io/tests/generate_legacy_storage_files.py new file mode 100644 index 0000000000000..686efde8402d1 --- /dev/null +++ b/pandas/io/tests/generate_legacy_storage_files.py @@ -0,0 +1,206 @@ +""" self-contained to write legacy storage (pickle/msgpack) files """ +from __future__ import print_function +from distutils.version import LooseVersion +from pandas import (Series, TimeSeries, DataFrame, Panel, + SparseSeries, SparseTimeSeries, SparseDataFrame, SparsePanel, + Index, MultiIndex, PeriodIndex, bdate_range, to_msgpack, + date_range, period_range, bdate_range, Timestamp, Categorical) +import os +import sys +import numpy as np +import pandas +import pandas.util.testing as tm +import platform as pl + + +def _create_sp_series(): + nan = np.nan + + # nan-based + arr = np.arange(15, dtype=np.float64) + arr[7:12] = nan + arr[-1:] = nan + + bseries = SparseSeries(arr, kind='block') + bseries.name = 'bseries' + return bseries + + +def _create_sp_tsseries(): + nan = np.nan + + # nan-based + arr = np.arange(15, dtype=np.float64) + arr[7:12] = nan + arr[-1:] = nan + + date_index = bdate_range('1/1/2011', periods=len(arr)) + bseries = SparseTimeSeries(arr, index=date_index, kind='block') + bseries.name = 'btsseries' + return bseries + + +def _create_sp_frame(): + nan = np.nan + + data = {'A': [nan, nan, nan, 0, 1, 2, 3, 4, 5, 6], + 'B': [0, 1, 2, nan, nan, nan, 3, 4, 5, 6], + 'C': np.arange(10).astype(np.int64), + 'D': [0, 1, 2, 3, 4, 5, nan, nan, nan, nan]} + + dates = bdate_range('1/1/2011', periods=10) + return SparseDataFrame(data, index=dates) + + +def create_data(): + """ create the pickle/msgpack data """ + + data = { + 'A': [0., 1., 2., 3., np.nan], + 'B': [0, 1, 0, 1, 0], + 'C': ['foo1', 'foo2', 'foo3', 'foo4', 'foo5'], + 'D': date_range('1/1/2009', periods=5), + 'E': [0., 1, Timestamp('20100101'), 'foo', 2.] + } + + index = dict(int=Index(np.arange(10)), + date=date_range('20130101', periods=10), + period=period_range('2013-01-01', freq='M', periods=10)) + + mi = dict(reg2=MultiIndex.from_tuples(tuple(zip(*[['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'], + ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']])), + names=['first', 'second'])) + series = dict(float=Series(data['A']), + int=Series(data['B']), + mixed=Series(data['E']), + ts=TimeSeries(np.arange(10).astype(np.int64), index=date_range('20130101',periods=10)), + mi=Series(np.arange(5).astype(np.float64), + index=MultiIndex.from_tuples(tuple(zip(*[[1, 1, 2, 2, 2], [3, 4, 3, 4, 5]])), + names=['one', 'two'])), + dup=Series(np.arange(5).astype(np.float64), index=['A', 'B', 'C', 'D', 'A']), + cat=Series(Categorical(['foo', 'bar', 'baz'])), + per=Series([Period('2000Q1')] * 5)) + + mixed_dup_df = DataFrame(data) + mixed_dup_df.columns = list("ABCDA") + frame = dict(float=DataFrame(dict(A=series['float'], B=series['float'] + 1)), + int=DataFrame(dict(A=series['int'], B=series['int'] + 1)), + mixed=DataFrame(dict([(k, data[k]) for k in ['A', 'B', 'C', 'D']])), + mi=DataFrame(dict(A=np.arange(5).astype(np.float64), B=np.arange(5).astype(np.int64)), + index=MultiIndex.from_tuples(tuple(zip(*[['bar', 'bar', 'baz', 'baz', 'baz'], + ['one', 'two', 'one', 'two', 'three']])), + names=['first', 'second'])), + dup=DataFrame(np.arange(15).reshape(5, 3).astype(np.float64), + columns=['A', 'B', 'A']), + cat_onecol=DataFrame(dict(A=Categorical(['foo', 'bar']))), + cat_and_float=DataFrame(dict(A=Categorical(['foo', 'bar', 'baz']), + B=np.arange(3).astype(np.int64))), + mixed_dup=mixed_dup_df) + + mixed_dup_panel = Panel(dict(ItemA=frame['float'], ItemB=frame['int'])) + mixed_dup_panel.items = ['ItemA', 'ItemA'] + panel = dict(float=Panel(dict(ItemA=frame['float'], ItemB=frame['float'] + 1)), + dup=Panel(np.arange(30).reshape(3, 5, 2).astype(np.float64), + items=['A', 'B', 'A']), + mixed_dup=mixed_dup_panel) + + return dict(series=series, + frame=frame, + panel=panel, + index=index, + mi=mi, + sp_series=dict(float=_create_sp_series(), + ts=_create_sp_tsseries()), + sp_frame=dict(float=_create_sp_frame())) + + +def create_pickle_data(): + data = create_data() + + # Pre-0.14.1 versions generated non-unpicklable mixed-type frames and + # panels if their columns/items were non-unique. + if LooseVersion(pandas.__version__) < '0.14.1': + del data['frame']['mixed_dup'] + del data['panel']['mixed_dup'] + return data + + +def create_msgpack_data(): + data = create_data() + if LooseVersion(pandas.__version__) < '0.17.0': + del data['frame']['mixed_dup'] + del data['panel']['mixed_dup'] + del data['frame']['dup'] + del data['panel']['dup'] + # Not supported + del data['sp_series'] + del data['sp_frame'] + del data['series']['cat'] + del data['frame']['cat_onecol'] + del data['frame']['cat_and_float'] + return data + + +def platform_name(): + return '_'.join([str(pandas.__version__), str(pl.machine()), str(pl.system().lower()), str(pl.python_version())]) + + +def write_legacy_pickles(output_dir): + + # make sure we are < 0.13 compat (in py3) + try: + from pandas.compat import zip, cPickle as pickle + except: + import pickle + + version = pandas.__version__ + + print("This script generates a storage file for the current arch, system, and python version") + print(" pandas version: {0}".format(version)) + print(" output dir : {0}".format(output_dir)) + print(" storage format: pickle") + + pth = '{0}.pickle'.format(platform_name()) + + fh = open(os.path.join(output_dir, pth), 'wb') + pickle.dump(create_pickle_data(), fh, pickle.HIGHEST_PROTOCOL) + fh.close() + + print("created pickle file: %s" % pth) + + +def write_legacy_msgpack(output_dir): + + version = pandas.__version__ + + print("This script generates a storage file for the current arch, system, and python version") + print(" pandas version: {0}".format(version)) + print(" output dir : {0}".format(output_dir)) + print(" storage format: msgpack") + + pth = '{0}.msgpack'.format(platform_name()) + to_msgpack(os.path.join(output_dir, pth), create_msgpack_data()) + + print("created msgpack file: %s" % pth) + + +def write_legacy_file(): + # force our cwd to be the first searched + sys.path.insert(0, '.') + + if len(sys.argv) != 3: + exit("Specify output directory and storage type: generate_legacy_storage_files.py ") + + output_dir = str(sys.argv[1]) + storage_type = str(sys.argv[2]) + + if storage_type == 'pickle': + write_legacy_pickles(output_dir=output_dir) + elif storage_type == 'msgpack': + write_legacy_msgpack(output_dir=output_dir) + else: + exit("storage_type must be one of {'pickle', 'msgpack'}") + + +if __name__ == '__main__': + write_legacy_file() diff --git a/pandas/io/tests/test_common.py b/pandas/io/tests/test_common.py index fe163cc13c5da..34e7c94b64bcb 100644 --- a/pandas/io/tests/test_common.py +++ b/pandas/io/tests/test_common.py @@ -29,12 +29,12 @@ def test_expand_user_normal_path(self): def test_get_filepath_or_buffer_with_path(self): filename = '~/sometest' - filepath_or_buffer, _ = common.get_filepath_or_buffer(filename) + filepath_or_buffer, _, _ = common.get_filepath_or_buffer(filename) self.assertNotEqual(filepath_or_buffer, filename) self.assertNotIn('~', filepath_or_buffer) self.assertEqual(os.path.expanduser(filename), filepath_or_buffer) def test_get_filepath_or_buffer_with_buffer(self): input_buffer = StringIO() - filepath_or_buffer, _ = common.get_filepath_or_buffer(input_buffer) + filepath_or_buffer, _, _ = common.get_filepath_or_buffer(input_buffer) self.assertEqual(filepath_or_buffer, input_buffer) diff --git a/pandas/io/tests/test_cparser.py b/pandas/io/tests/test_cparser.py index 93d55c654de90..ceb845073e2c3 100644 --- a/pandas/io/tests/test_cparser.py +++ b/pandas/io/tests/test_cparser.py @@ -186,6 +186,30 @@ def test_header_not_enough_lines(self): '1,2,3\n' '4,5,6') + reader = TextReader(StringIO(data), delimiter=',', header=2) + header = reader.header + expected = [['a', 'b', 'c']] + self.assertEqual(header, expected) + + recs = reader.read() + expected = {0 : [1, 4], 1 : [2, 5], 2 : [3, 6]} + assert_array_dicts_equal(expected, recs) + + # not enough rows + self.assertRaises(parser.CParserError, TextReader, StringIO(data), + delimiter=',', header=5, as_recarray=True) + + def test_header_not_enough_lines_as_recarray(self): + + if compat.is_platform_windows(): + raise nose.SkipTest("segfaults on win-64, only when all tests are run") + + data = ('skip this\n' + 'skip this\n' + 'a,b,c\n' + '1,2,3\n' + '4,5,6') + reader = TextReader(StringIO(data), delimiter=',', header=2, as_recarray=True) header = reader.header @@ -246,6 +270,21 @@ def _make_reader(**kwds): self.assertTrue((result[0] == ex_values).all()) self.assertEqual(result[1].dtype, 'S4') + def test_numpy_string_dtype_as_recarray(self): + data = """\ +a,1 +aa,2 +aaa,3 +aaaa,4 +aaaaa,5""" + + if compat.is_platform_windows(): + raise nose.SkipTest("segfaults on win-64, only when all tests are run") + + def _make_reader(**kwds): + return TextReader(StringIO(data), delimiter=',', header=None, + **kwds) + reader = _make_reader(dtype='S4', as_recarray=True) result = reader.read() self.assertEqual(result['0'].dtype, 'S4') diff --git a/pandas/io/tests/test_data.py b/pandas/io/tests/test_data.py index 63ed26ea7d931..96bac2c45340b 100644 --- a/pandas/io/tests/test_data.py +++ b/pandas/io/tests/test_data.py @@ -14,7 +14,6 @@ from pandas.util.testing import (assert_series_equal, assert_produces_warning, network, assert_frame_equal) import pandas.util.testing as tm -from numpy.testing import assert_array_equal if compat.PY3: from urllib.error import HTTPError @@ -292,13 +291,11 @@ def setUpClass(cls): # aapl has monthlies cls.aapl = web.Options('aapl', 'yahoo') - today = datetime.today() - cls.year = today.year - cls.month = today.month + 1 - if cls.month > 12: - cls.year = cls.year + 1 - cls.month = 1 - cls.expiry = datetime(cls.year, cls.month, 1) + d = (Timestamp.today() + pd.offsets.MonthBegin(1)).normalize() + cls.year = d.year + cls.month = d.month + cls.expiry = d + cls.expiry2 = d + pd.offsets.MonthBegin(1) cls.dirpath = tm.get_data_path() cls.html1 = os.path.join(cls.dirpath, 'yahoo_options1.html') cls.html2 = os.path.join(cls.dirpath, 'yahoo_options2.html') @@ -326,7 +323,7 @@ def test_get_options_data(self): def test_get_near_stock_price(self): try: options = self.aapl.get_near_stock_price(call=True, put=True, - expiry=self.expiry) + expiry=[self.expiry,self.expiry2]) except RemoteDataError as e: raise nose.SkipTest(e) self.assertTrue(len(options) > 1) @@ -497,10 +494,7 @@ def test_fred(self): end = datetime(2013, 1, 27) received = web.DataReader("GDP", "fred", start, end)['GDP'].tail(1)[0] - - # < 7/30/14 16535 was returned - #self.assertEqual(int(received), 16535) - self.assertEqual(int(received), 16502) + self.assertTrue(int(received) > 10000) self.assertRaises(Exception, web.DataReader, "NON EXISTENT SERIES", 'fred', start, end) @@ -533,7 +527,7 @@ def test_fred_part2(self): [848.3], [933.3]] result = web.get_data_fred("A09024USA144NNBR", start="1915").ix[:5] - assert_array_equal(result.values, np.array(expected)) + tm.assert_numpy_array_equal(result.values, np.array(expected)) @network def test_invalid_series(self): diff --git a/pandas/io/tests/test_excel.py b/pandas/io/tests/test_excel.py index 768aa40696cbc..26f4d65978fa0 100644 --- a/pandas/io/tests/test_excel.py +++ b/pandas/io/tests/test_excel.py @@ -1,6 +1,6 @@ # pylint: disable=E1101 -from pandas.compat import u, range, map, openpyxl_compat +from pandas.compat import u, range, map, openpyxl_compat, BytesIO, iteritems from datetime import datetime, date, time import sys import os @@ -424,27 +424,27 @@ def test_reader_converters(self): for path in (xls_path, xlsx_path): actual = read_excel(path, 'Sheet1', converters=converters) tm.assert_frame_equal(actual, expected) - + def test_reading_all_sheets(self): # Test reading all sheetnames by setting sheetname to None, # Ensure a dict is returned. # See PR #9450 - + _skip_if_no_xlrd() - + dfs = read_excel(self.multisheet,sheetname=None) expected_keys = ['Alpha','Beta','Charlie'] tm.assert_contains_all(expected_keys,dfs.keys()) def test_reading_multiple_specific_sheets(self): - # Test reading specific sheetnames by specifying a mixed list + # Test reading specific sheetnames by specifying a mixed list # of integers and strings, and confirm that duplicated sheet # references (positions/names) are removed properly. - + # Ensure a dict is returned # See PR #9450 _skip_if_no_xlrd() - + #Explicitly request duplicates. Only the set should be returned. expected_keys = [2,'Charlie','Charlie'] dfs = read_excel(self.multisheet,sheetname=expected_keys) @@ -455,28 +455,28 @@ def test_reading_multiple_specific_sheets(self): def test_creating_and_reading_multiple_sheets(self): # Test reading multiple sheets, from a runtime created excel file # with multiple sheets. - # See PR #9450 - + # See PR #9450 + _skip_if_no_xlrd() _skip_if_no_xlwt() - + def tdf(sheetname): d, i = [11,22,33], [1,2,3] return DataFrame(d,i,columns=[sheetname]) - + sheets = ['AAA','BBB','CCC'] - + dfs = [tdf(s) for s in sheets] dfs = dict(zip(sheets,dfs)) - + with ensure_clean('.xlsx') as pth: with ExcelWriter(pth) as ew: - for sheetname, df in dfs.iteritems(): + for sheetname, df in iteritems(dfs): df.to_excel(ew,sheetname) dfs_returned = pd.read_excel(pth,sheetname=sheets) for s in sheets: tm.assert_frame_equal(dfs[s],dfs_returned[s]) - + def test_reader_seconds(self): # Test reading times with and without milliseconds. GH5945. _skip_if_no_xlrd() @@ -520,6 +520,29 @@ def test_reader_seconds(self): actual = read_excel(epoch_1904, 'Sheet1') tm.assert_frame_equal(actual, expected) + # GH6403 + def test_read_excel_blank(self): + _skip_if_no_xlrd() + + blank = os.path.join(self.dirpath, 'blank.xls') + actual = read_excel(blank, 'Sheet1') + tm.assert_frame_equal(actual, DataFrame()) + + blank = os.path.join(self.dirpath, 'blank.xlsx') + actual = read_excel(blank, 'Sheet1') + tm.assert_frame_equal(actual, DataFrame()) + + def test_read_excel_blank_with_header(self): + _skip_if_no_xlrd() + + expected = DataFrame(columns=['col_1', 'col_2']) + blank = os.path.join(self.dirpath, 'blank_with_header.xls') + actual = read_excel(blank, 'Sheet1') + tm.assert_frame_equal(actual, expected) + + blank = os.path.join(self.dirpath, 'blank_with_header.xlsx') + actual = read_excel(blank, 'Sheet1') + tm.assert_frame_equal(actual, expected) class ExcelWriterBase(SharedItems): # Base class for test cases to run with different Excel writers. @@ -1218,6 +1241,30 @@ def test_datetimes(self): tm.assert_series_equal(write_frame['A'], read_frame['A']) + # GH7074 + def test_bytes_io(self): + bio = BytesIO() + df = DataFrame(np.random.randn(10, 2)) + writer = ExcelWriter(bio) + df.to_excel(writer) + writer.save() + bio.seek(0) + reread_df = pd.read_excel(bio) + tm.assert_frame_equal(df, reread_df) + + # GH8188 + def test_write_lists_dict(self): + df = pd.DataFrame({'mixed': ['a', ['b', 'c'], {'d': 'e', 'f': 2}], + 'numeric': [1, 2, 3.0], + 'str': ['apple', 'banana', 'cherry']}) + expected = df.copy() + expected.mixed = expected.mixed.apply(str) + expected.numeric = expected.numeric.astype('int64') + with ensure_clean(self.ext) as path: + df.to_excel(path, 'Sheet1') + read = read_excel(path, 'Sheet1', header=0) + tm.assert_frame_equal(read, expected) + def raise_wrapper(major_ver): def versioned_raise_wrapper(orig_method): @functools.wraps(orig_method) @@ -1512,6 +1559,7 @@ class XlsxWriterTests_NoMerge(ExcelWriterBase, tm.TestCase): class ExcelWriterEngineTests(tm.TestCase): + def test_ExcelWriter_dispatch(self): with tm.assertRaisesRegexp(ValueError, 'No engine'): ExcelWriter('nothing') @@ -1527,12 +1575,12 @@ def test_ExcelWriter_dispatch(self): with ensure_clean('.xlsx') as path: writer = ExcelWriter(path) - tm.assert_isinstance(writer, writer_klass) + tm.assertIsInstance(writer, writer_klass) _skip_if_no_xlwt() with ensure_clean('.xls') as path: writer = ExcelWriter(path) - tm.assert_isinstance(writer, _XlwtWriter) + tm.assertIsInstance(writer, _XlwtWriter) def test_register_writer(self): # some awkward mocking to test out dispatch and such actually works @@ -1560,7 +1608,7 @@ def check_called(func): register_writer(DummyClass) writer = ExcelWriter('something.test') - tm.assert_isinstance(writer, DummyClass) + tm.assertIsInstance(writer, DummyClass) df = tm.makeCustomDataframe(1, 1) panel = tm.makePanel() func = lambda: df.to_excel('something.test') diff --git a/pandas/io/tests/test_html.py b/pandas/io/tests/test_html.py index c162bd7c50f5a..9093df9f0bf62 100644 --- a/pandas/io/tests/test_html.py +++ b/pandas/io/tests/test_html.py @@ -159,12 +159,12 @@ def test_spam_with_types(self): def test_spam_no_match(self): dfs = self.read_html(self.spam_data) for df in dfs: - tm.assert_isinstance(df, DataFrame) + tm.assertIsInstance(df, DataFrame) def test_banklist_no_match(self): dfs = self.read_html(self.banklist_data, attrs={'id': 'table'}) for df in dfs: - tm.assert_isinstance(df, DataFrame) + tm.assertIsInstance(df, DataFrame) def test_spam_header(self): df = self.read_html(self.spam_data, '.*Water.*', header=1)[0] @@ -307,9 +307,9 @@ def test_file_url(self): url = self.banklist_data dfs = self.read_html(file_path_to_url(url), 'First', attrs={'id': 'table'}) - tm.assert_isinstance(dfs, list) + tm.assertIsInstance(dfs, list) for df in dfs: - tm.assert_isinstance(df, DataFrame) + tm.assertIsInstance(df, DataFrame) @slow def test_invalid_table_attrs(self): @@ -325,34 +325,34 @@ def _bank_data(self, *args, **kwargs): @slow def test_multiindex_header(self): df = self._bank_data(header=[0, 1])[0] - tm.assert_isinstance(df.columns, MultiIndex) + tm.assertIsInstance(df.columns, MultiIndex) @slow def test_multiindex_index(self): df = self._bank_data(index_col=[0, 1])[0] - tm.assert_isinstance(df.index, MultiIndex) + tm.assertIsInstance(df.index, MultiIndex) @slow def test_multiindex_header_index(self): df = self._bank_data(header=[0, 1], index_col=[0, 1])[0] - tm.assert_isinstance(df.columns, MultiIndex) - tm.assert_isinstance(df.index, MultiIndex) + tm.assertIsInstance(df.columns, MultiIndex) + tm.assertIsInstance(df.index, MultiIndex) @slow def test_multiindex_header_skiprows_tuples(self): df = self._bank_data(header=[0, 1], skiprows=1, tupleize_cols=True)[0] - tm.assert_isinstance(df.columns, Index) + tm.assertIsInstance(df.columns, Index) @slow def test_multiindex_header_skiprows(self): df = self._bank_data(header=[0, 1], skiprows=1)[0] - tm.assert_isinstance(df.columns, MultiIndex) + tm.assertIsInstance(df.columns, MultiIndex) @slow def test_multiindex_header_index_skiprows(self): df = self._bank_data(header=[0, 1], index_col=[0, 1], skiprows=1)[0] - tm.assert_isinstance(df.index, MultiIndex) - tm.assert_isinstance(df.columns, MultiIndex) + tm.assertIsInstance(df.index, MultiIndex) + tm.assertIsInstance(df.columns, MultiIndex) @slow def test_regex_idempotency(self): @@ -360,9 +360,9 @@ def test_regex_idempotency(self): dfs = self.read_html(file_path_to_url(url), match=re.compile(re.compile('Florida')), attrs={'id': 'table'}) - tm.assert_isinstance(dfs, list) + tm.assertIsInstance(dfs, list) for df in dfs: - tm.assert_isinstance(df, DataFrame) + tm.assertIsInstance(df, DataFrame) def test_negative_skiprows(self): with tm.assertRaisesRegexp(ValueError, @@ -426,10 +426,10 @@ def test_empty_tables(self): res1 = self.read_html(StringIO(data1)) res2 = self.read_html(StringIO(data2)) assert_framelist_equal(res1, res2) - + def test_tfoot_read(self): """ - Make sure that read_html reads tfoot, containing td or th. + Make sure that read_html reads tfoot, containing td or th. Ignores empty tfoot """ data_template = ''' @@ -452,10 +452,10 @@ def test_tfoot_read(self): data1 = data_template.format(footer = "") data2 = data_template.format(footer ="") - + d1 = {'A': ['bodyA'], 'B': ['bodyB']} d2 = {'A': ['bodyA', 'footA'], 'B': ['bodyB', 'footB']} - + tm.assert_frame_equal(self.read_html(data1)[0], DataFrame(d1)) tm.assert_frame_equal(self.read_html(data2)[0], DataFrame(d2)) @@ -540,9 +540,11 @@ def try_remove_ws(x): 'Hamilton Bank, NA', 'The Citizens Savings Bank'] dfnew = df.applymap(try_remove_ws).replace(old, new) gtnew = ground_truth.applymap(try_remove_ws) - converted = dfnew.convert_objects(convert_numeric=True) - tm.assert_frame_equal(converted.convert_objects(convert_dates='coerce'), - gtnew) + converted = dfnew.convert_objects(datetime=True, numeric=True) + date_cols = ['Closing Date','Updated Date'] + converted[date_cols] = converted[date_cols].convert_objects(datetime=True, + coerce=True) + tm.assert_frame_equal(converted,gtnew) @slow def test_gold_canyon(self): @@ -721,8 +723,8 @@ def test_data_fail(self): def test_works_on_valid_markup(self): filename = os.path.join(DATA_PATH, 'valid_markup.html') dfs = self.read_html(filename, index_col=0) - tm.assert_isinstance(dfs, list) - tm.assert_isinstance(dfs[0], DataFrame) + tm.assertIsInstance(dfs, list) + tm.assertIsInstance(dfs[0], DataFrame) @slow def test_fallback_success(self): diff --git a/pandas/io/tests/test_json/test_pandas.py b/pandas/io/tests/test_json/test_pandas.py index c145c717df4c4..66c2bbde0b3f8 100644 --- a/pandas/io/tests/test_json/test_pandas.py +++ b/pandas/io/tests/test_json/test_pandas.py @@ -178,7 +178,10 @@ def _check_orient(df, orient, dtype=None, numpy=False, self.assertTrue(df.columns.equals(unser.columns)) elif orient == "values": # index and cols are not captured in this orientation - assert_almost_equal(df.values, unser.values) + if numpy is True and df.shape == (0, 0): + assert unser.shape[0] == 0 + else: + assert_almost_equal(df.values, unser.values) elif orient == "split": # index and col labels might not be strings unser.index = [str(i) for i in unser.index] @@ -670,15 +673,20 @@ def test_doc_example(self): def test_misc_example(self): # parsing unordered input fails - result = read_json('[{"a": 1, "b": 2}, {"b":2, "a" :1}]',numpy=True) - expected = DataFrame([[1,2],[1,2]],columns=['a','b']) - with tm.assertRaisesRegexp(AssertionError, - '\[index\] left \[.+\], right \[.+\]'): + result = read_json('[{"a": 1, "b": 2}, {"b":2, "a" :1}]', numpy=True) + expected = DataFrame([[1,2], [1,2]], columns=['a', 'b']) + + error_msg = """DataFrame\\.index are different + +DataFrame\\.index values are different \\(100\\.0 %\\) +\\[left\\]: Index\\(\\[u?'a', u?'b'\\], dtype='object'\\) +\\[right\\]: Int64Index\\(\\[0, 1\\], dtype='int64'\\)""" + with tm.assertRaisesRegexp(AssertionError, error_msg): assert_frame_equal(result, expected) result = read_json('[{"a": 1, "b": 2}, {"b":2, "a" :1}]') - expected = DataFrame([[1,2],[1,2]],columns=['a','b']) - assert_frame_equal(result,expected) + expected = DataFrame([[1,2], [1,2]], columns=['a','b']) + assert_frame_equal(result, expected) @network def test_round_trip_exception_(self): @@ -739,3 +747,9 @@ def my_handler_raises(obj): raise TypeError("raisin") self.assertRaises(TypeError, DataFrame({'a': [1, 2, object()]}).to_json, default_handler=my_handler_raises) + + +if __name__ == '__main__': + import nose + nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', + '--pdb-failure', '-s'], exit=False) \ No newline at end of file diff --git a/pandas/io/tests/test_json/test_ujson.py b/pandas/io/tests/test_json/test_ujson.py index fcd5515419537..af0a1da830c83 100644 --- a/pandas/io/tests/test_json/test_ujson.py +++ b/pandas/io/tests/test_json/test_ujson.py @@ -21,8 +21,7 @@ import pandas.compat as compat import numpy as np -from numpy.testing import (assert_array_equal, - assert_array_almost_equal_nulp, +from numpy.testing import (assert_array_almost_equal_nulp, assert_approx_equal) import pytz import dateutil @@ -36,7 +35,7 @@ def _skip_if_python_ver(skip_major, skip_minor=None): raise nose.SkipTest("skipping Python version %d.%d" % (major, minor)) -json_unicode = (json.dumps if sys.version_info[0] >= 3 +json_unicode = (json.dumps if compat.PY3 else partial(json.dumps, encoding="utf-8")) class UltraJSONTests(TestCase): @@ -114,6 +113,9 @@ def test_decimalDecodeTestPrecise(self): self.assertEqual(sut, decoded) def test_encodeDoubleTinyExponential(self): + if compat.is_platform_windows() and not compat.PY3: + raise nose.SkipTest("buggy on win-64 for py2") + num = 1e-40 self.assertEqual(num, ujson.decode(ujson.encode(num))) num = 1e-100 @@ -163,7 +165,7 @@ def test_encodeArrayOfNestedArrays(self): #self.assertEqual(output, json.dumps(input)) self.assertEqual(input, ujson.decode(output)) input = np.array(input) - assert_array_equal(input, ujson.decode(output, numpy=True, dtype=input.dtype)) + tm.assert_numpy_array_equal(input, ujson.decode(output, numpy=True, dtype=input.dtype)) def test_encodeArrayOfDoubles(self): input = [ 31337.31337, 31337.31337, 31337.31337, 31337.31337] * 10 @@ -171,7 +173,7 @@ def test_encodeArrayOfDoubles(self): self.assertEqual(input, json.loads(output)) #self.assertEqual(output, json.dumps(input)) self.assertEqual(input, ujson.decode(output)) - assert_array_equal(np.array(input), ujson.decode(output, numpy=True)) + tm.assert_numpy_array_equal(np.array(input), ujson.decode(output, numpy=True)) def test_doublePrecisionTest(self): input = 30.012345678901234 @@ -268,7 +270,7 @@ def test_encodeArrayInArray(self): self.assertEqual(input, json.loads(output)) self.assertEqual(output, json.dumps(input)) self.assertEqual(input, ujson.decode(output)) - assert_array_equal(np.array(input), ujson.decode(output, numpy=True)) + tm.assert_numpy_array_equal(np.array(input), ujson.decode(output, numpy=True)) pass def test_encodeIntConversion(self): @@ -304,7 +306,7 @@ def test_encodeListConversion(self): output = ujson.encode(input) self.assertEqual(input, json.loads(output)) self.assertEqual(input, ujson.decode(output)) - assert_array_equal(np.array(input), ujson.decode(output, numpy=True)) + tm.assert_numpy_array_equal(np.array(input), ujson.decode(output, numpy=True)) pass def test_encodeDictConversion(self): @@ -673,8 +675,8 @@ def test_encodeListLongConversion(self): output = ujson.encode(input) self.assertEqual(input, json.loads(output)) self.assertEqual(input, ujson.decode(output)) - assert_array_equal(np.array(input), ujson.decode(output, numpy=True, - dtype=np.int64)) + tm.assert_numpy_array_equal(np.array(input), ujson.decode(output, numpy=True, + dtype=np.int64)) pass def test_encodeLongConversion(self): @@ -752,7 +754,7 @@ def test_loadFile(self): f = StringIO("[1,2,3,4]") self.assertEqual([1, 2, 3, 4], ujson.load(f)) f = StringIO("[1,2,3,4]") - assert_array_equal(np.array([1, 2, 3, 4]), ujson.load(f, numpy=True)) + tm.assert_numpy_array_equal(np.array([1, 2, 3, 4]), ujson.load(f, numpy=True)) def test_loadFileLikeObject(self): class filelike: @@ -765,7 +767,7 @@ def read(self): f = filelike() self.assertEqual([1, 2, 3, 4], ujson.load(f)) f = filelike() - assert_array_equal(np.array([1, 2, 3, 4]), ujson.load(f, numpy=True)) + tm.assert_numpy_array_equal(np.array([1, 2, 3, 4]), ujson.load(f, numpy=True)) def test_loadFileArgsError(self): try: @@ -903,7 +905,7 @@ def testBoolArray(self): inpt = np.array([True, False, True, True, False, True, False , False], dtype=np.bool) outp = np.array(ujson.decode(ujson.encode(inpt)), dtype=np.bool) - assert_array_equal(inpt, outp) + tm.assert_numpy_array_equal(inpt, outp) def testInt(self): num = np.int(2562010) @@ -940,7 +942,7 @@ def testIntArray(self): for dtype in dtypes: inpt = arr.astype(dtype) outp = np.array(ujson.decode(ujson.encode(inpt)), dtype=dtype) - assert_array_equal(inpt, outp) + tm.assert_numpy_array_equal(inpt, outp) def testIntMax(self): num = np.int(np.iinfo(np.int).max) @@ -1005,26 +1007,26 @@ def testArrays(self): arr = np.arange(100); arr = arr.reshape((10, 10)) - assert_array_equal(np.array(ujson.decode(ujson.encode(arr))), arr) - assert_array_equal(ujson.decode(ujson.encode(arr), numpy=True), arr) + tm.assert_numpy_array_equal(np.array(ujson.decode(ujson.encode(arr))), arr) + tm.assert_numpy_array_equal(ujson.decode(ujson.encode(arr), numpy=True), arr) arr = arr.reshape((5, 5, 4)) - assert_array_equal(np.array(ujson.decode(ujson.encode(arr))), arr) - assert_array_equal(ujson.decode(ujson.encode(arr), numpy=True), arr) + tm.assert_numpy_array_equal(np.array(ujson.decode(ujson.encode(arr))), arr) + tm.assert_numpy_array_equal(ujson.decode(ujson.encode(arr), numpy=True), arr) arr = arr.reshape((100, 1)) - assert_array_equal(np.array(ujson.decode(ujson.encode(arr))), arr) - assert_array_equal(ujson.decode(ujson.encode(arr), numpy=True), arr) + tm.assert_numpy_array_equal(np.array(ujson.decode(ujson.encode(arr))), arr) + tm.assert_numpy_array_equal(ujson.decode(ujson.encode(arr), numpy=True), arr) arr = np.arange(96); arr = arr.reshape((2, 2, 2, 2, 3, 2)) - assert_array_equal(np.array(ujson.decode(ujson.encode(arr))), arr) - assert_array_equal(ujson.decode(ujson.encode(arr), numpy=True), arr) + tm.assert_numpy_array_equal(np.array(ujson.decode(ujson.encode(arr))), arr) + tm.assert_numpy_array_equal(ujson.decode(ujson.encode(arr), numpy=True), arr) l = ['a', list(), dict(), dict(), list(), 42, 97.8, ['a', 'b'], {'key': 'val'}] arr = np.array(l) - assert_array_equal(np.array(ujson.decode(ujson.encode(arr))), arr) + tm.assert_numpy_array_equal(np.array(ujson.decode(ujson.encode(arr))), arr) arr = np.arange(100.202, 200.202, 1, dtype=np.float32); arr = arr.reshape((5, 5, 4)) @@ -1129,22 +1131,20 @@ def testArrayNumpyLabelled(self): self.assertTrue(output[1] is None) self.assertTrue((np.array([u('a')]) == output[2]).all()) - # py3 is non-determinstic on the ordering...... - if not compat.PY3: - input = [{'a': 42, 'b':31}, {'a': 24, 'c': 99}, {'a': 2.4, 'b': 78}] - output = ujson.loads(ujson.dumps(input), numpy=True, labelled=True) - expectedvals = np.array([42, 31, 24, 99, 2.4, 78], dtype=int).reshape((3,2)) - self.assertTrue((expectedvals == output[0]).all()) - self.assertTrue(output[1] is None) - self.assertTrue((np.array([u('a'), 'b']) == output[2]).all()) - + # Write out the dump explicitly so there is no dependency on iteration order GH10837 + input_dumps = '[{"a": 42, "b":31}, {"a": 24, "c": 99}, {"a": 2.4, "b": 78}]' + output = ujson.loads(input_dumps, numpy=True, labelled=True) + expectedvals = np.array([42, 31, 24, 99, 2.4, 78], dtype=int).reshape((3, 2)) + self.assertTrue((expectedvals == output[0]).all()) + self.assertTrue(output[1] is None) + self.assertTrue((np.array([u('a'), 'b']) == output[2]).all()) - input = {1: {'a': 42, 'b':31}, 2: {'a': 24, 'c': 99}, 3: {'a': 2.4, 'b': 78}} - output = ujson.loads(ujson.dumps(input), numpy=True, labelled=True) - expectedvals = np.array([42, 31, 24, 99, 2.4, 78], dtype=int).reshape((3,2)) - self.assertTrue((expectedvals == output[0]).all()) - self.assertTrue((np.array(['1','2','3']) == output[1]).all()) - self.assertTrue((np.array(['a', 'b']) == output[2]).all()) + input_dumps = '{"1": {"a": 42, "b":31}, "2": {"a": 24, "c": 99}, "3": {"a": 2.4, "b": 78}}' + output = ujson.loads(input_dumps, numpy=True, labelled=True) + expectedvals = np.array([42, 31, 24, 99, 2.4, 78], dtype=int).reshape((3, 2)) + self.assertTrue((expectedvals == output[0]).all()) + self.assertTrue((np.array(['1', '2', '3']) == output[1]).all()) + self.assertTrue((np.array(['a', 'b']) == output[2]).all()) class PandasJSONTests(TestCase): @@ -1155,19 +1155,19 @@ def testDataFrame(self): # column indexed outp = DataFrame(ujson.decode(ujson.encode(df))) self.assertTrue((df == outp).values.all()) - assert_array_equal(df.columns, outp.columns) - assert_array_equal(df.index, outp.index) + tm.assert_numpy_array_equal(df.columns, outp.columns) + tm.assert_numpy_array_equal(df.index, outp.index) dec = _clean_dict(ujson.decode(ujson.encode(df, orient="split"))) outp = DataFrame(**dec) self.assertTrue((df == outp).values.all()) - assert_array_equal(df.columns, outp.columns) - assert_array_equal(df.index, outp.index) + tm.assert_numpy_array_equal(df.columns, outp.columns) + tm.assert_numpy_array_equal(df.index, outp.index) outp = DataFrame(ujson.decode(ujson.encode(df, orient="records"))) outp.index = df.index self.assertTrue((df == outp).values.all()) - assert_array_equal(df.columns, outp.columns) + tm.assert_numpy_array_equal(df.columns, outp.columns) outp = DataFrame(ujson.decode(ujson.encode(df, orient="values"))) outp.index = df.index @@ -1175,8 +1175,8 @@ def testDataFrame(self): outp = DataFrame(ujson.decode(ujson.encode(df, orient="index"))) self.assertTrue((df.transpose() == outp).values.all()) - assert_array_equal(df.transpose().columns, outp.columns) - assert_array_equal(df.transpose().index, outp.index) + tm.assert_numpy_array_equal(df.transpose().columns, outp.columns) + tm.assert_numpy_array_equal(df.transpose().index, outp.index) def testDataFrameNumpy(self): df = DataFrame([[1,2,3], [4,5,6]], index=['a', 'b'], columns=['x', 'y', 'z']) @@ -1184,20 +1184,20 @@ def testDataFrameNumpy(self): # column indexed outp = DataFrame(ujson.decode(ujson.encode(df), numpy=True)) self.assertTrue((df == outp).values.all()) - assert_array_equal(df.columns, outp.columns) - assert_array_equal(df.index, outp.index) + tm.assert_numpy_array_equal(df.columns, outp.columns) + tm.assert_numpy_array_equal(df.index, outp.index) dec = _clean_dict(ujson.decode(ujson.encode(df, orient="split"), numpy=True)) outp = DataFrame(**dec) self.assertTrue((df == outp).values.all()) - assert_array_equal(df.columns, outp.columns) - assert_array_equal(df.index, outp.index) + tm.assert_numpy_array_equal(df.columns, outp.columns) + tm.assert_numpy_array_equal(df.index, outp.index) outp = DataFrame(ujson.decode(ujson.encode(df, orient="index"), numpy=True)) self.assertTrue((df.transpose() == outp).values.all()) - assert_array_equal(df.transpose().columns, outp.columns) - assert_array_equal(df.transpose().index, outp.index) + tm.assert_numpy_array_equal(df.transpose().columns, outp.columns) + tm.assert_numpy_array_equal(df.transpose().index, outp.index) def testDataFrameNested(self): df = DataFrame([[1,2,3], [4,5,6]], index=['a', 'b'], columns=['x', 'y', 'z']) @@ -1230,18 +1230,18 @@ def testDataFrameNumpyLabelled(self): # column indexed outp = DataFrame(*ujson.decode(ujson.encode(df), numpy=True, labelled=True)) self.assertTrue((df.T == outp).values.all()) - assert_array_equal(df.T.columns, outp.columns) - assert_array_equal(df.T.index, outp.index) + tm.assert_numpy_array_equal(df.T.columns, outp.columns) + tm.assert_numpy_array_equal(df.T.index, outp.index) outp = DataFrame(*ujson.decode(ujson.encode(df, orient="records"), numpy=True, labelled=True)) outp.index = df.index self.assertTrue((df == outp).values.all()) - assert_array_equal(df.columns, outp.columns) + tm.assert_numpy_array_equal(df.columns, outp.columns) outp = DataFrame(*ujson.decode(ujson.encode(df, orient="index"), numpy=True, labelled=True)) self.assertTrue((df == outp).values.all()) - assert_array_equal(df.columns, outp.columns) - assert_array_equal(df.index, outp.index) + tm.assert_numpy_array_equal(df.columns, outp.columns) + tm.assert_numpy_array_equal(df.index, outp.index) def testSeries(self): s = Series([10, 20, 30, 40, 50, 60], name="series", index=[6,7,8,9,10,15]) diff --git a/pandas/io/tests/test_packers.py b/pandas/io/tests/test_packers.py index 92e0d7ba1a338..1267821086d61 100644 --- a/pandas/io/tests/test_packers.py +++ b/pandas/io/tests/test_packers.py @@ -1,5 +1,6 @@ import nose +import os import datetime import numpy as np import sys @@ -11,7 +12,7 @@ date_range, period_range, Index, SparseSeries, SparseDataFrame, SparsePanel) import pandas.util.testing as tm -from pandas.util.testing import ensure_clean +from pandas.util.testing import ensure_clean, assert_index_equal from pandas.tests.test_series import assert_series_equal from pandas.tests.test_frame import assert_frame_equal from pandas.tests.test_panel import assert_panel_equal @@ -39,6 +40,8 @@ def check_arbitrary(a, b): assert_frame_equal(a, b) elif isinstance(a, Series): assert_series_equal(a, b) + elif isinstance(a, Index): + assert_index_equal(a, b) else: assert(a == b) @@ -51,9 +54,9 @@ def setUp(self): def tearDown(self): pass - def encode_decode(self, x, **kwargs): + def encode_decode(self, x, compress=None, **kwargs): with ensure_clean(self.path) as p: - to_msgpack(p, x, **kwargs) + to_msgpack(p, x, compress=compress, **kwargs) return read_msgpack(p, **kwargs) class TestAPI(TestPackers): @@ -93,6 +96,17 @@ def test_iterator_with_string_io(self): for i, result in enumerate(read_msgpack(s,iterator=True)): tm.assert_frame_equal(result,dfs[i]) + def test_invalid_arg(self): + #GH10369 + class A(object): + def __init__(self): + self.read = 0 + + tm.assertRaises(ValueError, read_msgpack, path_or_buf=None) + tm.assertRaises(ValueError, read_msgpack, path_or_buf={}) + tm.assertRaises(ValueError, read_msgpack, path_or_buf=A()) + + class TestNumpy(TestPackers): def test_numpy_scalar_float(self): @@ -385,6 +399,24 @@ def tests_datetimeindex_freq_issue(self): result = self.encode_decode(df) assert_frame_equal(result, df) + def test_dataframe_duplicate_column_names(self): + + # GH 9618 + expected_1 = DataFrame(columns=['a', 'a']) + expected_2 = DataFrame(columns=[1]*100) + expected_2.loc[0] = np.random.randn(100) + expected_3 = DataFrame(columns=[1, 1]) + expected_3.loc[0] = ['abc', np.nan] + + result_1 = self.encode_decode(expected_1) + result_2 = self.encode_decode(expected_2) + result_3 = self.encode_decode(expected_3) + + assert_frame_equal(result_1, expected_1) + assert_frame_equal(result_2, expected_2) + assert_frame_equal(result_3, expected_3) + + class TestSparse(TestPackers): def _check_roundtrip(self, obj, comparator, **kwargs): @@ -485,6 +517,100 @@ def test_compression_blosc(self): assert_frame_equal(self.frame[k], i_rec[k]) +class TestEncoding(TestPackers): + def setUp(self): + super(TestEncoding, self).setUp() + data = { + 'A': [compat.u('\u2019')] * 1000, + 'B': np.arange(1000, dtype=np.int32), + 'C': list(100 * 'abcdefghij'), + 'D': date_range(datetime.datetime(2015, 4, 1), periods=1000), + 'E': [datetime.timedelta(days=x) for x in range(1000)], + 'G': [400] * 1000 + } + self.frame = { + 'float': DataFrame(dict((k, data[k]) for k in ['A', 'A'])), + 'int': DataFrame(dict((k, data[k]) for k in ['B', 'B'])), + 'mixed': DataFrame(data), + } + self.utf_encodings = ['utf8', 'utf16', 'utf32'] + + def test_utf(self): + # GH10581 + for encoding in self.utf_encodings: + for frame in compat.itervalues(self.frame): + result = self.encode_decode(frame, encoding=encoding) + assert_frame_equal(result, frame) + + +class TestMsgpack(): + """ + How to add msgpack tests: + + 1. Install pandas version intended to output the msgpack. +TestPackers + 2. Execute "generate_legacy_storage_files.py" to create the msgpack. + $ python generate_legacy_storage_files.py msgpack + + 3. Move the created pickle to "data/legacy_msgpack/" directory. + + NOTE: TestMsgpack can't be a subclass of tm.Testcase to use test generator. + http://stackoverflow.com/questions/6689537/nose-test-generators-inside-class + """ + def setUp(self): + from pandas.io.tests.generate_legacy_storage_files import ( + create_msgpack_data, create_data) + self.data = create_msgpack_data() + self.all_data = create_data() + self.path = u('__%s__.msgpack' % tm.rands(10)) + self.minimum_structure = {'series': ['float', 'int', 'mixed', 'ts', 'mi', 'dup'], + 'frame': ['float', 'int', 'mixed', 'mi'], + 'panel': ['float'], + 'index': ['int', 'date', 'period'], + 'mi': ['reg2']} + + def check_min_structure(self, data): + for typ, v in self.minimum_structure.items(): + assert typ in data, '"{0}" not found in unpacked data'.format(typ) + for kind in v: + assert kind in data[typ], '"{0}" not found in data["{1}"]'.format(kind, typ) + + def compare(self, vf): + data = read_msgpack(vf) + self.check_min_structure(data) + for typ, dv in data.items(): + assert typ in self.all_data, 'unpacked data contains extra key "{0}"'.format(typ) + for dt, result in dv.items(): + assert dt in self.all_data[typ], 'data["{0}"] contains extra key "{1}"'.format(typ, dt) + try: + expected = self.data[typ][dt] + except KeyError: + continue + check_arbitrary(result, expected) + + return data + + def read_msgpacks(self, version): + + pth = tm.get_data_path('legacy_msgpack/{0}'.format(str(version))) + n = 0 + for f in os.listdir(pth): + vf = os.path.join(pth, f) + self.compare(vf) + n += 1 + assert n > 0, 'Msgpack files are not tested' + + def test_msgpack(self): + msgpack_path = tm.get_data_path('legacy_msgpack') + n = 0 + for v in os.listdir(msgpack_path): + pth = os.path.join(msgpack_path, v) + if os.path.isdir(pth): + yield self.read_msgpacks, v + n += 1 + assert n > 0, 'Msgpack files are not tested' + + if __name__ == '__main__': import nose nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'], diff --git a/pandas/io/tests/test_parsers.py b/pandas/io/tests/test_parsers.py index 4c040252ee3cb..ed261edad4f20 100755 --- a/pandas/io/tests/test_parsers.py +++ b/pandas/io/tests/test_parsers.py @@ -33,7 +33,6 @@ import pandas.tseries.tools as tools from numpy.testing.decorators import slow -from numpy.testing import assert_array_equal import pandas.parser @@ -163,7 +162,7 @@ def test_empty_string(self): def test_read_csv(self): if not compat.PY3: - if 'win' in sys.platform: + if compat.is_platform_windows(): prefix = u("file:///") else: prefix = u("file://") @@ -276,7 +275,7 @@ def test_squeeze(self): expected = Series([1, 2, 3], name=1, index=idx) result = self.read_table(StringIO(data), sep=',', index_col=0, header=None, squeeze=True) - tm.assert_isinstance(result, Series) + tm.assertIsInstance(result, Series) tm.assert_series_equal(result, expected) def test_squeeze_no_view(self): @@ -747,7 +746,7 @@ def test_default_na_values(self): _NA_VALUES = set(['-1.#IND', '1.#QNAN', '1.#IND', '-1.#QNAN', '#N/A','N/A', 'NA', '#NA', 'NULL', 'NaN', 'nan', '-NaN', '-nan', '#N/A N/A','']) - assert_array_equal (_NA_VALUES, parsers._NA_VALUES) + self.assertEqual(_NA_VALUES, parsers._NA_VALUES) nv = len(_NA_VALUES) def f(i, v): if i == 0: @@ -1016,7 +1015,7 @@ def test_parse_dates_column_list(self): expected['aux_date'] = to_datetime(expected['aux_date'], dayfirst=True) expected['aux_date'] = lmap(Timestamp, expected['aux_date']) - tm.assert_isinstance(expected['aux_date'][0], datetime) + tm.assertIsInstance(expected['aux_date'][0], datetime) df = self.read_csv(StringIO(data), sep=";", index_col=lrange(4), parse_dates=[0, 5], dayfirst=True) @@ -1117,7 +1116,7 @@ def test_read_csv_infer_compression(self): def test_read_table_unicode(self): fin = BytesIO(u('\u0141aski, Jan;1').encode('utf-8')) df1 = read_table(fin, sep=";", encoding="utf-8", header=None) - tm.assert_isinstance(df1[0].values[0], compat.text_type) + tm.assertIsInstance(df1[0].values[0], compat.text_type) def test_read_table_wrong_num_columns(self): # too few! @@ -1300,7 +1299,7 @@ def test_iterator(self): treader = self.read_table(StringIO(self.data1), sep=',', index_col=0, iterator=True) - tm.assert_isinstance(treader, TextFileReader) + tm.assertIsInstance(treader, TextFileReader) # stopping iteration when on chunksize is specified, GH 3967 data = """A,B,C @@ -1601,7 +1600,7 @@ def test_converters(self): expected = self.read_csv(StringIO(data)) expected['D'] = expected['D'].map(parse_date) - tm.assert_isinstance(result['D'][0], (datetime, Timestamp)) + tm.assertIsInstance(result['D'][0], (datetime, Timestamp)) tm.assert_frame_equal(result, expected) tm.assert_frame_equal(result2, expected) @@ -2301,6 +2300,81 @@ def test_empty_with_index(self): expected = DataFrame([], columns=['y'], index=Index([], name='x')) tm.assert_frame_equal(result, expected) + def test_emtpy_with_multiindex(self): + # GH 10467 + data = 'x,y,z' + result = self.read_csv(StringIO(data), index_col=['x', 'y']) + expected = DataFrame([], columns=['z'], + index=MultiIndex.from_arrays([[]] * 2, names=['x', 'y'])) + tm.assert_frame_equal(result, expected) + + def test_empty_with_reversed_multiindex(self): + data = 'x,y,z' + result = self.read_csv(StringIO(data), index_col=[1, 0]) + expected = DataFrame([], columns=['z'], + index=MultiIndex.from_arrays([[]] * 2, names=['y', 'x'])) + tm.assert_frame_equal(result, expected) + + def test_empty_index_col_scenarios(self): + data = 'x,y,z' + + # None, no index + index_col, expected = None, DataFrame([], columns=list('xyz')), + tm.assert_frame_equal(self.read_csv(StringIO(data), index_col=index_col), expected) + + # False, no index + index_col, expected = False, DataFrame([], columns=list('xyz')), + tm.assert_frame_equal(self.read_csv(StringIO(data), index_col=index_col), expected) + + # int, first column + index_col, expected = 0, DataFrame([], columns=['y', 'z'], index=Index([], name='x')) + tm.assert_frame_equal(self.read_csv(StringIO(data), index_col=index_col), expected) + + # int, not first column + index_col, expected = 1, DataFrame([], columns=['x', 'z'], index=Index([], name='y')) + tm.assert_frame_equal(self.read_csv(StringIO(data), index_col=index_col), expected) + + # str, first column + index_col, expected = 'x', DataFrame([], columns=['y', 'z'], index=Index([], name='x')) + tm.assert_frame_equal(self.read_csv(StringIO(data), index_col=index_col), expected) + + # str, not the first column + index_col, expected = 'y', DataFrame([], columns=['x', 'z'], index=Index([], name='y')) + tm.assert_frame_equal(self.read_csv(StringIO(data), index_col=index_col), expected) + + # list of int + index_col, expected = [0, 1], DataFrame([], columns=['z'], + index=MultiIndex.from_arrays([[]] * 2, names=['x', 'y'])) + tm.assert_frame_equal(self.read_csv(StringIO(data), index_col=index_col), expected) + + # list of str + index_col, expected = ( + ['x', 'y'], + DataFrame([], columns=['z'], index=MultiIndex.from_arrays([[]] * 2, names=['x', 'y'])) + ) + tm.assert_frame_equal(self.read_csv(StringIO(data), index_col=index_col), expected) + + # list of int, reversed sequence + index_col, expected = ( + [1, 0], + DataFrame([], columns=['z'], index=MultiIndex.from_arrays([[]] * 2, names=['y', 'x'])) + ) + tm.assert_frame_equal(self.read_csv(StringIO(data), index_col=index_col), expected) + + # list of str, reversed sequence + index_col, expected = ( + ['y', 'x'], + DataFrame([], columns=['z'], index=MultiIndex.from_arrays([[]] * 2, names=['y', 'x'])) + ) + tm.assert_frame_equal(self.read_csv(StringIO(data), index_col=index_col), expected) + + def test_empty_with_index_col_false(self): + # GH 10413 + data = 'x,y' + result = self.read_csv(StringIO(data), index_col=False) + expected = DataFrame([], columns=['x', 'y']) + tm.assert_frame_equal(result, expected) + def test_float_parser(self): # GH 9565 data = '45e-1,4.5,45.,inf,-inf' @@ -2341,6 +2415,94 @@ def test_int64_overflow(self): expected = pd.DataFrame([str(x)]) tm.assert_frame_equal(result, expected) + def test_empty_with_nrows_chunksize(self): + # GH 9535 + expected = pd.DataFrame([], columns=['foo', 'bar']) + + result = self.read_csv(StringIO('foo,bar\n'), nrows=10) + tm.assert_frame_equal(result, expected) + + result = next(iter(pd.read_csv(StringIO('foo,bar\n'), chunksize=10))) + tm.assert_frame_equal(result, expected) + + result = pd.read_csv(StringIO('foo,bar\n'), nrows=10, as_recarray=True) + result = pd.DataFrame(result[2], columns=result[1], index=result[0]) + tm.assert_frame_equal(pd.DataFrame.from_records(result), expected) + + result = next(iter(pd.read_csv(StringIO('foo,bar\n'), chunksize=10, as_recarray=True))) + result = pd.DataFrame(result[2], columns=result[1], index=result[0]) + tm.assert_frame_equal(pd.DataFrame.from_records(result), expected) + + def test_eof_states(self): + # GH 10728 and 10548 + + ## With skip_blank_lines = True + expected = pd.DataFrame([[4, 5, 6]], columns=['a', 'b', 'c']) + + # GH 10728 + # WHITESPACE_LINE + data = 'a,b,c\n4,5,6\n ' + result = self.read_csv(StringIO(data)) + tm.assert_frame_equal(result, expected) + + # GH 10548 + # EAT_LINE_COMMENT + data = 'a,b,c\n4,5,6\n#comment' + result = self.read_csv(StringIO(data), comment='#') + tm.assert_frame_equal(result, expected) + + # EAT_CRNL_NOP + data = 'a,b,c\n4,5,6\n\r' + result = self.read_csv(StringIO(data)) + tm.assert_frame_equal(result, expected) + + # EAT_COMMENT + data = 'a,b,c\n4,5,6#comment' + result = self.read_csv(StringIO(data), comment='#') + tm.assert_frame_equal(result, expected) + + # SKIP_LINE + data = 'a,b,c\n4,5,6\nskipme' + result = self.read_csv(StringIO(data), skiprows=[2]) + tm.assert_frame_equal(result, expected) + + ## With skip_blank_lines = False + + # EAT_LINE_COMMENT + data = 'a,b,c\n4,5,6\n#comment' + result = self.read_csv(StringIO(data), comment='#', skip_blank_lines=False) + expected = pd.DataFrame([[4, 5, 6]], columns=['a', 'b', 'c']) + tm.assert_frame_equal(result, expected) + + # IN_FIELD + data = 'a,b,c\n4,5,6\n ' + result = self.read_csv(StringIO(data), skip_blank_lines=False) + expected = pd.DataFrame([['4', 5, 6], [' ', None, None]], columns=['a', 'b', 'c']) + tm.assert_frame_equal(result, expected) + + # EAT_CRNL + data = 'a,b,c\n4,5,6\n\r' + result = self.read_csv(StringIO(data), skip_blank_lines=False) + expected = pd.DataFrame([[4, 5, 6], [None, None, None]], columns=['a', 'b', 'c']) + tm.assert_frame_equal(result, expected) + + ## Should produce exceptions + + # ESCAPED_CHAR + data = "a,b,c\n4,5,6\n\\" + self.assertRaises(Exception, self.read_csv, StringIO(data), escapechar='\\') + + # ESCAPE_IN_QUOTED_FIELD + data = 'a,b,c\n4,5,6\n"\\' + self.assertRaises(Exception, self.read_csv, StringIO(data), escapechar='\\') + + # IN_QUOTED_FIELD + # Python 2.6 won't throw an exception for this case (see http://bugs.python.org/issue16013) + tm._skip_if_python26() + data = 'a,b,c\n4,5,6\n"' + self.assertRaises(Exception, self.read_csv, StringIO(data), escapechar='\\') + + class TestPythonParser(ParserTests, tm.TestCase): def test_negative_skipfooter_raises(self): @@ -2579,6 +2741,25 @@ def test_fwf_regression(self): res = df.loc[:,c] self.assertTrue(len(res)) + def test_fwf_for_uint8(self): + data = """1421302965.213420 PRI=3 PGN=0xef00 DST=0x17 SRC=0x28 04 154 00 00 00 00 00 127 +1421302964.226776 PRI=6 PGN=0xf002 SRC=0x47 243 00 00 255 247 00 00 71""" + df = read_fwf(StringIO(data), + colspecs=[(0,17),(25,26),(33,37),(49,51),(58,62),(63,1000)], + names=['time','pri','pgn','dst','src','data'], + converters={ + 'pgn':lambda x: int(x,16), + 'src':lambda x: int(x,16), + 'dst':lambda x: int(x,16), + 'data':lambda x: len(x.split(' '))}) + + expected = DataFrame([[1421302965.213420,3,61184,23,40,8], + [1421302964.226776,6,61442,None, 71,8]], + columns = ["time", "pri", "pgn", "dst", "src","data"]) + expected["dst"] = expected["dst"].astype(object) + + tm.assert_frame_equal(df, expected) + def test_fwf_compression(self): try: import gzip @@ -2727,7 +2908,7 @@ def test_iterator(self): treader = self.read_table(StringIO(self.data1), sep=',', index_col=0, iterator=True) - tm.assert_isinstance(treader, TextFileReader) + tm.assertIsInstance(treader, TextFileReader) # stopping iteration when on chunksize is specified, GH 3967 data = """A,B,C @@ -2995,6 +3176,7 @@ def test_whitespace_lines(self): df = self.read_csv(StringIO(data)) tm.assert_almost_equal(df.values, expected) + class TestFwfColspaceSniffing(tm.TestCase): def test_full_file(self): # File with all values @@ -3110,6 +3292,9 @@ def read_table(self, *args, **kwds): return read_table(*args, **kwds) def test_compact_ints(self): + if compat.is_platform_windows(): + raise nose.SkipTest("segfaults on win-64, only when all tests are run") + data = ('0,1,0,0\n' '1,1,0,0\n' '0,1,0,1') @@ -3421,6 +3606,25 @@ def test_compact_ints(self): '1,1,0,0\n' '0,1,0,1') + result = read_csv(StringIO(data), delimiter=',', header=None, + compact_ints=True) + ex_dtype = np.dtype([(str(i), 'i1') for i in range(4)]) + self.assertEqual(result.to_records(index=False).dtype, ex_dtype) + + result = read_csv(StringIO(data), delimiter=',', header=None, + compact_ints=True, + use_unsigned=True) + ex_dtype = np.dtype([(str(i), 'u1') for i in range(4)]) + self.assertEqual(result.to_records(index=False).dtype, ex_dtype) + + def test_compact_ints_as_recarray(self): + if compat.is_platform_windows(): + raise nose.SkipTest("segfaults on win-64, only when all tests are run") + + data = ('0,1,0,0\n' + '1,1,0,0\n' + '0,1,0,1') + result = read_csv(StringIO(data), delimiter=',', header=None, compact_ints=True, as_recarray=True) ex_dtype = np.dtype([(str(i), 'i1') for i in range(4)]) @@ -3460,17 +3664,91 @@ def test_pass_dtype(self): 3,4.5 4,5.5""" + result = self.read_csv(StringIO(data), dtype={'one': 'u1', 1: 'S1'}) + self.assertEqual(result['one'].dtype, 'u1') + self.assertEqual(result['two'].dtype, 'object') + + def test_pass_dtype_as_recarray(self): + data = """\ +one,two +1,2.5 +2,3.5 +3,4.5 +4,5.5""" + + if compat.is_platform_windows(): + raise nose.SkipTest("segfaults on win-64, only when all tests are run") + result = self.read_csv(StringIO(data), dtype={'one': 'u1', 1: 'S1'}, as_recarray=True) self.assertEqual(result['one'].dtype, 'u1') self.assertEqual(result['two'].dtype, 'S1') + def test_empty_pass_dtype(self): + data = 'one,two' + result = self.read_csv(StringIO(data), dtype={'one': 'u1'}) + + expected = DataFrame({'one': np.empty(0, dtype='u1'), + 'two': np.empty(0, dtype=np.object)}) + tm.assert_frame_equal(result, expected) + + def test_empty_with_index_pass_dtype(self): + data = 'one,two' + result = self.read_csv(StringIO(data), index_col=['one'], + dtype={'one': 'u1', 1: 'f'}) + + expected = DataFrame({'two': np.empty(0, dtype='f')}, + index=Index([], dtype='u1', name='one')) + tm.assert_frame_equal(result, expected) + + def test_empty_with_multiindex_pass_dtype(self): + data = 'one,two,three' + result = self.read_csv(StringIO(data), index_col=['one', 'two'], + dtype={'one': 'u1', 1: 'f8'}) + + expected = DataFrame({'three': np.empty(0, dtype=np.object)}, index=MultiIndex.from_arrays( + [np.empty(0, dtype='u1'), np.empty(0, dtype='O')], + names=['one', 'two']) + ) + tm.assert_frame_equal(result, expected) + + def test_empty_with_mangled_column_pass_dtype_by_names(self): + data = 'one,one' + result = self.read_csv(StringIO(data), dtype={'one': 'u1', 'one.1': 'f'}) + + expected = DataFrame({'one': np.empty(0, dtype='u1'), 'one.1': np.empty(0, dtype='f')}) + tm.assert_frame_equal(result, expected) + + def test_empty_with_mangled_column_pass_dtype_by_indexes(self): + data = 'one,one' + result = self.read_csv(StringIO(data), dtype={0: 'u1', 1: 'f'}) + + expected = DataFrame({'one': np.empty(0, dtype='u1'), 'one.1': np.empty(0, dtype='f')}) + tm.assert_frame_equal(result, expected) + + def test_empty_with_dup_column_pass_dtype_by_names(self): + data = 'one,one' + result = self.read_csv(StringIO(data), mangle_dupe_cols=False, dtype={'one': 'u1'}) + expected = pd.concat([Series([], name='one', dtype='u1')] * 2, axis=1) + tm.assert_frame_equal(result, expected) + + def test_empty_with_dup_column_pass_dtype_by_indexes(self): + ### FIXME in GH9424 + raise nose.SkipTest("GH 9424; known failure read_csv with duplicate columns") + + data = 'one,one' + result = self.read_csv(StringIO(data), mangle_dupe_cols=False, dtype={0: 'u1', 1: 'f'}) + expected = pd.concat([Series([], name='one', dtype='u1'), + Series([], name='one', dtype='f')], axis=1) + tm.assert_frame_equal(result, expected) + def test_usecols_dtypes(self): data = """\ 1,2,3 4,5,6 7,8,9 10,11,12""" + result = self.read_csv(StringIO(data), usecols=(0, 1, 2), names=('a', 'b', 'c'), header=None, @@ -3927,6 +4205,25 @@ def test_convert_sql_column_decimals(self): assert_same_values_and_dtype(result, expected) +class TestUrlGz(tm.TestCase): + def setUp(self): + dirpath = tm.get_data_path() + localtable = os.path.join(dirpath, 'salary.table') + self.local_table = read_table(localtable) + + @tm.network + def test_url_gz(self): + url = 'https://raw.github.com/pydata/pandas/master/pandas/io/tests/data/salary.table.gz' + url_table = read_table(url, compression="gzip", engine="python") + tm.assert_frame_equal(url_table, self.local_table) + + @tm.network + def test_url_gz_infer(self): + url = ('https://s3.amazonaws.com/pandas-test/salary.table.gz') + url_table = read_table(url, compression="infer", engine="python") + tm.assert_frame_equal(url_table, self.local_table) + + class TestS3(tm.TestCase): def setUp(self): try: @@ -3942,6 +4239,12 @@ def test_parse_public_s3_bucket(self): nt.assert_false(df.empty) tm.assert_frame_equal(pd.read_csv(tm.get_data_path('tips.csv')), df) + # Read public file from bucket with not-public contents + df = pd.read_csv('s3://cant_get_it/tips.csv') + nt.assert_true(isinstance(df, pd.DataFrame)) + nt.assert_false(df.empty) + tm.assert_frame_equal(pd.read_csv(tm.get_data_path('tips.csv')), df) + @tm.network def test_s3_fails(self): import boto @@ -3949,9 +4252,11 @@ def test_s3_fails(self): 'S3ResponseError: 404 Not Found'): pd.read_csv('s3://nyqpug/asdf.csv') + # Receive a permission error when trying to read a private bucket. + # It's irrelevant here that this isn't actually a table. with tm.assertRaisesRegexp(boto.exception.S3ResponseError, - 'S3ResponseError: 403 Forbidden'): - pd.read_csv('s3://cant_get_it/tips.csv') + 'S3ResponseError: 403 Forbidden'): + pd.read_csv('s3://cant_get_it/') def assert_same_values_and_dtype(res, exp): diff --git a/pandas/io/tests/test_pickle.py b/pandas/io/tests/test_pickle.py index d1396463f3b23..e691fac215002 100644 --- a/pandas/io/tests/test_pickle.py +++ b/pandas/io/tests/test_pickle.py @@ -24,8 +24,8 @@ class TestPickle(): 1. Install pandas version intended to output the pickle. - 2. Execute "generate_legacy_pkcles.py" to create the pickle. - $ python generate_legacy_pickles.py + 2. Execute "generate_legacy_storage_files.py" to create the pickle. + $ python generate_legacy_storage_files.py pickle 3. Move the created pickle to "data/legacy_pickle/" directory. @@ -35,8 +35,8 @@ class TestPickle(): _multiprocess_can_split_ = True def setUp(self): - from pandas.io.tests.generate_legacy_pickles import create_data - self.data = create_data() + from pandas.io.tests.generate_legacy_storage_files import create_pickle_data + self.data = create_pickle_data() self.path = u('__%s__.pickle' % tm.rands(10)) def compare_element(self, typ, result, expected): diff --git a/pandas/io/tests/test_pytables.py b/pandas/io/tests/test_pytables.py index 6aaeb6652f2b6..210852d83094f 100644 --- a/pandas/io/tests/test_pytables.py +++ b/pandas/io/tests/test_pytables.py @@ -131,18 +131,18 @@ def compat_assert_produces_warning(w,f): f() -class TestHDFStore(tm.TestCase): +class Base(tm.TestCase): @classmethod def setUpClass(cls): - super(TestHDFStore, cls).setUpClass() + super(Base, cls).setUpClass() # Pytables 3.0.0 deprecates lots of things tm.reset_testing_mode() @classmethod def tearDownClass(cls): - super(TestHDFStore, cls).tearDownClass() + super(Base, cls).tearDownClass() # Pytables 3.0.0 deprecates lots of things tm.set_testing_mode() @@ -155,6 +155,9 @@ def setUp(self): def tearDown(self): pass + +class TestHDFStore(Base): + def test_factory_fun(self): path = create_tempfile(self.path) try: @@ -400,7 +403,7 @@ def test_repr(self): df['datetime1'] = datetime.datetime(2001,1,2,0,0) df['datetime2'] = datetime.datetime(2001,1,3,0,0) df.ix[3:6,['obj1']] = np.nan - df = df.consolidate().convert_objects() + df = df.consolidate().convert_objects(datetime=True) warnings.filterwarnings('ignore', category=PerformanceWarning) store['df'] = df @@ -725,7 +728,7 @@ def test_put_mixed_type(self): df['datetime1'] = datetime.datetime(2001, 1, 2, 0, 0) df['datetime2'] = datetime.datetime(2001, 1, 3, 0, 0) df.ix[3:6, ['obj1']] = np.nan - df = df.consolidate().convert_objects() + df = df.consolidate().convert_objects(datetime=True) with ensure_clean_store(self.path) as store: _maybe_remove(store, 'df') @@ -1037,6 +1040,28 @@ def test_append_all_nans(self): store.append('df2', df[10:], dropna=False) tm.assert_frame_equal(store['df2'], df) + # Test to make sure defaults are to not drop. + # Corresponding to Issue 9382 + df_with_missing = DataFrame({'col1':[0, np.nan, 2], 'col2':[1, np.nan, np.nan]}) + + with ensure_clean_path(self.path) as path: + df_with_missing.to_hdf(path, 'df_with_missing', format = 'table') + reloaded = read_hdf(path, 'df_with_missing') + tm.assert_frame_equal(df_with_missing, reloaded) + + matrix = [[[np.nan, np.nan, np.nan],[1,np.nan,np.nan]], + [[np.nan, np.nan, np.nan], [np.nan,5,6]], + [[np.nan, np.nan, np.nan],[np.nan,3,np.nan]]] + + panel_with_missing = Panel(matrix, items=['Item1', 'Item2','Item3'], + major_axis=[1,2], + minor_axis=['A', 'B', 'C']) + + with ensure_clean_path(self.path) as path: + panel_with_missing.to_hdf(path, 'panel_with_missing', format='table') + reloaded_panel = read_hdf(path, 'panel_with_missing') + tm.assert_panel_equal(panel_with_missing, reloaded_panel) + def test_append_frame_column_oriented(self): with ensure_clean_store(self.path) as store: @@ -1378,7 +1403,7 @@ def check_col(key,name,size): df_dc.ix[7:9, 'string'] = 'bar' df_dc['string2'] = 'cool' df_dc['datetime'] = Timestamp('20010102') - df_dc = df_dc.convert_objects() + df_dc = df_dc.convert_objects(datetime=True) df_dc.ix[3:5, ['A', 'B', 'datetime']] = np.nan _maybe_remove(store, 'df_dc') @@ -1840,7 +1865,7 @@ def test_table_mixed_dtypes(self): df['datetime1'] = datetime.datetime(2001, 1, 2, 0, 0) df['datetime2'] = datetime.datetime(2001, 1, 3, 0, 0) df.ix[3:6, ['obj1']] = np.nan - df = df.consolidate().convert_objects() + df = df.consolidate().convert_objects(datetime=True) with ensure_clean_store(self.path) as store: store.append('df1_mixed', df) @@ -1896,7 +1921,7 @@ def test_unimplemented_dtypes_table_columns(self): df['obj1'] = 'foo' df['obj2'] = 'bar' df['datetime1'] = datetime.date(2001, 1, 2) - df = df.consolidate().convert_objects() + df = df.consolidate().convert_objects(datetime=True) with ensure_clean_store(self.path) as store: # this fails because we have a date in the object block...... @@ -2067,9 +2092,8 @@ def test_store_timezone(self): # GH2852 # issue storing datetime.date with a timezone as it resets when read back in a new timezone - import platform - if platform.system() == "Windows": - raise nose.SkipTest("timezone setting not supported on windows") + # timezone setting not supported on windows + tm._skip_if_windows() import datetime import time @@ -3766,7 +3790,7 @@ def f(): # valid result = store.select_column('df', 'index') tm.assert_almost_equal(result.values, Series(df.index).values) - self.assertIsInstance(result,Series) + self.assertIsInstance(result, Series) # not a data indexable column self.assertRaises( @@ -3806,6 +3830,14 @@ def f(): result = store.select_column('df3', 'string', start=-2, stop=2) tm.assert_almost_equal(result.values, df3['string'].values[-2:2]) + # GH 10392 - make sure column name is preserved + df4 = DataFrame({'A': np.random.randn(10), 'B': 'foo'}) + store.append('df4', df4, data_columns=True) + expected = df4['B'] + result = store.select_column('df4', 'B') + tm.assert_series_equal(result, expected) + + def test_coordinates(self): df = tm.makeTimeDataFrame() @@ -4724,6 +4756,156 @@ def test_invalid_complib(self): columns=list('ABCDE')) with ensure_clean_path(self.path) as path: self.assertRaises(ValueError, df.to_hdf, path, 'df', complib='blosc:zlib') + # GH10443 + def test_read_nokey(self): + df = DataFrame(np.random.rand(4, 5), + index=list('abcd'), + columns=list('ABCDE')) + with ensure_clean_path(self.path) as path: + df.to_hdf(path, 'df', mode='a') + reread = read_hdf(path) + assert_frame_equal(df, reread) + df.to_hdf(path, 'df2', mode='a') + self.assertRaises(ValueError, read_hdf, path) + + +class TestHDFComplexValues(Base): + # GH10447 + def test_complex_fixed(self): + df = DataFrame(np.random.rand(4, 5).astype(np.complex64), + index=list('abcd'), + columns=list('ABCDE')) + + with ensure_clean_path(self.path) as path: + df.to_hdf(path, 'df') + reread = read_hdf(path, 'df') + assert_frame_equal(df, reread) + + df = DataFrame(np.random.rand(4, 5).astype(np.complex128), + index=list('abcd'), + columns=list('ABCDE')) + with ensure_clean_path(self.path) as path: + df.to_hdf(path, 'df') + reread = read_hdf(path, 'df') + assert_frame_equal(df, reread) + + def test_complex_table(self): + df = DataFrame(np.random.rand(4, 5).astype(np.complex64), + index=list('abcd'), + columns=list('ABCDE')) + + with ensure_clean_path(self.path) as path: + df.to_hdf(path, 'df', format='table') + reread = read_hdf(path, 'df') + assert_frame_equal(df, reread) + + df = DataFrame(np.random.rand(4, 5).astype(np.complex128), + index=list('abcd'), + columns=list('ABCDE')) + + with ensure_clean_path(self.path) as path: + df.to_hdf(path, 'df', format='table', mode='w') + reread = read_hdf(path, 'df') + assert_frame_equal(df, reread) + + def test_complex_mixed_fixed(self): + complex64 = np.array([1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j], dtype=np.complex64) + complex128 = np.array([1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j], + dtype=np.complex128) + df = DataFrame({'A': [1, 2, 3, 4], + 'B': ['a', 'b', 'c', 'd'], + 'C': complex64, + 'D': complex128, + 'E': [1.0, 2.0, 3.0, 4.0]}, + index=list('abcd')) + with ensure_clean_path(self.path) as path: + df.to_hdf(path, 'df') + reread = read_hdf(path, 'df') + assert_frame_equal(df, reread) + + def test_complex_mixed_table(self): + complex64 = np.array([1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j], dtype=np.complex64) + complex128 = np.array([1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j], + dtype=np.complex128) + df = DataFrame({'A': [1, 2, 3, 4], + 'B': ['a', 'b', 'c', 'd'], + 'C': complex64, + 'D': complex128, + 'E': [1.0, 2.0, 3.0, 4.0]}, + index=list('abcd')) + + with ensure_clean_store(self.path) as store: + store.append('df', df, data_columns=['A', 'B']) + result = store.select('df', where=Term('A>2')) + assert_frame_equal(df.loc[df.A > 2], result) + + with ensure_clean_path(self.path) as path: + df.to_hdf(path, 'df', format='table') + reread = read_hdf(path, 'df') + assert_frame_equal(df, reread) + + def test_complex_across_dimensions_fixed(self): + complex128 = np.array([1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j]) + s = Series(complex128, index=list('abcd')) + df = DataFrame({'A': s, 'B': s}) + p = Panel({'One': df, 'Two': df}) + + objs = [s, df, p] + comps = [tm.assert_series_equal, tm.assert_frame_equal, + tm.assert_panel_equal] + for obj, comp in zip(objs, comps): + with ensure_clean_path(self.path) as path: + obj.to_hdf(path, 'obj', format='fixed') + reread = read_hdf(path, 'obj') + comp(obj, reread) + + def test_complex_across_dimensions(self): + complex128 = np.array([1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j]) + s = Series(complex128, index=list('abcd')) + df = DataFrame({'A': s, 'B': s}) + p = Panel({'One': df, 'Two': df}) + p4d = pd.Panel4D({'i': p, 'ii': p}) + + objs = [df, p, p4d] + comps = [tm.assert_frame_equal, tm.assert_panel_equal, + tm.assert_panel4d_equal] + for obj, comp in zip(objs, comps): + with ensure_clean_path(self.path) as path: + obj.to_hdf(path, 'obj', format='table') + reread = read_hdf(path, 'obj') + comp(obj, reread) + + def test_complex_indexing_error(self): + complex128 = np.array([1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j], + dtype=np.complex128) + df = DataFrame({'A': [1, 2, 3, 4], + 'B': ['a', 'b', 'c', 'd'], + 'C': complex128}, + index=list('abcd')) + with ensure_clean_store(self.path) as store: + self.assertRaises(TypeError, store.append, 'df', df, data_columns=['C']) + + def test_complex_series_error(self): + complex128 = np.array([1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j]) + s = Series(complex128, index=list('abcd')) + + with ensure_clean_path(self.path) as path: + self.assertRaises(TypeError, s.to_hdf, path, 'obj', format='t') + + with ensure_clean_path(self.path) as path: + s.to_hdf(path, 'obj', format='t', index=False) + reread = read_hdf(path, 'obj') + tm.assert_series_equal(s, reread) + + def test_complex_append(self): + df = DataFrame({'a': np.random.randn(100).astype(np.complex128), + 'b': np.random.randn(100)}) + + with ensure_clean_store(self.path) as store: + store.append('df', df, data_columns=['b']) + store.append('df', df) + result = store.select('df') + assert_frame_equal(pd.concat([df, df], 0), result) def _test_sort(obj): if isinstance(obj, DataFrame): diff --git a/pandas/io/tests/test_sas.py b/pandas/io/tests/test_sas.py new file mode 100644 index 0000000000000..0e08252fdce97 --- /dev/null +++ b/pandas/io/tests/test_sas.py @@ -0,0 +1,112 @@ +import pandas as pd +import pandas.util.testing as tm +from pandas import compat +from pandas.io.sas import XportReader, read_sas +import numpy as np +import os + +# CSV versions of test XPT files were obtained using the R foreign library + +# Numbers in a SAS xport file are always float64, so need to convert +# before making comparisons. +def numeric_as_float(data): + for v in data.columns: + if data[v].dtype is np.dtype('int64'): + data[v] = data[v].astype(np.float64) + + +class TestXport(tm.TestCase): + + def setUp(self): + self.dirpath = tm.get_data_path() + self.file01 = os.path.join(self.dirpath, "DEMO_G.XPT") + self.file02 = os.path.join(self.dirpath, "SSHSV1_A.XPT") + self.file03 = os.path.join(self.dirpath, "DRXFCD_G.XPT") + + + def test1(self): + # Tests with DEMO_G.XPT (all numeric file) + + # Compare to this + data_csv = pd.read_csv(self.file01.replace(".XPT", ".csv")) + numeric_as_float(data_csv) + + # Read full file + data = XportReader(self.file01).read() + tm.assert_frame_equal(data, data_csv) + + # Test incremental read with `read` method. + reader = XportReader(self.file01) + data = reader.read(10) + tm.assert_frame_equal(data, data_csv.iloc[0:10, :]) + + # Test incremental read with `get_chunk` method. + reader = XportReader(self.file01, chunksize=10) + data = reader.get_chunk() + tm.assert_frame_equal(data, data_csv.iloc[0:10, :]) + + # Read full file with `read_sas` method + data = read_sas(self.file01) + tm.assert_frame_equal(data, data_csv) + + + def test1_index(self): + # Tests with DEMO_G.XPT using index (all numeric file) + + # Compare to this + data_csv = pd.read_csv(self.file01.replace(".XPT", ".csv")) + data_csv = data_csv.set_index("SEQN") + numeric_as_float(data_csv) + + # Read full file + data = XportReader(self.file01, index="SEQN").read() + tm.assert_frame_equal(data, data_csv) + + # Test incremental read with `read` method. + reader = XportReader(self.file01, index="SEQN") + data = reader.read(10) + tm.assert_frame_equal(data, data_csv.iloc[0:10, :]) + + # Test incremental read with `get_chunk` method. + reader = XportReader(self.file01, index="SEQN", chunksize=10) + data = reader.get_chunk() + tm.assert_frame_equal(data, data_csv.iloc[0:10, :]) + + + def test1_incremental(self): + # Test with DEMO_G.XPT, reading full file incrementally + + data_csv = pd.read_csv(self.file01.replace(".XPT", ".csv")) + data_csv = data_csv.set_index("SEQN") + numeric_as_float(data_csv) + + reader = XportReader(self.file01, index="SEQN", chunksize=1000) + + all_data = [x for x in reader] + data = pd.concat(all_data, axis=0) + + tm.assert_frame_equal(data, data_csv) + + + def test2(self): + # Test with SSHSV1_A.XPT + + # Compare to this + data_csv = pd.read_csv(self.file02.replace(".XPT", ".csv")) + numeric_as_float(data_csv) + + data = XportReader(self.file02).read() + tm.assert_frame_equal(data, data_csv) + + + def test3(self): + # Test with DRXFCD_G.XPT (contains text and numeric variables) + + # Compare to this + data_csv = pd.read_csv(self.file03.replace(".XPT", ".csv")) + + data = XportReader(self.file03).read() + tm.assert_frame_equal(data, data_csv) + + data = read_sas(self.file03) + tm.assert_frame_equal(data, data_csv) diff --git a/pandas/io/tests/test_sql.py b/pandas/io/tests/test_sql.py index 33ea63ba41f1f..619de8d6bad3b 100644 --- a/pandas/io/tests/test_sql.py +++ b/pandas/io/tests/test_sql.py @@ -9,7 +9,8 @@ - `TestSQLiteFallbackApi`: test the public API with a sqlite DBAPI connection - Tests for the different SQL flavors (flavor specific type conversions) - Tests for the sqlalchemy mode: `_TestSQLAlchemy` is the base class with - common methods, the different tested flavors (sqlite3, MySQL, PostgreSQL) + common methods, `_TestSQLAlchemyConn` tests the API with a SQLAlchemy + Connection object. The different tested flavors (sqlite3, MySQL, PostgreSQL) derive from the base class - Tests for the fallback mode (`TestSQLiteFallback` and `TestMySQLLegacy`) @@ -43,6 +44,8 @@ import sqlalchemy import sqlalchemy.schema import sqlalchemy.sql.sqltypes as sqltypes + from sqlalchemy.ext import declarative + from sqlalchemy.orm import session as sa_session SQLALCHEMY_INSTALLED = True except ImportError: SQLALCHEMY_INSTALLED = False @@ -158,19 +161,74 @@ SELECT * FROM iris WHERE "Name"=%(name)s AND "SepalLength"=%(length)s """ + }, + 'create_view': { + 'sqlite': """ + CREATE VIEW iris_view AS + SELECT * FROM iris + """ } } +class MixInBase(object): + def tearDown(self): + for tbl in self._get_all_tables(): + self.drop_table(tbl) + self._close_conn() + + +class MySQLMixIn(MixInBase): + def drop_table(self, table_name): + cur = self.conn.cursor() + cur.execute("DROP TABLE IF EXISTS %s" % sql._get_valid_mysql_name(table_name)) + self.conn.commit() + + def _get_all_tables(self): + cur = self.conn.cursor() + cur.execute('SHOW TABLES') + return [table[0] for table in cur.fetchall()] + + def _close_conn(self): + from pymysql.err import Error + try: + self.conn.close() + except Error: + pass + + +class SQLiteMixIn(MixInBase): + def drop_table(self, table_name): + self.conn.execute("DROP TABLE IF EXISTS %s" % sql._get_valid_sqlite_name(table_name)) + self.conn.commit() + + def _get_all_tables(self): + c = self.conn.execute("SELECT name FROM sqlite_master WHERE type='table'") + return [table[0] for table in c.fetchall()] + + def _close_conn(self): + self.conn.close() + + +class SQLAlchemyMixIn(MixInBase): + def drop_table(self, table_name): + sql.SQLDatabase(self.conn).drop_table(table_name) + + def _get_all_tables(self): + meta = sqlalchemy.schema.MetaData(bind=self.conn) + meta.reflect() + table_list = meta.tables.keys() + return table_list + + def _close_conn(self): + pass + class PandasSQLTest(unittest.TestCase): """ Base class with common private methods for SQLAlchemy and fallback cases. """ - def drop_table(self, table_name): - self._get_exec().execute("DROP TABLE IF EXISTS %s" % table_name) - def _get_exec(self): if hasattr(self.conn, 'execute'): return self.conn @@ -192,6 +250,10 @@ def _load_iris_data(self): for row in r: self._get_exec().execute(ins, row) + def _load_iris_view(self): + self.drop_table('iris_view') + self._get_exec().execute(SQL_STRINGS['create_view'][self.flavor]) + def _check_iris_loaded_frame(self, iris_frame): pytype = iris_frame.dtypes[0].type row = iris_frame.iloc[0] @@ -430,6 +492,7 @@ class _TestSQLApi(PandasSQLTest): def setUp(self): self.conn = self.connect() self._load_iris_data() + self._load_iris_view() self._load_test1_data() self._load_test2_data() self._load_test3_data() @@ -440,6 +503,11 @@ def test_read_sql_iris(self): "SELECT * FROM iris", self.conn) self._check_iris_loaded_frame(iris_frame) + def test_read_sql_view(self): + iris_frame = sql.read_sql_query( + "SELECT * FROM iris_view", self.conn) + self._check_iris_loaded_frame(iris_frame) + def test_legacy_read_frame(self): with tm.assert_produces_warning(FutureWarning): iris_frame = sql.read_frame( @@ -703,6 +771,19 @@ def test_get_schema_dtypes(self): self.assertTrue('CREATE' in create_sql) self.assertTrue('INTEGER' in create_sql) + def test_get_schema_keys(self): + frame = DataFrame({'Col1':[1.1,1.2], 'Col2':[2.1,2.2]}) + create_sql = sql.get_schema(frame, 'test', 'sqlite', + con=self.conn, keys='Col1') + constraint_sentence = 'CONSTRAINT test_pk PRIMARY KEY ("Col1")' + self.assertTrue(constraint_sentence in create_sql) + + # multiple columns as key (GH10385) + create_sql = sql.get_schema(self.test_frame1, 'test', 'sqlite', + con=self.conn, keys=['A', 'B']) + constraint_sentence = 'CONSTRAINT test_pk PRIMARY KEY ("A", "B")' + self.assertTrue(constraint_sentence in create_sql) + def test_chunksize_read(self): df = DataFrame(np.random.randn(22, 5), columns=list('abcde')) df.to_sql('test_chunksize', self.conn, index=False) @@ -752,7 +833,7 @@ def test_categorical(self): tm.assert_frame_equal(res, df) -class TestSQLApi(_TestSQLApi): +class TestSQLApi(SQLAlchemyMixIn, _TestSQLApi): """ Test the public API as it would be used directly @@ -853,8 +934,51 @@ def test_sqlalchemy_type_mapping(self): table = sql.SQLTable("test_type", db, frame=df) self.assertTrue(isinstance(table.table.c['time'].type, sqltypes.DateTime)) + def test_to_sql_read_sql_with_database_uri(self): -class TestSQLiteFallbackApi(_TestSQLApi): + # Test read_sql and .to_sql method with a database URI (GH10654) + test_frame1 = self.test_frame1 + #db_uri = 'sqlite:///:memory:' # raises sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) near "iris": syntax error [SQL: 'iris'] + with tm.ensure_clean() as name: + db_uri = 'sqlite:///' + name + table = 'iris' + test_frame1.to_sql(table, db_uri, if_exists='replace', index=False) + test_frame2 = sql.read_sql(table, db_uri) + test_frame3 = sql.read_sql_table(table, db_uri) + query = 'SELECT * FROM iris' + test_frame4 = sql.read_sql_query(query, db_uri) + tm.assert_frame_equal(test_frame1, test_frame2) + tm.assert_frame_equal(test_frame1, test_frame3) + tm.assert_frame_equal(test_frame1, test_frame4) + + +class _EngineToConnMixin(object): + """ + A mixin that causes setup_connect to create a conn rather than an engine. + """ + + def setUp(self): + super(_EngineToConnMixin, self).setUp() + engine = self.conn + conn = engine.connect() + self.__tx = conn.begin() + self.pandasSQL = sql.SQLDatabase(conn) + self.__engine = engine + self.conn = conn + + def tearDown(self): + self.__tx.rollback() + self.conn.close() + self.conn = self.__engine + self.pandasSQL = sql.SQLDatabase(self.__engine) + super(_EngineToConnMixin, self).tearDown() + + +class TestSQLApiConn(_EngineToConnMixin, TestSQLApi): + pass + + +class TestSQLiteFallbackApi(SQLiteMixIn, _TestSQLApi): """ Test the public sqlite connection fallback API @@ -937,7 +1061,7 @@ def test_sqlite_type_mapping(self): #--- Database flavor specific tests -class _TestSQLAlchemy(PandasSQLTest): +class _TestSQLAlchemy(SQLAlchemyMixIn, PandasSQLTest): """ Base class for testing the sqlalchemy backend. @@ -990,9 +1114,6 @@ def setup_connect(self): except sqlalchemy.exc.OperationalError: raise nose.SkipTest("Can't connect to {0} server".format(self.flavor)) - def tearDown(self): - raise NotImplementedError() - def test_aread_sql(self): self._read_sql_iris() @@ -1166,7 +1287,7 @@ def test_datetime_NaT(self): result = sql.read_sql_query('SELECT * FROM test_datetime', self.conn) if self.flavor == 'sqlite': self.assertTrue(isinstance(result.loc[0, 'A'], string_types)) - result['A'] = to_datetime(result['A'], coerce=True) + result['A'] = to_datetime(result['A'], errors='coerce') tm.assert_frame_equal(result, df) else: tm.assert_frame_equal(result, df) @@ -1346,9 +1467,58 @@ def test_double_precision(self): self.assertTrue(isinstance(col_dict['i32'].type, sqltypes.Integer)) self.assertTrue(isinstance(col_dict['i64'].type, sqltypes.BigInteger)) + def test_connectable_issue_example(self): + # This tests the example raised in issue + # https://github.com/pydata/pandas/issues/10104 + + def foo(connection): + query = 'SELECT test_foo_data FROM test_foo_data' + return sql.read_sql_query(query, con=connection) + + def bar(connection, data): + data.to_sql(name='test_foo_data', con=connection, if_exists='append') + + def main(connectable): + with connectable.connect() as conn: + with conn.begin(): + foo_data = conn.run_callable(foo) + conn.run_callable(bar, foo_data) + + DataFrame({'test_foo_data': [0, 1, 2]}).to_sql('test_foo_data', self.conn) + main(self.conn) + + def test_temporary_table(self): + test_data = u'Hello, World!' + expected = DataFrame({'spam': [test_data]}) + Base = declarative.declarative_base() + + class Temporary(Base): + __tablename__ = 'temp_test' + __table_args__ = {'prefixes': ['TEMPORARY']} + id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True) + spam = sqlalchemy.Column(sqlalchemy.Unicode(30), nullable=False) + + Session = sa_session.sessionmaker(bind=self.conn) + session = Session() + with session.transaction: + conn = session.connection() + Temporary.__table__.create(conn) + session.add(Temporary(spam=test_data)) + session.flush() + df = sql.read_sql_query( + sql=sqlalchemy.select([Temporary.spam]), + con=conn, + ) + + tm.assert_frame_equal(df, expected) -class TestSQLiteAlchemy(_TestSQLAlchemy): +class _TestSQLAlchemyConn(_EngineToConnMixin, _TestSQLAlchemy): + def test_transactions(self): + raise nose.SkipTest("Nested transactions rollbacks don't work with Pandas") + + +class _TestSQLiteAlchemy(object): """ Test the sqlalchemy backend against an in-memory sqlite database. @@ -1364,10 +1534,6 @@ def setup_driver(cls): # sqlite3 is built-in cls.driver = None - def tearDown(self): - # in memory so tables should not be removed explicitly - pass - def test_default_type_conversion(self): df = sql.read_sql_table("types_test_data", self.conn) @@ -1404,7 +1570,7 @@ def test_bigint_warning(self): self.assertEqual(len(w), 0, "Warning triggered for other table") -class TestMySQLAlchemy(_TestSQLAlchemy): +class _TestMySQLAlchemy(object): """ Test the sqlalchemy backend against an MySQL database. @@ -1424,11 +1590,6 @@ def setup_driver(cls): except ImportError: raise nose.SkipTest('pymysql not installed') - def tearDown(self): - c = self.conn.execute('SHOW TABLES') - for table in c.fetchall(): - self.conn.execute('DROP TABLE %s' % table[0]) - def test_default_type_conversion(self): df = sql.read_sql_table("types_test_data", self.conn) @@ -1478,7 +1639,7 @@ def test_read_procedure(self): tm.assert_frame_equal(df, res2) -class TestPostgreSQLAlchemy(_TestSQLAlchemy): +class _TestPostgreSQLAlchemy(object): """ Test the sqlalchemy backend against an PostgreSQL database. @@ -1498,13 +1659,6 @@ def setup_driver(cls): except ImportError: raise nose.SkipTest('psycopg2 not installed') - def tearDown(self): - c = self.conn.execute( - "SELECT table_name FROM information_schema.tables" - " WHERE table_schema = 'public'") - for table in c.fetchall(): - self.conn.execute("DROP TABLE %s" % table[0]) - def test_schema_support(self): # only test this for postgresql (schema's not supported in mysql/sqlite) df = DataFrame({'col1':[1, 2], 'col2':[0.1, 0.2], 'col3':['a', 'n']}) @@ -1550,15 +1704,18 @@ def test_schema_support(self): ## specifying schema in user-provided meta - engine2 = self.connect() - meta = sqlalchemy.MetaData(engine2, schema='other') - pdsql = sql.SQLDatabase(engine2, meta=meta) - pdsql.to_sql(df, 'test_schema_other2', index=False) - pdsql.to_sql(df, 'test_schema_other2', index=False, if_exists='replace') - pdsql.to_sql(df, 'test_schema_other2', index=False, if_exists='append') - res1 = sql.read_sql_table('test_schema_other2', self.conn, schema='other') - res2 = pdsql.read_table('test_schema_other2') - tm.assert_frame_equal(res1, res2) + # The schema won't be applied on another Connection + # because of transactional schemas + if isinstance(self.conn, sqlalchemy.engine.Engine): + engine2 = self.connect() + meta = sqlalchemy.MetaData(engine2, schema='other') + pdsql = sql.SQLDatabase(engine2, meta=meta) + pdsql.to_sql(df, 'test_schema_other2', index=False) + pdsql.to_sql(df, 'test_schema_other2', index=False, if_exists='replace') + pdsql.to_sql(df, 'test_schema_other2', index=False, if_exists='append') + res1 = sql.read_sql_table('test_schema_other2', self.conn, schema='other') + res2 = pdsql.read_table('test_schema_other2') + tm.assert_frame_equal(res1, res2) def test_datetime_with_time_zone(self): # Test to see if we read the date column with timezones that @@ -1574,10 +1731,35 @@ def test_datetime_with_time_zone(self): # "2000-06-01 00:00:00-07:00" should convert to "2000-06-01 07:00:00" self.assertEqual(df.DateColWithTz[1], Timestamp('2000-06-01 07:00:00')) + +class TestMySQLAlchemy(_TestMySQLAlchemy, _TestSQLAlchemy): + pass + + +class TestMySQLAlchemyConn(_TestMySQLAlchemy, _TestSQLAlchemyConn): + pass + + +class TestPostgreSQLAlchemy(_TestPostgreSQLAlchemy, _TestSQLAlchemy): + pass + + +class TestPostgreSQLAlchemyConn(_TestPostgreSQLAlchemy, _TestSQLAlchemyConn): + pass + + +class TestSQLiteAlchemy(_TestSQLiteAlchemy, _TestSQLAlchemy): + pass + + +class TestSQLiteAlchemyConn(_TestSQLiteAlchemy, _TestSQLAlchemyConn): + pass + + #------------------------------------------------------------------------------ #--- Test Sqlite / MySQL fallback -class TestSQLiteFallback(PandasSQLTest): +class TestSQLiteFallback(SQLiteMixIn, PandasSQLTest): """ Test the fallback mode against an in-memory sqlite database. @@ -1588,11 +1770,6 @@ class TestSQLiteFallback(PandasSQLTest): def connect(cls): return sqlite3.connect(':memory:') - def drop_table(self, table_name): - cur = self.conn.cursor() - cur.execute("DROP TABLE IF EXISTS %s" % table_name) - self.conn.commit() - def setUp(self): self.conn = self.connect() self.pandasSQL = sql.SQLiteDatabase(self.conn, 'sqlite') @@ -1739,7 +1916,7 @@ def test_illegal_names(self): for ndx, weird_name in enumerate(['test_weird_name]','test_weird_name[', 'test_weird_name`','test_weird_name"', 'test_weird_name\'', '_b.test_weird_name_01-30', '"_b.test_weird_name_01-30"', - '12345','12345blah']): + '99beginswithnumber', '12345']): df.to_sql(weird_name, self.conn, flavor=self.flavor) sql.table_exists(weird_name, self.conn) @@ -1749,7 +1926,7 @@ def test_illegal_names(self): sql.table_exists(c_tbl, self.conn) -class TestMySQLLegacy(TestSQLiteFallback): +class TestMySQLLegacy(MySQLMixIn, TestSQLiteFallback): """ Test the legacy mode against a MySQL database. @@ -1778,11 +1955,6 @@ def setup_driver(cls): def connect(cls): return cls.driver.connect(host='127.0.0.1', user='root', passwd='', db='pandas_nosetest') - def drop_table(self, table_name): - cur = self.conn.cursor() - cur.execute("DROP TABLE IF EXISTS %s" % table_name) - self.conn.commit() - def _count_rows(self, table_name): cur = self._get_exec() cur.execute( @@ -1801,14 +1973,6 @@ def setUp(self): self._load_iris_data() self._load_test1_data() - def tearDown(self): - c = self.conn.cursor() - c.execute('SHOW TABLES') - for table in c.fetchall(): - c.execute('DROP TABLE %s' % table[0]) - self.conn.commit() - self.conn.close() - def test_a_deprecation(self): with tm.assert_produces_warning(FutureWarning): sql.to_sql(self.test_frame1, 'test_frame1', self.conn, @@ -1846,14 +2010,10 @@ def test_illegal_names(self): for ndx, ok_name in enumerate(['99beginswithnumber','12345']): df.to_sql(ok_name, self.conn, flavor=self.flavor, index=False, if_exists='replace') - self.conn.cursor().execute("DROP TABLE `%s`" % ok_name) - self.conn.commit() df2 = DataFrame([[1, 2], [3, 4]], columns=['a', ok_name]) - c_tbl = 'test_ok_col_name%d'%ndx - df2.to_sql(c_tbl, self.conn, flavor=self.flavor, index=False, - if_exists='replace') - self.conn.cursor().execute("DROP TABLE `%s`" % c_tbl) - self.conn.commit() + + df2.to_sql('test_ok_col_name', self.conn, flavor=self.flavor, index=False, + if_exists='replace') # For MySQL, these should raise ValueError for ndx, illegal_name in enumerate(['test_illegal_name]','test_illegal_name[', @@ -1862,8 +2022,7 @@ def test_illegal_names(self): flavor=self.flavor, index=False) df2 = DataFrame([[1, 2], [3, 4]], columns=['a', illegal_name]) - c_tbl = 'test_illegal_col_name%d'%ndx - self.assertRaises(ValueError, df2.to_sql, c_tbl, + self.assertRaises(ValueError, df2.to_sql, 'test_illegal_col_name%d'%ndx, self.conn, flavor=self.flavor, index=False) @@ -1905,10 +2064,10 @@ def _skip_if_no_pymysql(): raise nose.SkipTest('pymysql not installed, skipping') -class TestXSQLite(tm.TestCase): +class TestXSQLite(SQLiteMixIn, tm.TestCase): def setUp(self): - self.db = sqlite3.connect(':memory:') + self.conn = sqlite3.connect(':memory:') def test_basic(self): frame = tm.makeTimeDataFrame() @@ -1919,34 +2078,34 @@ def test_write_row_by_row(self): frame = tm.makeTimeDataFrame() frame.ix[0, 0] = np.nan create_sql = sql.get_schema(frame, 'test', 'sqlite') - cur = self.db.cursor() + cur = self.conn.cursor() cur.execute(create_sql) - cur = self.db.cursor() + cur = self.conn.cursor() ins = "INSERT INTO test VALUES (%s, %s, %s, %s)" for idx, row in frame.iterrows(): fmt_sql = format_query(ins, *row) sql.tquery(fmt_sql, cur=cur) - self.db.commit() + self.conn.commit() - result = sql.read_frame("select * from test", con=self.db) + result = sql.read_frame("select * from test", con=self.conn) result.index = frame.index tm.assert_frame_equal(result, frame) def test_execute(self): frame = tm.makeTimeDataFrame() create_sql = sql.get_schema(frame, 'test', 'sqlite') - cur = self.db.cursor() + cur = self.conn.cursor() cur.execute(create_sql) ins = "INSERT INTO test VALUES (?, ?, ?, ?)" row = frame.ix[0] - sql.execute(ins, self.db, params=tuple(row)) - self.db.commit() + sql.execute(ins, self.conn, params=tuple(row)) + self.conn.commit() - result = sql.read_frame("select * from test", self.db) + result = sql.read_frame("select * from test", self.conn) result.index = frame.index[:1] tm.assert_frame_equal(result, frame[:1]) @@ -1962,8 +2121,8 @@ def test_schema(self): frame = tm.makeTimeDataFrame() create_sql = sql.get_schema(frame, 'test', 'sqlite', keys=['A', 'B'],) lines = create_sql.splitlines() - self.assertTrue('PRIMARY KEY ("A","B")' in create_sql) - cur = self.db.cursor() + self.assertTrue('PRIMARY KEY ("A", "B")' in create_sql) + cur = self.conn.cursor() cur.execute(create_sql) def test_execute_fail(self): @@ -1976,17 +2135,17 @@ def test_execute_fail(self): PRIMARY KEY (a, b) ); """ - cur = self.db.cursor() + cur = self.conn.cursor() cur.execute(create_sql) - sql.execute('INSERT INTO test VALUES("foo", "bar", 1.234)', self.db) - sql.execute('INSERT INTO test VALUES("foo", "baz", 2.567)', self.db) + sql.execute('INSERT INTO test VALUES("foo", "bar", 1.234)', self.conn) + sql.execute('INSERT INTO test VALUES("foo", "baz", 2.567)', self.conn) try: sys.stdout = StringIO() self.assertRaises(Exception, sql.execute, 'INSERT INTO test VALUES("foo", "bar", 7)', - self.db) + self.conn) finally: sys.stdout = sys.__stdout__ @@ -2000,24 +2159,27 @@ def test_execute_closed_connection(self): PRIMARY KEY (a, b) ); """ - cur = self.db.cursor() + cur = self.conn.cursor() cur.execute(create_sql) - sql.execute('INSERT INTO test VALUES("foo", "bar", 1.234)', self.db) - self.db.close() + sql.execute('INSERT INTO test VALUES("foo", "bar", 1.234)', self.conn) + self.conn.close() try: sys.stdout = StringIO() self.assertRaises(Exception, sql.tquery, "select * from test", - con=self.db) + con=self.conn) finally: sys.stdout = sys.__stdout__ + # Initialize connection again (needed for tearDown) + self.setUp() + def test_na_roundtrip(self): pass def _check_roundtrip(self, frame): - sql.write_frame(frame, name='test_table', con=self.db) - result = sql.read_frame("select * from test_table", self.db) + sql.write_frame(frame, name='test_table', con=self.conn) + result = sql.read_frame("select * from test_table", self.conn) # HACK! Change this once indexes are handled properly. result.index = frame.index @@ -2028,8 +2190,8 @@ def _check_roundtrip(self, frame): frame['txt'] = ['a'] * len(frame) frame2 = frame.copy() frame2['Idx'] = Index(lrange(len(frame2))) + 10 - sql.write_frame(frame2, name='test_table2', con=self.db) - result = sql.read_frame("select * from test_table2", self.db, + sql.write_frame(frame2, name='test_table2', con=self.conn) + result = sql.read_frame("select * from test_table2", self.conn, index_col='Idx') expected = frame.copy() expected.index = Index(lrange(len(frame2))) + 10 @@ -2038,8 +2200,8 @@ def _check_roundtrip(self, frame): def test_tquery(self): frame = tm.makeTimeDataFrame() - sql.write_frame(frame, name='test_table', con=self.db) - result = sql.tquery("select A from test_table", self.db) + sql.write_frame(frame, name='test_table', con=self.conn) + result = sql.tquery("select A from test_table", self.conn) expected = Series(frame.A.values, frame.index) # not to have name result = Series(result, frame.index) tm.assert_series_equal(result, expected) @@ -2047,27 +2209,27 @@ def test_tquery(self): try: sys.stdout = StringIO() self.assertRaises(sql.DatabaseError, sql.tquery, - 'select * from blah', con=self.db) + 'select * from blah', con=self.conn) self.assertRaises(sql.DatabaseError, sql.tquery, - 'select * from blah', con=self.db, retry=True) + 'select * from blah', con=self.conn, retry=True) finally: sys.stdout = sys.__stdout__ def test_uquery(self): frame = tm.makeTimeDataFrame() - sql.write_frame(frame, name='test_table', con=self.db) + sql.write_frame(frame, name='test_table', con=self.conn) stmt = 'INSERT INTO test_table VALUES(2.314, -123.1, 1.234, 2.3)' - self.assertEqual(sql.uquery(stmt, con=self.db), 1) + self.assertEqual(sql.uquery(stmt, con=self.conn), 1) try: sys.stdout = StringIO() self.assertRaises(sql.DatabaseError, sql.tquery, - 'insert into blah values (1)', con=self.db) + 'insert into blah values (1)', con=self.conn) self.assertRaises(sql.DatabaseError, sql.tquery, - 'insert into blah values (1)', con=self.db, + 'insert into blah values (1)', con=self.conn, retry=True) finally: sys.stdout = sys.__stdout__ @@ -2076,16 +2238,16 @@ def test_keyword_as_column_names(self): ''' ''' df = DataFrame({'From':np.ones(5)}) - sql.write_frame(df, con = self.db, name = 'testkeywords') + sql.write_frame(df, con = self.conn, name = 'testkeywords') def test_onecolumn_of_integer(self): # GH 3628 # a column_of_integers dataframe should transfer well to sql mono_df=DataFrame([1 , 2], columns=['c0']) - sql.write_frame(mono_df, con = self.db, name = 'mono_df') + sql.write_frame(mono_df, con = self.conn, name = 'mono_df') # computing the sum via sql - con_x=self.db + con_x=self.conn the_sum=sum([my_c0[0] for my_c0 in con_x.execute("select * from mono_df")]) # it should not fail, and gives 3 ( Issue #3628 ) self.assertEqual(the_sum , 3) @@ -2104,56 +2266,53 @@ def clean_up(test_table_to_drop): Drops tables created from individual tests so no dependencies arise from sequential tests """ - if sql.table_exists(test_table_to_drop, self.db, flavor='sqlite'): - cur = self.db.cursor() - cur.execute("DROP TABLE %s" % test_table_to_drop) - cur.close() + self.drop_table(test_table_to_drop) # test if invalid value for if_exists raises appropriate error self.assertRaises(ValueError, sql.write_frame, frame=df_if_exists_1, - con=self.db, + con=self.conn, name=table_name, flavor='sqlite', if_exists='notvalidvalue') clean_up(table_name) # test if_exists='fail' - sql.write_frame(frame=df_if_exists_1, con=self.db, name=table_name, + sql.write_frame(frame=df_if_exists_1, con=self.conn, name=table_name, flavor='sqlite', if_exists='fail') self.assertRaises(ValueError, sql.write_frame, frame=df_if_exists_1, - con=self.db, + con=self.conn, name=table_name, flavor='sqlite', if_exists='fail') # test if_exists='replace' - sql.write_frame(frame=df_if_exists_1, con=self.db, name=table_name, + sql.write_frame(frame=df_if_exists_1, con=self.conn, name=table_name, flavor='sqlite', if_exists='replace') - self.assertEqual(sql.tquery(sql_select, con=self.db), + self.assertEqual(sql.tquery(sql_select, con=self.conn), [(1, 'A'), (2, 'B')]) - sql.write_frame(frame=df_if_exists_2, con=self.db, name=table_name, + sql.write_frame(frame=df_if_exists_2, con=self.conn, name=table_name, flavor='sqlite', if_exists='replace') - self.assertEqual(sql.tquery(sql_select, con=self.db), + self.assertEqual(sql.tquery(sql_select, con=self.conn), [(3, 'C'), (4, 'D'), (5, 'E')]) clean_up(table_name) # test if_exists='append' - sql.write_frame(frame=df_if_exists_1, con=self.db, name=table_name, + sql.write_frame(frame=df_if_exists_1, con=self.conn, name=table_name, flavor='sqlite', if_exists='fail') - self.assertEqual(sql.tquery(sql_select, con=self.db), + self.assertEqual(sql.tquery(sql_select, con=self.conn), [(1, 'A'), (2, 'B')]) - sql.write_frame(frame=df_if_exists_2, con=self.db, name=table_name, + sql.write_frame(frame=df_if_exists_2, con=self.conn, name=table_name, flavor='sqlite', if_exists='append') - self.assertEqual(sql.tquery(sql_select, con=self.db), + self.assertEqual(sql.tquery(sql_select, con=self.conn), [(1, 'A'), (2, 'B'), (3, 'C'), (4, 'D'), (5, 'E')]) clean_up(table_name) -class TestXMySQL(tm.TestCase): +class TestXMySQL(MySQLMixIn, tm.TestCase): @classmethod def setUpClass(cls): @@ -2190,14 +2349,14 @@ def setUp(self): try: # Try Travis defaults. # No real user should allow root access with a blank password. - self.db = pymysql.connect(host='localhost', user='root', passwd='', + self.conn = pymysql.connect(host='localhost', user='root', passwd='', db='pandas_nosetest') except: pass else: return try: - self.db = pymysql.connect(read_default_group='pandas') + self.conn = pymysql.connect(read_default_group='pandas') except pymysql.ProgrammingError as e: raise nose.SkipTest( "Create a group of connection parameters under the heading " @@ -2210,12 +2369,6 @@ def setUp(self): "[pandas] in your system's mysql default file, " "typically located at ~/.my.cnf or /etc/.my.cnf. ") - def tearDown(self): - from pymysql.err import Error - try: - self.db.close() - except Error: - pass def test_basic(self): _skip_if_no_pymysql() @@ -2229,7 +2382,7 @@ def test_write_row_by_row(self): frame.ix[0, 0] = np.nan drop_sql = "DROP TABLE IF EXISTS test" create_sql = sql.get_schema(frame, 'test', 'mysql') - cur = self.db.cursor() + cur = self.conn.cursor() cur.execute(drop_sql) cur.execute(create_sql) ins = "INSERT INTO test VALUES (%s, %s, %s, %s)" @@ -2237,9 +2390,9 @@ def test_write_row_by_row(self): fmt_sql = format_query(ins, *row) sql.tquery(fmt_sql, cur=cur) - self.db.commit() + self.conn.commit() - result = sql.read_frame("select * from test", con=self.db) + result = sql.read_frame("select * from test", con=self.conn) result.index = frame.index tm.assert_frame_equal(result, frame) @@ -2248,7 +2401,7 @@ def test_execute(self): frame = tm.makeTimeDataFrame() drop_sql = "DROP TABLE IF EXISTS test" create_sql = sql.get_schema(frame, 'test', 'mysql') - cur = self.db.cursor() + cur = self.conn.cursor() with warnings.catch_warnings(): warnings.filterwarnings("ignore", "Unknown table.*") cur.execute(drop_sql) @@ -2256,10 +2409,10 @@ def test_execute(self): ins = "INSERT INTO test VALUES (%s, %s, %s, %s)" row = frame.ix[0].values.tolist() - sql.execute(ins, self.db, params=tuple(row)) - self.db.commit() + sql.execute(ins, self.conn, params=tuple(row)) + self.conn.commit() - result = sql.read_frame("select * from test", self.db) + result = sql.read_frame("select * from test", self.conn) result.index = frame.index[:1] tm.assert_frame_equal(result, frame[:1]) @@ -2277,8 +2430,8 @@ def test_schema(self): drop_sql = "DROP TABLE IF EXISTS test" create_sql = sql.get_schema(frame, 'test', 'mysql', keys=['A', 'B'],) lines = create_sql.splitlines() - self.assertTrue('PRIMARY KEY (`A`,`B`)' in create_sql) - cur = self.db.cursor() + self.assertTrue('PRIMARY KEY (`A`, `B`)' in create_sql) + cur = self.conn.cursor() cur.execute(drop_sql) cur.execute(create_sql) @@ -2294,18 +2447,18 @@ def test_execute_fail(self): PRIMARY KEY (a(5), b(5)) ); """ - cur = self.db.cursor() + cur = self.conn.cursor() cur.execute(drop_sql) cur.execute(create_sql) - sql.execute('INSERT INTO test VALUES("foo", "bar", 1.234)', self.db) - sql.execute('INSERT INTO test VALUES("foo", "baz", 2.567)', self.db) + sql.execute('INSERT INTO test VALUES("foo", "bar", 1.234)', self.conn) + sql.execute('INSERT INTO test VALUES("foo", "baz", 2.567)', self.conn) try: sys.stdout = StringIO() self.assertRaises(Exception, sql.execute, 'INSERT INTO test VALUES("foo", "bar", 7)', - self.db) + self.conn) finally: sys.stdout = sys.__stdout__ @@ -2321,19 +2474,23 @@ def test_execute_closed_connection(self): PRIMARY KEY (a(5), b(5)) ); """ - cur = self.db.cursor() + cur = self.conn.cursor() cur.execute(drop_sql) cur.execute(create_sql) - sql.execute('INSERT INTO test VALUES("foo", "bar", 1.234)', self.db) - self.db.close() + sql.execute('INSERT INTO test VALUES("foo", "bar", 1.234)', self.conn) + self.conn.close() try: sys.stdout = StringIO() self.assertRaises(Exception, sql.tquery, "select * from test", - con=self.db) + con=self.conn) finally: sys.stdout = sys.__stdout__ + # Initialize connection again (needed for tearDown) + self.setUp() + + def test_na_roundtrip(self): _skip_if_no_pymysql() pass @@ -2341,12 +2498,12 @@ def test_na_roundtrip(self): def _check_roundtrip(self, frame): _skip_if_no_pymysql() drop_sql = "DROP TABLE IF EXISTS test_table" - cur = self.db.cursor() + cur = self.conn.cursor() with warnings.catch_warnings(): warnings.filterwarnings("ignore", "Unknown table.*") cur.execute(drop_sql) - sql.write_frame(frame, name='test_table', con=self.db, flavor='mysql') - result = sql.read_frame("select * from test_table", self.db) + sql.write_frame(frame, name='test_table', con=self.conn, flavor='mysql') + result = sql.read_frame("select * from test_table", self.conn) # HACK! Change this once indexes are handled properly. result.index = frame.index @@ -2360,12 +2517,12 @@ def _check_roundtrip(self, frame): index = Index(lrange(len(frame2))) + 10 frame2['Idx'] = index drop_sql = "DROP TABLE IF EXISTS test_table2" - cur = self.db.cursor() + cur = self.conn.cursor() with warnings.catch_warnings(): warnings.filterwarnings("ignore", "Unknown table.*") cur.execute(drop_sql) - sql.write_frame(frame2, name='test_table2', con=self.db, flavor='mysql') - result = sql.read_frame("select * from test_table2", self.db, + sql.write_frame(frame2, name='test_table2', con=self.conn, flavor='mysql') + result = sql.read_frame("select * from test_table2", self.conn, index_col='Idx') expected = frame.copy() @@ -2381,10 +2538,10 @@ def test_tquery(self): raise nose.SkipTest("no pymysql") frame = tm.makeTimeDataFrame() drop_sql = "DROP TABLE IF EXISTS test_table" - cur = self.db.cursor() + cur = self.conn.cursor() cur.execute(drop_sql) - sql.write_frame(frame, name='test_table', con=self.db, flavor='mysql') - result = sql.tquery("select A from test_table", self.db) + sql.write_frame(frame, name='test_table', con=self.conn, flavor='mysql') + result = sql.tquery("select A from test_table", self.conn) expected = Series(frame.A.values, frame.index) # not to have name result = Series(result, frame.index) tm.assert_series_equal(result, expected) @@ -2392,10 +2549,10 @@ def test_tquery(self): try: sys.stdout = StringIO() self.assertRaises(sql.DatabaseError, sql.tquery, - 'select * from blah', con=self.db) + 'select * from blah', con=self.conn) self.assertRaises(sql.DatabaseError, sql.tquery, - 'select * from blah', con=self.db, retry=True) + 'select * from blah', con=self.conn, retry=True) finally: sys.stdout = sys.__stdout__ @@ -2406,20 +2563,20 @@ def test_uquery(self): raise nose.SkipTest("no pymysql") frame = tm.makeTimeDataFrame() drop_sql = "DROP TABLE IF EXISTS test_table" - cur = self.db.cursor() + cur = self.conn.cursor() cur.execute(drop_sql) - sql.write_frame(frame, name='test_table', con=self.db, flavor='mysql') + sql.write_frame(frame, name='test_table', con=self.conn, flavor='mysql') stmt = 'INSERT INTO test_table VALUES(2.314, -123.1, 1.234, 2.3)' - self.assertEqual(sql.uquery(stmt, con=self.db), 1) + self.assertEqual(sql.uquery(stmt, con=self.conn), 1) try: sys.stdout = StringIO() self.assertRaises(sql.DatabaseError, sql.tquery, - 'insert into blah values (1)', con=self.db) + 'insert into blah values (1)', con=self.conn) self.assertRaises(sql.DatabaseError, sql.tquery, - 'insert into blah values (1)', con=self.db, + 'insert into blah values (1)', con=self.conn, retry=True) finally: sys.stdout = sys.__stdout__ @@ -2429,7 +2586,7 @@ def test_keyword_as_column_names(self): ''' _skip_if_no_pymysql() df = DataFrame({'From':np.ones(5)}) - sql.write_frame(df, con = self.db, name = 'testkeywords', + sql.write_frame(df, con = self.conn, name = 'testkeywords', if_exists='replace', flavor='mysql') def test_if_exists(self): @@ -2444,51 +2601,48 @@ def clean_up(test_table_to_drop): Drops tables created from individual tests so no dependencies arise from sequential tests """ - if sql.table_exists(test_table_to_drop, self.db, flavor='mysql'): - cur = self.db.cursor() - cur.execute("DROP TABLE %s" % test_table_to_drop) - cur.close() + self.drop_table(test_table_to_drop) # test if invalid value for if_exists raises appropriate error self.assertRaises(ValueError, sql.write_frame, frame=df_if_exists_1, - con=self.db, + con=self.conn, name=table_name, flavor='mysql', if_exists='notvalidvalue') clean_up(table_name) # test if_exists='fail' - sql.write_frame(frame=df_if_exists_1, con=self.db, name=table_name, + sql.write_frame(frame=df_if_exists_1, con=self.conn, name=table_name, flavor='mysql', if_exists='fail') self.assertRaises(ValueError, sql.write_frame, frame=df_if_exists_1, - con=self.db, + con=self.conn, name=table_name, flavor='mysql', if_exists='fail') # test if_exists='replace' - sql.write_frame(frame=df_if_exists_1, con=self.db, name=table_name, + sql.write_frame(frame=df_if_exists_1, con=self.conn, name=table_name, flavor='mysql', if_exists='replace') - self.assertEqual(sql.tquery(sql_select, con=self.db), + self.assertEqual(sql.tquery(sql_select, con=self.conn), [(1, 'A'), (2, 'B')]) - sql.write_frame(frame=df_if_exists_2, con=self.db, name=table_name, + sql.write_frame(frame=df_if_exists_2, con=self.conn, name=table_name, flavor='mysql', if_exists='replace') - self.assertEqual(sql.tquery(sql_select, con=self.db), + self.assertEqual(sql.tquery(sql_select, con=self.conn), [(3, 'C'), (4, 'D'), (5, 'E')]) clean_up(table_name) # test if_exists='append' - sql.write_frame(frame=df_if_exists_1, con=self.db, name=table_name, + sql.write_frame(frame=df_if_exists_1, con=self.conn, name=table_name, flavor='mysql', if_exists='fail') - self.assertEqual(sql.tquery(sql_select, con=self.db), + self.assertEqual(sql.tquery(sql_select, con=self.conn), [(1, 'A'), (2, 'B')]) - sql.write_frame(frame=df_if_exists_2, con=self.db, name=table_name, + sql.write_frame(frame=df_if_exists_2, con=self.conn, name=table_name, flavor='mysql', if_exists='append') - self.assertEqual(sql.tquery(sql_select, con=self.db), + self.assertEqual(sql.tquery(sql_select, con=self.conn), [(1, 'A'), (2, 'B'), (3, 'C'), (4, 'D'), (5, 'E')]) clean_up(table_name) diff --git a/pandas/io/tests/test_stata.py b/pandas/io/tests/test_stata.py index 97bbfb0edf92c..5b934bad38bd3 100644 --- a/pandas/io/tests/test_stata.py +++ b/pandas/io/tests/test_stata.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # pylint: disable=E1101 from datetime import datetime @@ -22,6 +23,7 @@ from pandas.tslib import NaT from pandas import compat + class TestStata(tm.TestCase): def setUp(self): @@ -77,6 +79,8 @@ def setUp(self): self.dta21_117 = os.path.join(self.dirpath, 'stata12_117.dta') + self.dta22_118 = os.path.join(self.dirpath, 'stata14_118.dta') + def read_dta(self, file): # Legacy default reader configuration return read_stata(file, convert_dates=True) @@ -180,9 +184,9 @@ def test_read_dta2(self): # buggy test because of the NaT comparison on certain platforms # Format 113 test fails since it does not support tc and tC formats # tm.assert_frame_equal(parsed_113, expected) - tm.assert_frame_equal(parsed_114, expected) - tm.assert_frame_equal(parsed_115, expected) - tm.assert_frame_equal(parsed_117, expected) + tm.assert_frame_equal(parsed_114, expected, check_datetimelike_compat=True) + tm.assert_frame_equal(parsed_115, expected, check_datetimelike_compat=True) + tm.assert_frame_equal(parsed_117, expected, check_datetimelike_compat=True) def test_read_dta3(self): parsed_113 = self.read_dta(self.dta3_113) @@ -244,6 +248,36 @@ def test_read_dta12(self): tm.assert_frame_equal(parsed_117, expected, check_dtype=False) + + def test_read_dta18(self): + parsed_118 = self.read_dta(self.dta22_118) + parsed_118["Bytes"] = parsed_118["Bytes"].astype('O') + expected = DataFrame.from_records( + [['Cat', 'Bogota', u'Bogotá', 1, 1.0, u'option b Ünicode', 1.0], + ['Dog', 'Boston', u'Uzunköprü', np.nan, np.nan, np.nan, np.nan], + ['Plane', 'Rome', u'Tromsø', 0, 0.0, 'option a', 0.0], + ['Potato', 'Tokyo', u'Elâzığ', -4, 4.0, 4, 4], + ['', '', '', 0, 0.3332999, 'option a', 1/3.] + ], + columns=['Things', 'Cities', 'Unicode_Cities_Strl', 'Ints', 'Floats', 'Bytes', 'Longs']) + expected["Floats"] = expected["Floats"].astype(np.float32) + for col in parsed_118.columns: + tm.assert_almost_equal(parsed_118[col], expected[col]) + + rdr = StataReader(self.dta22_118) + vl = rdr.variable_labels() + vl_expected = {u'Unicode_Cities_Strl': u'Here are some strls with Ünicode chars', + u'Longs': u'long data', + u'Things': u'Here are some things', + u'Bytes': u'byte data', + u'Ints': u'int data', + u'Cities': u'Here are some cities', + u'Floats': u'float data'} + tm.assert_dict_equal(vl, vl_expected) + + self.assertEqual(rdr.data_label, u'This is a Ünicode data label') + + def test_read_write_dta5(self): original = DataFrame([(np.nan, np.nan, np.nan, np.nan, np.nan)], columns=['float_miss', 'double_miss', 'byte_miss', @@ -383,9 +417,9 @@ def test_read_write_reread_dta14(self): expected = self.read_csv(self.csv14) cols = ['byte_', 'int_', 'long_', 'float_', 'double_'] for col in cols: - expected[col] = expected[col].convert_objects(convert_numeric=True) + expected[col] = expected[col].convert_objects(datetime=True, numeric=True) expected['float_'] = expected['float_'].astype(np.float32) - expected['date_td'] = pd.to_datetime(expected['date_td'], coerce=True) + expected['date_td'] = pd.to_datetime(expected['date_td'], errors='coerce') parsed_113 = self.read_dta(self.dta14_113) parsed_113.index.name = 'index' @@ -430,20 +464,19 @@ def test_timestamp_and_label(self): data_label = 'This is a data file.' with tm.ensure_clean() as path: original.to_stata(path, time_stamp=time_stamp, data_label=data_label) - reader = StataReader(path) - parsed_time_stamp = dt.datetime.strptime(reader.time_stamp, ('%d %b %Y %H:%M')) - assert parsed_time_stamp == time_stamp - assert reader.data_label == data_label + + with StataReader(path) as reader: + parsed_time_stamp = dt.datetime.strptime(reader.time_stamp, ('%d %b %Y %H:%M')) + assert parsed_time_stamp == time_stamp + assert reader.data_label == data_label def test_numeric_column_names(self): original = DataFrame(np.reshape(np.arange(25.0), (5, 5))) original.index.name = 'index' with tm.ensure_clean() as path: # should get a warning for that format. - with warnings.catch_warnings(record=True) as w: - tm.assert_produces_warning(original.to_stata(path), InvalidColumnName) - # should produce a single warning - tm.assert_equal(len(w), 1) + with tm.assert_produces_warning(InvalidColumnName): + original.to_stata(path) written_and_read_again = self.read_dta(path) written_and_read_again = written_and_read_again.set_index('index') @@ -495,11 +528,8 @@ def test_large_value_conversion(self): original = DataFrame({'s0': s0, 's1': s1, 's2': s2, 's3': s3}) original.index.name = 'index' with tm.ensure_clean() as path: - with warnings.catch_warnings(record=True) as w: - tm.assert_produces_warning(original.to_stata(path), - PossiblePrecisionLoss) - # should produce a single warning - tm.assert_equal(len(w), 1) + with tm.assert_produces_warning(PossiblePrecisionLoss): + original.to_stata(path) written_and_read_again = self.read_dta(path) modified = original.copy() @@ -513,10 +543,8 @@ def test_dates_invalid_column(self): original = DataFrame([datetime(2006, 11, 19, 23, 13, 20)]) original.index.name = 'index' with tm.ensure_clean() as path: - with warnings.catch_warnings(record=True) as w: - tm.assert_produces_warning(original.to_stata(path, {0: 'tc'}), - InvalidColumnName) - tm.assert_equal(len(w), 1) + with tm.assert_produces_warning(InvalidColumnName): + original.to_stata(path, {0: 'tc'}) written_and_read_again = self.read_dta(path) modified = original.copy() @@ -599,13 +627,14 @@ def test_minimal_size_col(self): original = DataFrame(s) with tm.ensure_clean() as path: original.to_stata(path, write_index=False) - sr = StataReader(path) - typlist = sr.typlist - variables = sr.varlist - formats = sr.fmtlist - for variable, fmt, typ in zip(variables, formats, typlist): - self.assertTrue(int(variable[1:]) == int(fmt[1:-1])) - self.assertTrue(int(variable[1:]) == typ) + + with StataReader(path) as sr: + typlist = sr.typlist + variables = sr.varlist + formats = sr.fmtlist + for variable, fmt, typ in zip(variables, formats, typlist): + self.assertTrue(int(variable[1:]) == int(fmt[1:-1])) + self.assertTrue(int(variable[1:]) == typ) def test_excessively_long_string(self): str_lens = (1, 244, 500) @@ -684,6 +713,7 @@ def test_big_dates(self): expected.append([NaT] * 7) columns = ['date_tc', 'date_td', 'date_tw', 'date_tm', 'date_tq', 'date_th', 'date_ty'] + # Fixes for weekly, quarterly,half,year expected[2][2] = datetime(9999,12,24) expected[2][3] = datetime(9999,12,1) @@ -696,11 +726,10 @@ def test_big_dates(self): expected[5][5] = expected[5][6] = datetime(1678,1,1) expected = DataFrame(expected, columns=columns, dtype=np.object) - parsed_115 = read_stata(self.dta18_115) parsed_117 = read_stata(self.dta18_117) - tm.assert_frame_equal(expected, parsed_115) - tm.assert_frame_equal(expected, parsed_117) + tm.assert_frame_equal(expected, parsed_115, check_datetimelike_compat=True) + tm.assert_frame_equal(expected, parsed_117, check_datetimelike_compat=True) date_conversion = dict((c, c[-2:]) for c in columns) #{c : c[-2:] for c in columns} @@ -709,7 +738,8 @@ def test_big_dates(self): expected.to_stata(path, date_conversion) written_and_read_again = self.read_dta(path) tm.assert_frame_equal(written_and_read_again.set_index('index'), - expected) + expected, + check_datetimelike_compat=True) def test_dtype_conversion(self): expected = self.read_csv(self.csv15) @@ -752,6 +782,14 @@ def test_drop_column(self): columns=columns) tm.assert_frame_equal(expected, dropped) + + # See PR 10757 + columns = ['int_', 'long_', 'byte_'] + expected = expected[columns] + reordered = read_stata(self.dta15_117, convert_dates=True, + columns=columns) + tm.assert_frame_equal(expected, reordered) + with tm.assertRaises(ValueError): columns = ['byte_', 'byte_'] read_stata(self.dta15_117, convert_dates=True, columns=columns) @@ -912,7 +950,8 @@ def test_read_chunks_117(self): warnings.simplefilter("always") parsed = read_stata(fname, convert_categoricals=convert_categoricals, convert_dates=convert_dates) - itr = read_stata(fname, iterator=True) + itr = read_stata(fname, iterator=True, convert_categoricals=convert_categoricals, + convert_dates=convert_dates) pos = 0 for j in range(5): @@ -923,12 +962,10 @@ def test_read_chunks_117(self): except StopIteration: break from_frame = parsed.iloc[pos:pos+chunksize, :] - try: - tm.assert_frame_equal(from_frame, chunk, check_dtype=False) - except AssertionError: - # datetime.datetime and pandas.tslib.Timestamp may hold - # equivalent values but fail assert_frame_equal - assert(all([x == y for x, y in zip(from_frame, chunk)])) + tm.assert_frame_equal(from_frame, + chunk, + check_dtype=False, + check_datetimelike_compat=True) pos += chunksize @@ -966,13 +1003,15 @@ def test_read_chunks_115(self): for convert_categoricals in False, True: for convert_dates in False, True: + # Read the whole file with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") parsed = read_stata(fname, convert_categoricals=convert_categoricals, convert_dates=convert_dates) - itr = read_stata(fname, iterator=True, - convert_categoricals=convert_categoricals) + # Compare to what we get when reading by chunk + itr = read_stata(fname, iterator=True, convert_dates=convert_dates, + convert_categoricals=convert_categoricals) pos = 0 for j in range(5): with warnings.catch_warnings(record=True) as w: @@ -982,12 +1021,10 @@ def test_read_chunks_115(self): except StopIteration: break from_frame = parsed.iloc[pos:pos+chunksize, :] - try: - tm.assert_frame_equal(from_frame, chunk, check_dtype=False) - except AssertionError: - # datetime.datetime and pandas.tslib.Timestamp may hold - # equivalent values but fail assert_frame_equal - assert(all([x == y for x, y in zip(from_frame, chunk)])) + tm.assert_frame_equal(from_frame, + chunk, + check_dtype=False, + check_datetimelike_compat=True) pos += chunksize @@ -1011,4 +1048,3 @@ def test_read_chunks_columns(self): if __name__ == '__main__': nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'], exit=False) - diff --git a/pandas/io/wb.py b/pandas/io/wb.py index 7a9443c4b9ac6..fba4c72a51376 100644 --- a/pandas/io/wb.py +++ b/pandas/io/wb.py @@ -155,7 +155,7 @@ def download(country=['MX', 'CA', 'US'], indicator=['NY.GDP.MKTP.CD', 'NY.GNS.IC out = reduce(lambda x, y: x.merge(y, how='outer'), data) out = out.drop('iso_code', axis=1) out = out.set_index(['country', 'year']) - out = out.convert_objects(convert_numeric=True) + out = out.convert_objects(datetime=True, numeric=True) return out else: msg = "No indicators returned data." diff --git a/pandas/lib.pyx b/pandas/lib.pyx index cc4c43494176e..07f0c89535a77 100644 --- a/pandas/lib.pyx +++ b/pandas/lib.pyx @@ -21,6 +21,7 @@ from cpython cimport (PyDict_New, PyDict_GetItem, PyDict_SetItem, PyTuple_SetItem, PyTuple_New, PyObject_SetAttrString, + PyObject_RichCompareBool, PyBytes_GET_SIZE, PyUnicode_GET_SIZE) @@ -156,6 +157,31 @@ def ismember(ndarray arr, set values): return result.view(np.bool_) +def ismember_int64(ndarray[int64_t] arr, set values): + ''' + Checks whether + + Parameters + ---------- + arr : ndarray of int64 + values : set + + Returns + ------- + ismember : ndarray (boolean dtype) + ''' + cdef: + Py_ssize_t i, n + ndarray[uint8_t] result + int64_t v + + n = len(arr) + result = np.empty(n, dtype=np.uint8) + for i in range(n): + result[i] = arr[i] in values + + return result.view(np.bool_) + #---------------------------------------------------------------------- # datetime / io related @@ -347,19 +373,19 @@ def isnullobj2d_old(ndarray[object, ndim=2] arr): result[i, j] = 1 return result.view(np.bool_) -def list_to_object_array(list obj): + +@cython.wraparound(False) +@cython.boundscheck(False) +cpdef ndarray[object] list_to_object_array(list obj): ''' - Convert list to object ndarray. Seriously can't believe I had to write this + Convert list to object ndarray. Seriously can\'t believe I had to write this function ''' cdef: - Py_ssize_t i, n - ndarray[object] arr - - n = len(obj) - arr = np.empty(n, dtype=object) + Py_ssize_t i, n = len(obj) + ndarray[object] arr = np.empty(n, dtype=object) - for i from 0 <= i < n: + for i in range(n): arr[i] = obj[i] return arr @@ -607,17 +633,42 @@ def convert_timestamps(ndarray values): return out -def maybe_indices_to_slice(ndarray[int64_t] indices): + +def maybe_indices_to_slice(ndarray[int64_t] indices, int max_len): cdef: Py_ssize_t i, n = len(indices) + int k, vstart, vlast, v + + if n == 0: + return slice(0, 0) - if not n or indices[0] < 0: + vstart = indices[0] + if vstart < 0 or max_len <= vstart: return indices - for i in range(1, n): - if indices[i] - indices[i - 1] != 1: - return indices - return slice(indices[0], indices[n - 1] + 1) + if n == 1: + return slice(vstart, vstart + 1) + + vlast = indices[n - 1] + if vlast < 0 or max_len <= vlast: + return indices + + k = indices[1] - indices[0] + if k == 0: + return indices + else: + for i in range(2, n): + v = indices[i] + if v - indices[i - 1] != k: + return indices + + if k > 0: + return slice(vstart, vlast + 1, k) + else: + if vlast == 0: + return slice(vstart, None, k) + else: + return slice(vstart, vlast - 1, k) def maybe_booleans_to_slice(ndarray[uint8_t] mask): @@ -656,6 +707,7 @@ def scalar_compare(ndarray[object] values, object val, object op): cdef: Py_ssize_t i, n = len(values) ndarray[uint8_t, cast=True] result + bint isnull_val int flag object x @@ -675,12 +727,15 @@ def scalar_compare(ndarray[object] values, object val, object op): raise ValueError('Unrecognized operator') result = np.empty(n, dtype=bool).view(np.uint8) + isnull_val = _checknull(val) if flag == cpython.Py_NE: for i in range(n): x = values[i] if _checknull(x): result[i] = True + elif isnull_val: + result[i] = True else: try: result[i] = cpython.PyObject_RichCompareBool(x, val, flag) @@ -691,6 +746,8 @@ def scalar_compare(ndarray[object] values, object val, object op): x = values[i] if _checknull(x): result[i] = False + elif isnull_val: + result[i] = False else: try: result[i] = cpython.PyObject_RichCompareBool(x, val, flag) @@ -702,33 +759,32 @@ def scalar_compare(ndarray[object] values, object val, object op): x = values[i] if _checknull(x): result[i] = False + elif isnull_val: + result[i] = False else: result[i] = cpython.PyObject_RichCompareBool(x, val, flag) return result.view(bool) + @cython.wraparound(False) @cython.boundscheck(False) -def array_equivalent_object(ndarray[object] left, ndarray[object] right): +cpdef bint array_equivalent_object(object[:] left, object[:] right): """ perform an element by element comparion on 1-d object arrays taking into account nan positions """ - cdef Py_ssize_t i, n - cdef object x, y + cdef: + Py_ssize_t i, n = left.shape[0] + object x, y - n = len(left) - for i from 0 <= i < n: + for i in range(n): x = left[i] y = right[i] # we are either not equal or both nan # I think None == None will be true here - if cpython.PyObject_RichCompareBool(x, y, cpython.Py_EQ): - continue - elif _checknull(x) and _checknull(y): - continue - else: + if not (PyObject_RichCompareBool(x, y, cpython.Py_EQ) or + _checknull(x) and _checknull(y)): return False - return True @@ -1292,35 +1348,47 @@ def fast_zip_fillna(list ndarrays, fill_value=pandas_null): return result -def duplicated(ndarray[object] values, take_last=False): + +def duplicated(ndarray[object] values, object keep='first'): cdef: Py_ssize_t i, n - set seen = set() + dict seen = dict() object row n = len(values) cdef ndarray[uint8_t] result = np.zeros(n, dtype=np.uint8) - if take_last: + if keep == 'last': for i from n > i >= 0: row = values[i] - if row in seen: result[i] = 1 else: - seen.add(row) + seen[row] = i result[i] = 0 - else: + elif keep == 'first': for i from 0 <= i < n: row = values[i] if row in seen: result[i] = 1 else: - seen.add(row) + seen[row] = i result[i] = 0 + elif keep is False: + for i from 0 <= i < n: + row = values[i] + if row in seen: + result[i] = 1 + result[seen[row]] = 1 + else: + seen[row] = i + result[i] = 0 + else: + raise ValueError('keep must be either "first", "last" or False') return result.view(np.bool_) + def generate_slices(ndarray[int64_t] labels, Py_ssize_t ngroups): cdef: Py_ssize_t i, group_size, n, start diff --git a/pandas/msgpack.pyx b/pandas/msgpack.pyx deleted file mode 100644 index 625ac55ee832c..0000000000000 --- a/pandas/msgpack.pyx +++ /dev/null @@ -1,669 +0,0 @@ -# coding: utf-8 -#cython: embedsignature=True -#cython: profile=False - -from cpython cimport * -cdef extern from "Python.h": - ctypedef char* const_char_ptr "const char*" - ctypedef char* const_void_ptr "const void*" - ctypedef struct PyObject - cdef int PyObject_AsReadBuffer(object o, const_void_ptr* buff, Py_ssize_t* buf_len) except -1 - -from libc.stdlib cimport * -from libc.string cimport * -from libc.limits cimport * - -import cython -import numpy as np -from numpy cimport * - -class UnpackException(IOError): - pass - - -class BufferFull(UnpackException): - pass - - -class OutOfData(UnpackException): - pass - - -class UnpackValueError(UnpackException, ValueError): - pass - - -class ExtraData(ValueError): - def __init__(self, unpacked, extra): - self.unpacked = unpacked - self.extra = extra - - def __str__(self): - return "unpack(b) recieved extra data." - -class PackException(IOError): - pass - -class PackValueError(PackException, ValueError): - pass - -cdef extern from "msgpack/unpack.h": - ctypedef struct msgpack_user: - bint use_list - PyObject* object_hook - bint has_pairs_hook # call object_hook with k-v pairs - PyObject* list_hook - char *encoding - char *unicode_errors - - ctypedef struct template_context: - msgpack_user user - PyObject* obj - size_t count - unsigned int ct - PyObject* key - - ctypedef int (*execute_fn)(template_context* ctx, const_char_ptr data, - size_t len, size_t* off) except? -1 - execute_fn template_construct - execute_fn template_skip - execute_fn read_array_header - execute_fn read_map_header - void template_init(template_context* ctx) - object template_data(template_context* ctx) - -cdef extern from "msgpack/pack.h": - struct msgpack_packer: - char* buf - size_t length - size_t buf_size - - int msgpack_pack_int(msgpack_packer* pk, int d) - int msgpack_pack_nil(msgpack_packer* pk) - int msgpack_pack_true(msgpack_packer* pk) - int msgpack_pack_false(msgpack_packer* pk) - int msgpack_pack_long(msgpack_packer* pk, long d) - int msgpack_pack_long_long(msgpack_packer* pk, long long d) - int msgpack_pack_unsigned_long_long(msgpack_packer* pk, unsigned long long d) - int msgpack_pack_float(msgpack_packer* pk, float d) - int msgpack_pack_double(msgpack_packer* pk, double d) - int msgpack_pack_array(msgpack_packer* pk, size_t l) - int msgpack_pack_map(msgpack_packer* pk, size_t l) - int msgpack_pack_raw(msgpack_packer* pk, size_t l) - int msgpack_pack_raw_body(msgpack_packer* pk, char* body, size_t l) - -cdef int DEFAULT_RECURSE_LIMIT=511 - - - -cdef class Packer(object): - """MessagePack Packer - - usage: - - packer = Packer() - astream.write(packer.pack(a)) - astream.write(packer.pack(b)) - - Packer's constructor has some keyword arguments: - - * *defaut* - Convert user type to builtin type that Packer supports. - See also simplejson's document. - * *encoding* - Convert unicode to bytes with this encoding. (default: 'utf-8') - * *unicode_errors* - Error handler for encoding unicode. (default: 'strict') - * *use_single_float* - Use single precision float type for float. (default: False) - * *autoreset* - Reset buffer after each pack and return its content as `bytes`. (default: True). - If set this to false, use `bytes()` to get content and `.reset()` to clear buffer. - """ - cdef msgpack_packer pk - cdef object _default - cdef object _bencoding - cdef object _berrors - cdef char *encoding - cdef char *unicode_errors - cdef bool use_float - cdef bint autoreset - - def __cinit__(self): - cdef int buf_size = 1024*1024 - self.pk.buf = malloc(buf_size); - if self.pk.buf == NULL: - raise MemoryError("Unable to allocate internal buffer.") - self.pk.buf_size = buf_size - self.pk.length = 0 - - def __init__(self, default=None, encoding='utf-8', unicode_errors='strict', - use_single_float=False, bint autoreset=1): - self.use_float = use_single_float - self.autoreset = autoreset - if default is not None: - if not PyCallable_Check(default): - raise TypeError("default must be a callable.") - self._default = default - if encoding is None: - self.encoding = NULL - self.unicode_errors = NULL - else: - if isinstance(encoding, unicode): - self._bencoding = encoding.encode('ascii') - else: - self._bencoding = encoding - self.encoding = PyBytes_AsString(self._bencoding) - if isinstance(unicode_errors, unicode): - self._berrors = unicode_errors.encode('ascii') - else: - self._berrors = unicode_errors - self.unicode_errors = PyBytes_AsString(self._berrors) - - def __dealloc__(self): - free(self.pk.buf); - - @cython.boundscheck(False) - @cython.wraparound(False) - cdef int _pack(self, object o, int nest_limit=DEFAULT_RECURSE_LIMIT) except -1: - cdef long long llval - cdef unsigned long long ullval - cdef long longval - cdef float fval - cdef double dval - cdef char* rawval - cdef int ret - cdef dict d - cdef object dtype - - cdef int n,i - - if nest_limit < 0: - raise PackValueError("recursion limit exceeded.") - - if o is None: - ret = msgpack_pack_nil(&self.pk) - elif isinstance(o, bool): - if o: - ret = msgpack_pack_true(&self.pk) - else: - ret = msgpack_pack_false(&self.pk) - elif PyLong_Check(o): - if o > 0: - ullval = o - ret = msgpack_pack_unsigned_long_long(&self.pk, ullval) - else: - llval = o - ret = msgpack_pack_long_long(&self.pk, llval) - elif PyInt_Check(o): - longval = o - ret = msgpack_pack_long(&self.pk, longval) - elif PyFloat_Check(o): - if self.use_float: - fval = o - ret = msgpack_pack_float(&self.pk, fval) - else: - dval = o - ret = msgpack_pack_double(&self.pk, dval) - elif PyBytes_Check(o): - rawval = o - ret = msgpack_pack_raw(&self.pk, len(o)) - if ret == 0: - ret = msgpack_pack_raw_body(&self.pk, rawval, len(o)) - elif PyUnicode_Check(o): - if not self.encoding: - raise TypeError("Can't encode unicode string: no encoding is specified") - o = PyUnicode_AsEncodedString(o, self.encoding, self.unicode_errors) - rawval = o - ret = msgpack_pack_raw(&self.pk, len(o)) - if ret == 0: - ret = msgpack_pack_raw_body(&self.pk, rawval, len(o)) - elif PyDict_CheckExact(o): - d = o - ret = msgpack_pack_map(&self.pk, len(d)) - if ret == 0: - for k, v in d.iteritems(): - ret = self._pack(k, nest_limit-1) - if ret != 0: break - ret = self._pack(v, nest_limit-1) - if ret != 0: break - elif PyDict_Check(o): - ret = msgpack_pack_map(&self.pk, len(o)) - if ret == 0: - for k, v in o.items(): - ret = self._pack(k, nest_limit-1) - if ret != 0: break - ret = self._pack(v, nest_limit-1) - if ret != 0: break - elif PyTuple_Check(o) or PyList_Check(o): - ret = msgpack_pack_array(&self.pk, len(o)) - if ret == 0: - for v in o: - ret = self._pack(v, nest_limit-1) - if ret != 0: break - - elif self._default: - o = self._default(o) - ret = self._pack(o, nest_limit-1) - else: - raise TypeError("can't serialize %r" % (o,)) - return ret - - cpdef pack(self, object obj): - cdef int ret - ret = self._pack(obj, DEFAULT_RECURSE_LIMIT) - if ret == -1: - raise MemoryError - elif ret: # should not happen. - raise TypeError - if self.autoreset: - buf = PyBytes_FromStringAndSize(self.pk.buf, self.pk.length) - self.pk.length = 0 - return buf - - def pack_array_header(self, size_t size): - cdef int ret = msgpack_pack_array(&self.pk, size) - if ret == -1: - raise MemoryError - elif ret: # should not happen - raise TypeError - if self.autoreset: - buf = PyBytes_FromStringAndSize(self.pk.buf, self.pk.length) - self.pk.length = 0 - return buf - - def pack_map_header(self, size_t size): - cdef int ret = msgpack_pack_map(&self.pk, size) - if ret == -1: - raise MemoryError - elif ret: # should not happen - raise TypeError - if self.autoreset: - buf = PyBytes_FromStringAndSize(self.pk.buf, self.pk.length) - self.pk.length = 0 - return buf - - def pack_map_pairs(self, object pairs): - """ - Pack *pairs* as msgpack map type. - - *pairs* should sequence of pair. - (`len(pairs)` and `for k, v in *pairs*:` should be supported.) - """ - cdef int ret = msgpack_pack_map(&self.pk, len(pairs)) - if ret == 0: - for k, v in pairs: - ret = self._pack(k) - if ret != 0: break - ret = self._pack(v) - if ret != 0: break - if ret == -1: - raise MemoryError - elif ret: # should not happen - raise TypeError - if self.autoreset: - buf = PyBytes_FromStringAndSize(self.pk.buf, self.pk.length) - self.pk.length = 0 - return buf - - def reset(self): - """Clear internal buffer.""" - self.pk.length = 0 - - def bytes(self): - """Return buffer content.""" - return PyBytes_FromStringAndSize(self.pk.buf, self.pk.length) - - - cdef inline pack_pair(self, object k, object v, int nest_limit): - ret = self._pack(k, nest_limit-1) - if ret != 0: raise PackException("cannot pack : %s" % k) - ret = self._pack(v, nest_limit-1) - if ret != 0: raise PackException("cannot pack : %s" % v) - return ret - -def pack(object o, object stream, default=None, encoding='utf-8', unicode_errors='strict'): - """ - pack an object `o` and write it to stream).""" - packer = Packer(default=default, encoding=encoding, unicode_errors=unicode_errors) - stream.write(packer.pack(o)) - -def packb(object o, default=None, encoding='utf-8', unicode_errors='strict', use_single_float=False): - """ - pack o and return packed bytes.""" - packer = Packer(default=default, encoding=encoding, unicode_errors=unicode_errors, - use_single_float=use_single_float) - return packer.pack(o) - - -cdef inline init_ctx(template_context *ctx, - object object_hook, object object_pairs_hook, object list_hook, - bint use_list, char* encoding, char* unicode_errors): - template_init(ctx) - ctx.user.use_list = use_list - ctx.user.object_hook = ctx.user.list_hook = NULL - - if object_hook is not None and object_pairs_hook is not None: - raise ValueError("object_pairs_hook and object_hook are mutually exclusive.") - - if object_hook is not None: - if not PyCallable_Check(object_hook): - raise TypeError("object_hook must be a callable.") - ctx.user.object_hook = object_hook - - if object_pairs_hook is None: - ctx.user.has_pairs_hook = False - else: - if not PyCallable_Check(object_pairs_hook): - raise TypeError("object_pairs_hook must be a callable.") - ctx.user.object_hook = object_pairs_hook - ctx.user.has_pairs_hook = True - - if list_hook is not None: - if not PyCallable_Check(list_hook): - raise TypeError("list_hook must be a callable.") - ctx.user.list_hook = list_hook - - ctx.user.encoding = encoding - ctx.user.unicode_errors = unicode_errors - -def unpackb(object packed, object object_hook=None, object list_hook=None, - bint use_list=1, encoding=None, unicode_errors="strict", - object_pairs_hook=None, - ): - """Unpack packed_bytes to object. Returns an unpacked object. - - Raises `ValueError` when `packed` contains extra bytes. - """ - cdef template_context ctx - cdef size_t off = 0 - cdef int ret - - cdef char* buf - cdef Py_ssize_t buf_len - cdef char* cenc = NULL - cdef char* cerr = NULL - - PyObject_AsReadBuffer(packed, &buf, &buf_len) - - if encoding is not None: - if isinstance(encoding, unicode): - encoding = encoding.encode('ascii') - cenc = PyBytes_AsString(encoding) - - if unicode_errors is not None: - if isinstance(unicode_errors, unicode): - unicode_errors = unicode_errors.encode('ascii') - cerr = PyBytes_AsString(unicode_errors) - - init_ctx(&ctx, object_hook, object_pairs_hook, list_hook, use_list, cenc, cerr) - ret = template_construct(&ctx, buf, buf_len, &off) - if ret == 1: - obj = template_data(&ctx) - if off < buf_len: - raise ExtraData(obj, PyBytes_FromStringAndSize(buf+off, buf_len-off)) - return obj - elif ret < 0: - raise ValueError("Unpack failed: error = %d" % (ret,)) - else: - raise UnpackValueError - - -def unpack(object stream, object object_hook=None, object list_hook=None, - bint use_list=1, encoding=None, unicode_errors="strict", - object_pairs_hook=None, - ): - """Unpack an object from `stream`. - - Raises `ValueError` when `stream` has extra bytes. - """ - return unpackb(stream.read(), use_list=use_list, - object_hook=object_hook, object_pairs_hook=object_pairs_hook, list_hook=list_hook, - encoding=encoding, unicode_errors=unicode_errors, - ) - - -cdef class Unpacker(object): - """ - Streaming unpacker. - - `file_like` is a file-like object having `.read(n)` method. - When `Unpacker` initialized with `file_like`, unpacker reads serialized data - from it and `.feed()` method is not usable. - - `read_size` is used as `file_like.read(read_size)`. - (default: min(1024**2, max_buffer_size)) - - If `use_list` is true (default), msgpack list is deserialized to Python list. - Otherwise, it is deserialized to Python tuple. - - `object_hook` is same to simplejson. If it is not None, it should be callable - and Unpacker calls it with a dict argument after deserializing a map. - - `object_pairs_hook` is same to simplejson. If it is not None, it should be callable - and Unpacker calls it with a list of key-value pairs after deserializing a map. - - `encoding` is encoding used for decoding msgpack bytes. If it is None (default), - msgpack bytes is deserialized to Python bytes. - - `unicode_errors` is used for decoding bytes. - - `max_buffer_size` limits size of data waiting unpacked. - 0 means system's INT_MAX (default). - Raises `BufferFull` exception when it is insufficient. - You shoud set this parameter when unpacking data from untrasted source. - - example of streaming deserialize from file-like object:: - - unpacker = Unpacker(file_like) - for o in unpacker: - do_something(o) - - example of streaming deserialize from socket:: - - unpacker = Unpacker() - while 1: - buf = sock.recv(1024**2) - if not buf: - break - unpacker.feed(buf) - for o in unpacker: - do_something(o) - """ - cdef template_context ctx - cdef char* buf - cdef size_t buf_size, buf_head, buf_tail - cdef object file_like - cdef object file_like_read - cdef Py_ssize_t read_size - cdef object object_hook - cdef object encoding, unicode_errors - cdef size_t max_buffer_size - - def __cinit__(self): - self.buf = NULL - - def __dealloc__(self): - free(self.buf) - self.buf = NULL - - def __init__(self, file_like=None, Py_ssize_t read_size=0, bint use_list=1, - object object_hook=None, object object_pairs_hook=None, object list_hook=None, - encoding=None, unicode_errors='strict', int max_buffer_size=0, - ): - cdef char *cenc=NULL, *cerr=NULL - - self.file_like = file_like - if file_like: - self.file_like_read = file_like.read - if not PyCallable_Check(self.file_like_read): - raise ValueError("`file_like.read` must be a callable.") - if not max_buffer_size: - max_buffer_size = INT_MAX - if read_size > max_buffer_size: - raise ValueError("read_size should be less or equal to max_buffer_size") - if not read_size: - read_size = min(max_buffer_size, 1024**2) - self.max_buffer_size = max_buffer_size - self.read_size = read_size - self.buf = malloc(read_size) - if self.buf == NULL: - raise MemoryError("Unable to allocate internal buffer.") - self.buf_size = read_size - self.buf_head = 0 - self.buf_tail = 0 - - if encoding is not None: - if isinstance(encoding, unicode): - encoding = encoding.encode('ascii') - self.encoding = encoding - cenc = PyBytes_AsString(encoding) - - if unicode_errors is not None: - if isinstance(unicode_errors, unicode): - unicode_errors = unicode_errors.encode('ascii') - self.unicode_errors = unicode_errors - cerr = PyBytes_AsString(unicode_errors) - - init_ctx(&self.ctx, object_hook, object_pairs_hook, list_hook, use_list, cenc, cerr) - - def feed(self, object next_bytes): - """Append `next_bytes` to internal buffer.""" - cdef char* buf - cdef Py_ssize_t buf_len - if self.file_like is not None: - raise TypeError( - "unpacker.feed() is not be able to use with `file_like`.") - PyObject_AsReadBuffer(next_bytes, &buf, &buf_len) - self.append_buffer(buf, buf_len) - - cdef append_buffer(self, void* _buf, Py_ssize_t _buf_len): - cdef: - char* buf = self.buf - char* new_buf - size_t head = self.buf_head - size_t tail = self.buf_tail - size_t buf_size = self.buf_size - size_t new_size - - if tail + _buf_len > buf_size: - if ((tail - head) + _buf_len) <= buf_size: - # move to front. - memmove(buf, buf + head, tail - head) - tail -= head - head = 0 - else: - # expand buffer. - new_size = (tail-head) + _buf_len - if new_size > self.max_buffer_size: - raise BufferFull - new_size = min(new_size*2, self.max_buffer_size) - new_buf = malloc(new_size) - if new_buf == NULL: - # self.buf still holds old buffer and will be freed during - # obj destruction - raise MemoryError("Unable to enlarge internal buffer.") - memcpy(new_buf, buf + head, tail - head) - free(buf) - - buf = new_buf - buf_size = new_size - tail -= head - head = 0 - - memcpy(buf + tail, (_buf), _buf_len) - self.buf = buf - self.buf_head = head - self.buf_size = buf_size - self.buf_tail = tail + _buf_len - - cdef read_from_file(self): - next_bytes = self.file_like_read( - min(self.read_size, - self.max_buffer_size - (self.buf_tail - self.buf_head) - )) - if next_bytes: - self.append_buffer(PyBytes_AsString(next_bytes), PyBytes_Size(next_bytes)) - else: - self.file_like = None - - cdef object _unpack(self, execute_fn execute, object write_bytes, bint iter=0): - cdef int ret - cdef object obj - cdef size_t prev_head - while 1: - prev_head = self.buf_head - ret = execute(&self.ctx, self.buf, self.buf_tail, &self.buf_head) - if write_bytes is not None: - write_bytes(PyBytes_FromStringAndSize(self.buf + prev_head, self.buf_head - prev_head)) - - if ret == 1: - obj = template_data(&self.ctx) - template_init(&self.ctx) - return obj - elif ret == 0: - if self.file_like is not None: - self.read_from_file() - continue - if iter: - raise StopIteration("No more data to unpack.") - else: - raise OutOfData("No more data to unpack.") - else: - raise ValueError("Unpack failed: error = %d" % (ret,)) - - def read_bytes(self, Py_ssize_t nbytes): - """read a specified number of raw bytes from the stream""" - cdef size_t nread - nread = min(self.buf_tail - self.buf_head, nbytes) - ret = PyBytes_FromStringAndSize(self.buf + self.buf_head, nread) - self.buf_head += nread - if len(ret) < nbytes and self.file_like is not None: - ret += self.file_like.read(nbytes - len(ret)) - return ret - - def unpack(self, object write_bytes=None): - """ - unpack one object - - If write_bytes is not None, it will be called with parts of the raw - message as it is unpacked. - - Raises `OutOfData` when there are no more bytes to unpack. - """ - return self._unpack(template_construct, write_bytes) - - def skip(self, object write_bytes=None): - """ - read and ignore one object, returning None - - If write_bytes is not None, it will be called with parts of the raw - message as it is unpacked. - - Raises `OutOfData` when there are no more bytes to unpack. - """ - return self._unpack(template_skip, write_bytes) - - def read_array_header(self, object write_bytes=None): - """assuming the next object is an array, return its size n, such that - the next n unpack() calls will iterate over its contents. - - Raises `OutOfData` when there are no more bytes to unpack. - """ - return self._unpack(read_array_header, write_bytes) - - def read_map_header(self, object write_bytes=None): - """assuming the next object is a map, return its size n, such that the - next n * 2 unpack() calls will iterate over its key-value pairs. - - Raises `OutOfData` when there are no more bytes to unpack. - """ - return self._unpack(read_map_header, write_bytes) - - def __iter__(self): - return self - - def __next__(self): - return self._unpack(template_construct, None, 1) - - # for debug. - #def _buf(self): - # return PyString_FromStringAndSize(self.buf, self.buf_tail) - - #def _off(self): - # return self.buf_head diff --git a/pandas/msgpack/__init__.py b/pandas/msgpack/__init__.py new file mode 100644 index 0000000000000..bf0e2853ae131 --- /dev/null +++ b/pandas/msgpack/__init__.py @@ -0,0 +1,49 @@ +# coding: utf-8 +from pandas.msgpack._version import version +from pandas.msgpack.exceptions import * + +from collections import namedtuple + + +class ExtType(namedtuple('ExtType', 'code data')): + """ExtType represents ext type in msgpack.""" + def __new__(cls, code, data): + if not isinstance(code, int): + raise TypeError("code must be int") + if not isinstance(data, bytes): + raise TypeError("data must be bytes") + if not 0 <= code <= 127: + raise ValueError("code must be 0~127") + return super(ExtType, cls).__new__(cls, code, data) + + +import os +from pandas.msgpack._packer import Packer +from pandas.msgpack._unpacker import unpack, unpackb, Unpacker + + + +def pack(o, stream, **kwargs): + """ + Pack object `o` and write it to `stream` + + See :class:`Packer` for options. + """ + packer = Packer(**kwargs) + stream.write(packer.pack(o)) + + +def packb(o, **kwargs): + """ + Pack object `o` and return packed bytes + + See :class:`Packer` for options. + """ + return Packer(**kwargs).pack(o) + +# alias for compatibility to simplejson/marshal/pickle. +load = unpack +loads = unpackb + +dump = pack +dumps = packb diff --git a/pandas/msgpack/_packer.pyx b/pandas/msgpack/_packer.pyx new file mode 100644 index 0000000000000..5004b9e8e7262 --- /dev/null +++ b/pandas/msgpack/_packer.pyx @@ -0,0 +1,294 @@ +# coding: utf-8 +#cython: embedsignature=True + +from cpython cimport * +from libc.stdlib cimport * +from libc.string cimport * +from libc.limits cimport * + +from pandas.msgpack.exceptions import PackValueError +from pandas.msgpack import ExtType + + +cdef extern from "../src/msgpack/pack.h": + struct msgpack_packer: + char* buf + size_t length + size_t buf_size + bint use_bin_type + + int msgpack_pack_int(msgpack_packer* pk, int d) + int msgpack_pack_nil(msgpack_packer* pk) + int msgpack_pack_true(msgpack_packer* pk) + int msgpack_pack_false(msgpack_packer* pk) + int msgpack_pack_long(msgpack_packer* pk, long d) + int msgpack_pack_long_long(msgpack_packer* pk, long long d) + int msgpack_pack_unsigned_long_long(msgpack_packer* pk, unsigned long long d) + int msgpack_pack_float(msgpack_packer* pk, float d) + int msgpack_pack_double(msgpack_packer* pk, double d) + int msgpack_pack_array(msgpack_packer* pk, size_t l) + int msgpack_pack_map(msgpack_packer* pk, size_t l) + int msgpack_pack_raw(msgpack_packer* pk, size_t l) + int msgpack_pack_bin(msgpack_packer* pk, size_t l) + int msgpack_pack_raw_body(msgpack_packer* pk, char* body, size_t l) + int msgpack_pack_ext(msgpack_packer* pk, char typecode, size_t l) + +cdef int DEFAULT_RECURSE_LIMIT=511 + + +cdef class Packer(object): + """ + MessagePack Packer + + usage:: + + packer = Packer() + astream.write(packer.pack(a)) + astream.write(packer.pack(b)) + + Packer's constructor has some keyword arguments: + + :param callable default: + Convert user type to builtin type that Packer supports. + See also simplejson's document. + :param str encoding: + Convert unicode to bytes with this encoding. (default: 'utf-8') + :param str unicode_errors: + Error handler for encoding unicode. (default: 'strict') + :param bool use_single_float: + Use single precision float type for float. (default: False) + :param bool autoreset: + Reset buffer after each pack and return it's content as `bytes`. (default: True). + If set this to false, use `bytes()` to get content and `.reset()` to clear buffer. + :param bool use_bin_type: + Use bin type introduced in msgpack spec 2.0 for bytes. + It also enable str8 type for unicode. + """ + cdef msgpack_packer pk + cdef object _default + cdef object _bencoding + cdef object _berrors + cdef char *encoding + cdef char *unicode_errors + cdef bool use_float + cdef bint autoreset + + def __cinit__(self): + cdef int buf_size = 1024*1024 + self.pk.buf = malloc(buf_size); + if self.pk.buf == NULL: + raise MemoryError("Unable to allocate internal buffer.") + self.pk.buf_size = buf_size + self.pk.length = 0 + + def __init__(self, default=None, encoding='utf-8', unicode_errors='strict', + use_single_float=False, bint autoreset=1, bint use_bin_type=0): + """ + """ + self.use_float = use_single_float + self.autoreset = autoreset + self.pk.use_bin_type = use_bin_type + if default is not None: + if not PyCallable_Check(default): + raise TypeError("default must be a callable.") + self._default = default + if encoding is None: + self.encoding = NULL + self.unicode_errors = NULL + else: + if isinstance(encoding, unicode): + self._bencoding = encoding.encode('ascii') + else: + self._bencoding = encoding + self.encoding = PyBytes_AsString(self._bencoding) + if isinstance(unicode_errors, unicode): + self._berrors = unicode_errors.encode('ascii') + else: + self._berrors = unicode_errors + self.unicode_errors = PyBytes_AsString(self._berrors) + + def __dealloc__(self): + free(self.pk.buf); + + cdef int _pack(self, object o, int nest_limit=DEFAULT_RECURSE_LIMIT) except -1: + cdef long long llval + cdef unsigned long long ullval + cdef long longval + cdef float fval + cdef double dval + cdef char* rawval + cdef int ret + cdef dict d + cdef size_t L + cdef int default_used = 0 + + if nest_limit < 0: + raise PackValueError("recursion limit exceeded.") + + while True: + if o is None: + ret = msgpack_pack_nil(&self.pk) + elif isinstance(o, bool): + if o: + ret = msgpack_pack_true(&self.pk) + else: + ret = msgpack_pack_false(&self.pk) + elif PyLong_Check(o): + # PyInt_Check(long) is True for Python 3. + # Sow we should test long before int. + if o > 0: + ullval = o + ret = msgpack_pack_unsigned_long_long(&self.pk, ullval) + else: + llval = o + ret = msgpack_pack_long_long(&self.pk, llval) + elif PyInt_Check(o): + longval = o + ret = msgpack_pack_long(&self.pk, longval) + elif PyFloat_Check(o): + if self.use_float: + fval = o + ret = msgpack_pack_float(&self.pk, fval) + else: + dval = o + ret = msgpack_pack_double(&self.pk, dval) + elif PyBytes_Check(o): + L = len(o) + if L > (2**32)-1: + raise ValueError("bytes is too large") + rawval = o + ret = msgpack_pack_bin(&self.pk, L) + if ret == 0: + ret = msgpack_pack_raw_body(&self.pk, rawval, L) + elif PyUnicode_Check(o): + if not self.encoding: + raise TypeError("Can't encode unicode string: no encoding is specified") + o = PyUnicode_AsEncodedString(o, self.encoding, self.unicode_errors) + L = len(o) + if L > (2**32)-1: + raise ValueError("dict is too large") + rawval = o + ret = msgpack_pack_raw(&self.pk, len(o)) + if ret == 0: + ret = msgpack_pack_raw_body(&self.pk, rawval, len(o)) + elif PyDict_CheckExact(o): + d = o + L = len(d) + if L > (2**32)-1: + raise ValueError("dict is too large") + ret = msgpack_pack_map(&self.pk, L) + if ret == 0: + for k, v in d.iteritems(): + ret = self._pack(k, nest_limit-1) + if ret != 0: break + ret = self._pack(v, nest_limit-1) + if ret != 0: break + elif PyDict_Check(o): + L = len(o) + if L > (2**32)-1: + raise ValueError("dict is too large") + ret = msgpack_pack_map(&self.pk, L) + if ret == 0: + for k, v in o.items(): + ret = self._pack(k, nest_limit-1) + if ret != 0: break + ret = self._pack(v, nest_limit-1) + if ret != 0: break + elif isinstance(o, ExtType): + # This should be before Tuple because ExtType is namedtuple. + longval = o.code + rawval = o.data + L = len(o.data) + if L > (2**32)-1: + raise ValueError("EXT data is too large") + ret = msgpack_pack_ext(&self.pk, longval, L) + ret = msgpack_pack_raw_body(&self.pk, rawval, L) + elif PyTuple_Check(o) or PyList_Check(o): + L = len(o) + if L > (2**32)-1: + raise ValueError("list is too large") + ret = msgpack_pack_array(&self.pk, L) + if ret == 0: + for v in o: + ret = self._pack(v, nest_limit-1) + if ret != 0: break + elif not default_used and self._default: + o = self._default(o) + default_used = 1 + continue + else: + raise TypeError("can't serialize %r" % (o,)) + return ret + + cpdef pack(self, object obj): + cdef int ret + ret = self._pack(obj, DEFAULT_RECURSE_LIMIT) + if ret == -1: + raise MemoryError + elif ret: # should not happen. + raise TypeError + if self.autoreset: + buf = PyBytes_FromStringAndSize(self.pk.buf, self.pk.length) + self.pk.length = 0 + return buf + + def pack_ext_type(self, typecode, data): + msgpack_pack_ext(&self.pk, typecode, len(data)) + msgpack_pack_raw_body(&self.pk, data, len(data)) + + def pack_array_header(self, size_t size): + if size > (2**32-1): + raise ValueError + cdef int ret = msgpack_pack_array(&self.pk, size) + if ret == -1: + raise MemoryError + elif ret: # should not happen + raise TypeError + if self.autoreset: + buf = PyBytes_FromStringAndSize(self.pk.buf, self.pk.length) + self.pk.length = 0 + return buf + + def pack_map_header(self, size_t size): + if size > (2**32-1): + raise ValueError + cdef int ret = msgpack_pack_map(&self.pk, size) + if ret == -1: + raise MemoryError + elif ret: # should not happen + raise TypeError + if self.autoreset: + buf = PyBytes_FromStringAndSize(self.pk.buf, self.pk.length) + self.pk.length = 0 + return buf + + def pack_map_pairs(self, object pairs): + """ + Pack *pairs* as msgpack map type. + + *pairs* should sequence of pair. + (`len(pairs)` and `for k, v in pairs:` should be supported.) + """ + cdef int ret = msgpack_pack_map(&self.pk, len(pairs)) + if ret == 0: + for k, v in pairs: + ret = self._pack(k) + if ret != 0: break + ret = self._pack(v) + if ret != 0: break + if ret == -1: + raise MemoryError + elif ret: # should not happen + raise TypeError + if self.autoreset: + buf = PyBytes_FromStringAndSize(self.pk.buf, self.pk.length) + self.pk.length = 0 + return buf + + def reset(self): + """Clear internal buffer.""" + self.pk.length = 0 + + def bytes(self): + """Return buffer content.""" + return PyBytes_FromStringAndSize(self.pk.buf, self.pk.length) diff --git a/pandas/msgpack/_unpacker.pyx b/pandas/msgpack/_unpacker.pyx new file mode 100644 index 0000000000000..f68bf3369427c --- /dev/null +++ b/pandas/msgpack/_unpacker.pyx @@ -0,0 +1,466 @@ +# coding: utf-8 +#cython: embedsignature=True + +from cpython cimport * +cdef extern from "Python.h": + ctypedef struct PyObject + cdef int PyObject_AsReadBuffer(object o, const void** buff, Py_ssize_t* buf_len) except -1 + +from libc.stdlib cimport * +from libc.string cimport * +from libc.limits cimport * + +from pandas.msgpack.exceptions import ( + BufferFull, + OutOfData, + UnpackValueError, + ExtraData, + ) +from pandas.msgpack import ExtType + + +cdef extern from "../src/msgpack/unpack.h": + ctypedef struct msgpack_user: + bint use_list + PyObject* object_hook + bint has_pairs_hook # call object_hook with k-v pairs + PyObject* list_hook + PyObject* ext_hook + char *encoding + char *unicode_errors + Py_ssize_t max_str_len + Py_ssize_t max_bin_len + Py_ssize_t max_array_len + Py_ssize_t max_map_len + Py_ssize_t max_ext_len + + ctypedef struct unpack_context: + msgpack_user user + PyObject* obj + size_t count + + ctypedef int (*execute_fn)(unpack_context* ctx, const char* data, + size_t len, size_t* off) except? -1 + execute_fn unpack_construct + execute_fn unpack_skip + execute_fn read_array_header + execute_fn read_map_header + void unpack_init(unpack_context* ctx) + object unpack_data(unpack_context* ctx) + +cdef inline init_ctx(unpack_context *ctx, + object object_hook, object object_pairs_hook, + object list_hook, object ext_hook, + bint use_list, char* encoding, char* unicode_errors, + Py_ssize_t max_str_len, Py_ssize_t max_bin_len, + Py_ssize_t max_array_len, Py_ssize_t max_map_len, + Py_ssize_t max_ext_len): + unpack_init(ctx) + ctx.user.use_list = use_list + ctx.user.object_hook = ctx.user.list_hook = NULL + ctx.user.max_str_len = max_str_len + ctx.user.max_bin_len = max_bin_len + ctx.user.max_array_len = max_array_len + ctx.user.max_map_len = max_map_len + ctx.user.max_ext_len = max_ext_len + + if object_hook is not None and object_pairs_hook is not None: + raise TypeError("object_pairs_hook and object_hook are mutually exclusive.") + + if object_hook is not None: + if not PyCallable_Check(object_hook): + raise TypeError("object_hook must be a callable.") + ctx.user.object_hook = object_hook + + if object_pairs_hook is None: + ctx.user.has_pairs_hook = False + else: + if not PyCallable_Check(object_pairs_hook): + raise TypeError("object_pairs_hook must be a callable.") + ctx.user.object_hook = object_pairs_hook + ctx.user.has_pairs_hook = True + + if list_hook is not None: + if not PyCallable_Check(list_hook): + raise TypeError("list_hook must be a callable.") + ctx.user.list_hook = list_hook + + if ext_hook is not None: + if not PyCallable_Check(ext_hook): + raise TypeError("ext_hook must be a callable.") + ctx.user.ext_hook = ext_hook + + ctx.user.encoding = encoding + ctx.user.unicode_errors = unicode_errors + +def default_read_extended_type(typecode, data): + raise NotImplementedError("Cannot decode extended type with typecode=%d" % typecode) + +def unpackb(object packed, object object_hook=None, object list_hook=None, + bint use_list=1, encoding=None, unicode_errors="strict", + object_pairs_hook=None, ext_hook=ExtType, + Py_ssize_t max_str_len=2147483647, # 2**32-1 + Py_ssize_t max_bin_len=2147483647, + Py_ssize_t max_array_len=2147483647, + Py_ssize_t max_map_len=2147483647, + Py_ssize_t max_ext_len=2147483647): + """ + Unpack packed_bytes to object. Returns an unpacked object. + + Raises `ValueError` when `packed` contains extra bytes. + + See :class:`Unpacker` for options. + """ + cdef unpack_context ctx + cdef size_t off = 0 + cdef int ret + + cdef char* buf + cdef Py_ssize_t buf_len + cdef char* cenc = NULL + cdef char* cerr = NULL + + PyObject_AsReadBuffer(packed, &buf, &buf_len) + + if encoding is not None: + if isinstance(encoding, unicode): + encoding = encoding.encode('ascii') + cenc = PyBytes_AsString(encoding) + + if unicode_errors is not None: + if isinstance(unicode_errors, unicode): + unicode_errors = unicode_errors.encode('ascii') + cerr = PyBytes_AsString(unicode_errors) + + init_ctx(&ctx, object_hook, object_pairs_hook, list_hook, ext_hook, + use_list, cenc, cerr, + max_str_len, max_bin_len, max_array_len, max_map_len, max_ext_len) + ret = unpack_construct(&ctx, buf, buf_len, &off) + if ret == 1: + obj = unpack_data(&ctx) + if off < buf_len: + raise ExtraData(obj, PyBytes_FromStringAndSize(buf+off, buf_len-off)) + return obj + else: + raise UnpackValueError("Unpack failed: error = %d" % (ret,)) + + +def unpack(object stream, object object_hook=None, object list_hook=None, + bint use_list=1, encoding=None, unicode_errors="strict", + object_pairs_hook=None, + ): + """ + Unpack an object from `stream`. + + Raises `ValueError` when `stream` has extra bytes. + + See :class:`Unpacker` for options. + """ + return unpackb(stream.read(), use_list=use_list, + object_hook=object_hook, object_pairs_hook=object_pairs_hook, list_hook=list_hook, + encoding=encoding, unicode_errors=unicode_errors, + ) + + +cdef class Unpacker(object): + """Streaming unpacker. + + arguments: + + :param file_like: + File-like object having `.read(n)` method. + If specified, unpacker reads serialized data from it and :meth:`feed()` is not usable. + + :param int read_size: + Used as `file_like.read(read_size)`. (default: `min(1024**2, max_buffer_size)`) + + :param bool use_list: + If true, unpack msgpack array to Python list. + Otherwise, unpack to Python tuple. (default: True) + + :param callable object_hook: + When specified, it should be callable. + Unpacker calls it with a dict argument after unpacking msgpack map. + (See also simplejson) + + :param callable object_pairs_hook: + When specified, it should be callable. + Unpacker calls it with a list of key-value pairs after unpacking msgpack map. + (See also simplejson) + + :param str encoding: + Encoding used for decoding msgpack raw. + If it is None (default), msgpack raw is deserialized to Python bytes. + + :param str unicode_errors: + Used for decoding msgpack raw with *encoding*. + (default: `'strict'`) + + :param int max_buffer_size: + Limits size of data waiting unpacked. 0 means system's INT_MAX (default). + Raises `BufferFull` exception when it is insufficient. + You shoud set this parameter when unpacking data from untrasted source. + + :param int max_str_len: + Limits max length of str. (default: 2**31-1) + + :param int max_bin_len: + Limits max length of bin. (default: 2**31-1) + + :param int max_array_len: + Limits max length of array. (default: 2**31-1) + + :param int max_map_len: + Limits max length of map. (default: 2**31-1) + + + example of streaming deserialize from file-like object:: + + unpacker = Unpacker(file_like) + for o in unpacker: + process(o) + + example of streaming deserialize from socket:: + + unpacker = Unpacker() + while True: + buf = sock.recv(1024**2) + if not buf: + break + unpacker.feed(buf) + for o in unpacker: + process(o) + """ + cdef unpack_context ctx + cdef char* buf + cdef size_t buf_size, buf_head, buf_tail + cdef object file_like + cdef object file_like_read + cdef Py_ssize_t read_size + # To maintain refcnt. + cdef object object_hook, object_pairs_hook, list_hook, ext_hook + cdef object encoding, unicode_errors + cdef size_t max_buffer_size + + def __cinit__(self): + self.buf = NULL + + def __dealloc__(self): + free(self.buf) + self.buf = NULL + + def __init__(self, file_like=None, Py_ssize_t read_size=0, bint use_list=1, + object object_hook=None, object object_pairs_hook=None, object list_hook=None, + encoding=None, unicode_errors='strict', int max_buffer_size=0, + object ext_hook=ExtType, + Py_ssize_t max_str_len=2147483647, # 2**32-1 + Py_ssize_t max_bin_len=2147483647, + Py_ssize_t max_array_len=2147483647, + Py_ssize_t max_map_len=2147483647, + Py_ssize_t max_ext_len=2147483647): + cdef char *cenc=NULL, + cdef char *cerr=NULL + + self.object_hook = object_hook + self.object_pairs_hook = object_pairs_hook + self.list_hook = list_hook + self.ext_hook = ext_hook + + self.file_like = file_like + if file_like: + self.file_like_read = file_like.read + if not PyCallable_Check(self.file_like_read): + raise TypeError("`file_like.read` must be a callable.") + if not max_buffer_size: + max_buffer_size = INT_MAX + if read_size > max_buffer_size: + raise ValueError("read_size should be less or equal to max_buffer_size") + if not read_size: + read_size = min(max_buffer_size, 1024**2) + self.max_buffer_size = max_buffer_size + self.read_size = read_size + self.buf = malloc(read_size) + if self.buf == NULL: + raise MemoryError("Unable to allocate internal buffer.") + self.buf_size = read_size + self.buf_head = 0 + self.buf_tail = 0 + + if encoding is not None: + if isinstance(encoding, unicode): + self.encoding = encoding.encode('ascii') + elif isinstance(encoding, bytes): + self.encoding = encoding + else: + raise TypeError("encoding should be bytes or unicode") + cenc = PyBytes_AsString(self.encoding) + + if unicode_errors is not None: + if isinstance(unicode_errors, unicode): + self.unicode_errors = unicode_errors.encode('ascii') + elif isinstance(unicode_errors, bytes): + self.unicode_errors = unicode_errors + else: + raise TypeError("unicode_errors should be bytes or unicode") + cerr = PyBytes_AsString(self.unicode_errors) + + init_ctx(&self.ctx, object_hook, object_pairs_hook, list_hook, + ext_hook, use_list, cenc, cerr, + max_str_len, max_bin_len, max_array_len, + max_map_len, max_ext_len) + + def feed(self, object next_bytes): + """Append `next_bytes` to internal buffer.""" + cdef Py_buffer pybuff + if self.file_like is not None: + raise AssertionError( + "unpacker.feed() is not be able to use with `file_like`.") + PyObject_GetBuffer(next_bytes, &pybuff, PyBUF_SIMPLE) + try: + self.append_buffer(pybuff.buf, pybuff.len) + finally: + PyBuffer_Release(&pybuff) + + cdef append_buffer(self, void* _buf, Py_ssize_t _buf_len): + cdef: + char* buf = self.buf + char* new_buf + size_t head = self.buf_head + size_t tail = self.buf_tail + size_t buf_size = self.buf_size + size_t new_size + + if tail + _buf_len > buf_size: + if ((tail - head) + _buf_len) <= buf_size: + # move to front. + memmove(buf, buf + head, tail - head) + tail -= head + head = 0 + else: + # expand buffer. + new_size = (tail-head) + _buf_len + if new_size > self.max_buffer_size: + raise BufferFull + new_size = min(new_size*2, self.max_buffer_size) + new_buf = malloc(new_size) + if new_buf == NULL: + # self.buf still holds old buffer and will be freed during + # obj destruction + raise MemoryError("Unable to enlarge internal buffer.") + memcpy(new_buf, buf + head, tail - head) + free(buf) + + buf = new_buf + buf_size = new_size + tail -= head + head = 0 + + memcpy(buf + tail, (_buf), _buf_len) + self.buf = buf + self.buf_head = head + self.buf_size = buf_size + self.buf_tail = tail + _buf_len + + cdef read_from_file(self): + next_bytes = self.file_like_read( + min(self.read_size, + self.max_buffer_size - (self.buf_tail - self.buf_head) + )) + if next_bytes: + self.append_buffer(PyBytes_AsString(next_bytes), PyBytes_Size(next_bytes)) + else: + self.file_like = None + + cdef object _unpack(self, execute_fn execute, object write_bytes, bint iter=0): + cdef int ret + cdef object obj + cdef size_t prev_head + + if self.buf_head >= self.buf_tail and self.file_like is not None: + self.read_from_file() + + while 1: + prev_head = self.buf_head + if prev_head >= self.buf_tail: + if iter: + raise StopIteration("No more data to unpack.") + else: + raise OutOfData("No more data to unpack.") + + ret = execute(&self.ctx, self.buf, self.buf_tail, &self.buf_head) + if write_bytes is not None: + write_bytes(PyBytes_FromStringAndSize(self.buf + prev_head, self.buf_head - prev_head)) + + if ret == 1: + obj = unpack_data(&self.ctx) + unpack_init(&self.ctx) + return obj + elif ret == 0: + if self.file_like is not None: + self.read_from_file() + continue + if iter: + raise StopIteration("No more data to unpack.") + else: + raise OutOfData("No more data to unpack.") + else: + raise ValueError("Unpack failed: error = %d" % (ret,)) + + def read_bytes(self, Py_ssize_t nbytes): + """Read a specified number of raw bytes from the stream""" + cdef size_t nread + nread = min(self.buf_tail - self.buf_head, nbytes) + ret = PyBytes_FromStringAndSize(self.buf + self.buf_head, nread) + self.buf_head += nread + if len(ret) < nbytes and self.file_like is not None: + ret += self.file_like.read(nbytes - len(ret)) + return ret + + def unpack(self, object write_bytes=None): + """Unpack one object + + If write_bytes is not None, it will be called with parts of the raw + message as it is unpacked. + + Raises `OutOfData` when there are no more bytes to unpack. + """ + return self._unpack(unpack_construct, write_bytes) + + def skip(self, object write_bytes=None): + """Read and ignore one object, returning None + + If write_bytes is not None, it will be called with parts of the raw + message as it is unpacked. + + Raises `OutOfData` when there are no more bytes to unpack. + """ + return self._unpack(unpack_skip, write_bytes) + + def read_array_header(self, object write_bytes=None): + """assuming the next object is an array, return its size n, such that + the next n unpack() calls will iterate over its contents. + + Raises `OutOfData` when there are no more bytes to unpack. + """ + return self._unpack(read_array_header, write_bytes) + + def read_map_header(self, object write_bytes=None): + """assuming the next object is a map, return its size n, such that the + next n * 2 unpack() calls will iterate over its key-value pairs. + + Raises `OutOfData` when there are no more bytes to unpack. + """ + return self._unpack(read_map_header, write_bytes) + + def __iter__(self): + return self + + def __next__(self): + return self._unpack(unpack_construct, None, 1) + + # for debug. + #def _buf(self): + # return PyString_FromStringAndSize(self.buf, self.buf_tail) + + #def _off(self): + # return self.buf_head diff --git a/pandas/msgpack/_version.py b/pandas/msgpack/_version.py new file mode 100644 index 0000000000000..2c1c96c0759a1 --- /dev/null +++ b/pandas/msgpack/_version.py @@ -0,0 +1 @@ +version = (0, 4, 6) diff --git a/pandas/msgpack/exceptions.py b/pandas/msgpack/exceptions.py new file mode 100644 index 0000000000000..f7678f135bd26 --- /dev/null +++ b/pandas/msgpack/exceptions.py @@ -0,0 +1,29 @@ +class UnpackException(Exception): + pass + + +class BufferFull(UnpackException): + pass + + +class OutOfData(UnpackException): + pass + + +class UnpackValueError(UnpackException, ValueError): + pass + + +class ExtraData(ValueError): + def __init__(self, unpacked, extra): + self.unpacked = unpacked + self.extra = extra + + def __str__(self): + return "unpack(b) received extra data." + +class PackException(Exception): + pass + +class PackValueError(PackException, ValueError): + pass diff --git a/pandas/parser.pyx b/pandas/parser.pyx index b28e0587264d4..5baef2e4f0225 100644 --- a/pandas/parser.pyx +++ b/pandas/parser.pyx @@ -1074,7 +1074,8 @@ cdef class TextReader: na_filter, na_hashset) if user_dtype and na_count is not None: if na_count > 0: - raise Exception('Integer column has NA values') + raise Exception("Integer column has NA values in " + "column {column}".format(column=i)) if result is not None and dtype[1:] != 'i8': result = result.astype(dtype) diff --git a/pandas/sparse/tests/test_array.py b/pandas/sparse/tests/test_array.py index 5227bb23ad616..4ffc0b98ebc71 100644 --- a/pandas/sparse/tests/test_array.py +++ b/pandas/sparse/tests/test_array.py @@ -129,19 +129,19 @@ def _check_op(op, first, second): res = op(first, second) exp = SparseArray(op(first.values, second.values), fill_value=first.fill_value) - tm.assert_isinstance(res, SparseArray) + tm.assertIsInstance(res, SparseArray) assert_almost_equal(res.values, exp.values) res2 = op(first, second.values) - tm.assert_isinstance(res2, SparseArray) + tm.assertIsInstance(res2, SparseArray) assert_sp_array_equal(res, res2) res3 = op(first.values, second) - tm.assert_isinstance(res3, SparseArray) + tm.assertIsInstance(res3, SparseArray) assert_sp_array_equal(res, res3) res4 = op(first, 4) - tm.assert_isinstance(res4, SparseArray) + tm.assertIsInstance(res4, SparseArray) # ignore this if the actual op raises (e.g. pow) try: diff --git a/pandas/sparse/tests/test_libsparse.py b/pandas/sparse/tests/test_libsparse.py index cd68d264e6bf9..7f9e61571ebfc 100644 --- a/pandas/sparse/tests/test_libsparse.py +++ b/pandas/sparse/tests/test_libsparse.py @@ -8,7 +8,7 @@ import pandas.util.testing as tm from pandas.core.sparse import SparseSeries -from pandas import DataFrame +from pandas import DataFrame, compat from pandas._sparse import IntIndex, BlockIndex import pandas._sparse as splib @@ -230,6 +230,8 @@ def _check_case(xloc, xlen, yloc, ylen, eloc, elen): _check_length_exc(xindex.to_int_index(), longer_index.to_int_index()) + if compat.is_platform_windows(): + raise nose.SkipTest("segfaults on win-64 when all tests are run") check_cases(_check_case) @@ -287,7 +289,7 @@ def _check_case(xloc, xlen, yloc, ylen, eloc, elen): # see if survive the round trip xbindex = xindex.to_int_index().to_block_index() ybindex = yindex.to_int_index().to_block_index() - tm.assert_isinstance(xbindex, BlockIndex) + tm.assertIsInstance(xbindex, BlockIndex) self.assertTrue(xbindex.equals(xindex)) self.assertTrue(ybindex.equals(yindex)) check_cases(_check_case) diff --git a/pandas/sparse/tests/test_sparse.py b/pandas/sparse/tests/test_sparse.py index b506758355228..103f3992f950a 100644 --- a/pandas/sparse/tests/test_sparse.py +++ b/pandas/sparse/tests/test_sparse.py @@ -13,7 +13,7 @@ from pandas.util.testing import (assert_almost_equal, assert_series_equal, assert_frame_equal, assert_panel_equal, assertRaisesRegexp, - assert_array_equal, assert_attr_equal) + assert_numpy_array_equal, assert_attr_equal) from numpy.testing import assert_equal from pandas import Series, DataFrame, bdate_range, Panel, MultiIndex @@ -230,9 +230,9 @@ def test_to_dense_preserve_name(self): def test_constructor(self): # test setup guys self.assertTrue(np.isnan(self.bseries.fill_value)) - tm.assert_isinstance(self.bseries.sp_index, BlockIndex) + tm.assertIsInstance(self.bseries.sp_index, BlockIndex) self.assertTrue(np.isnan(self.iseries.fill_value)) - tm.assert_isinstance(self.iseries.sp_index, IntIndex) + tm.assertIsInstance(self.iseries.sp_index, IntIndex) self.assertEqual(self.zbseries.fill_value, 0) assert_equal(self.zbseries.values.values, @@ -258,7 +258,7 @@ def _check_const(sparse, name): # Sparse time series works date_index = bdate_range('1/1/2000', periods=len(self.bseries)) s5 = SparseSeries(self.bseries, index=date_index) - tm.assert_isinstance(s5, SparseTimeSeries) + tm.assertIsInstance(s5, SparseTimeSeries) # pass Series bseries2 = SparseSeries(self.bseries.to_dense()) @@ -404,13 +404,13 @@ def test_set_value(self): def test_getitem_slice(self): idx = self.bseries.index res = self.bseries[::2] - tm.assert_isinstance(res, SparseSeries) + tm.assertIsInstance(res, SparseSeries) expected = self.bseries.reindex(idx[::2]) assert_sp_series_equal(res, expected) res = self.bseries[:5] - tm.assert_isinstance(res, SparseSeries) + tm.assertIsInstance(res, SparseSeries) assert_sp_series_equal(res, self.bseries.reindex(idx[:5])) res = self.bseries[5:] @@ -575,7 +575,7 @@ def _compare_with_series(sps, new_index): reindexed = self.bseries.reindex(self.bseries.index, copy=False) reindexed.sp_values[:] = 1. - np.testing.assert_array_equal(self.bseries.sp_values, 1.) + tm.assert_numpy_array_equal(self.bseries.sp_values, np.repeat(1., 10)) def test_sparse_reindex(self): length = 10 @@ -756,13 +756,13 @@ def test_shift(self): def test_cumsum(self): result = self.bseries.cumsum() expected = self.bseries.to_dense().cumsum() - tm.assert_isinstance(result, SparseSeries) + tm.assertIsInstance(result, SparseSeries) self.assertEqual(result.name, self.bseries.name) assert_series_equal(result.to_dense(), expected) result = self.zbseries.cumsum() expected = self.zbseries.to_dense().cumsum() - tm.assert_isinstance(result, Series) + tm.assertIsInstance(result, Series) assert_series_equal(result, expected) def test_combine_first(self): @@ -899,7 +899,7 @@ def _check_results_to_coo(results, check): (A, il, jl) = results (A_result, il_result, jl_result) = check # convert to dense and compare - assert_array_equal(A.todense(), A_result.todense()) + assert_numpy_array_equal(A.todense(), A_result.todense()) # or compare directly as difference of sparse # assert(abs(A - A_result).max() < 1e-12) # max is failing in python # 2.6 @@ -957,7 +957,7 @@ def test_as_matrix(self): def test_copy(self): cp = self.frame.copy() - tm.assert_isinstance(cp, SparseDataFrame) + tm.assertIsInstance(cp, SparseDataFrame) assert_sp_frame_equal(cp, self.frame) # as of v0.15.0 @@ -966,9 +966,9 @@ def test_copy(self): def test_constructor(self): for col, series in compat.iteritems(self.frame): - tm.assert_isinstance(series, SparseSeries) + tm.assertIsInstance(series, SparseSeries) - tm.assert_isinstance(self.iframe['A'].sp_index, IntIndex) + tm.assertIsInstance(self.iframe['A'].sp_index, IntIndex) # constructed zframe from matrix above self.assertEqual(self.zframe['A'].fill_value, 0) @@ -978,7 +978,7 @@ def test_constructor(self): # construct no data sdf = SparseDataFrame(columns=np.arange(10), index=np.arange(10)) for col, series in compat.iteritems(sdf): - tm.assert_isinstance(series, SparseSeries) + tm.assertIsInstance(series, SparseSeries) # construct from nested dict data = {} @@ -1047,9 +1047,9 @@ def test_constructor_from_series(self): # GH 2873 x = Series(np.random.randn(10000), name='a') x = x.to_sparse(fill_value=0) - tm.assert_isinstance(x, SparseSeries) + tm.assertIsInstance(x, SparseSeries) df = SparseDataFrame(x) - tm.assert_isinstance(df, SparseDataFrame) + tm.assertIsInstance(df, SparseDataFrame) x = Series(np.random.randn(10000), name='a') y = Series(np.random.randn(10000), name='b') @@ -1098,13 +1098,13 @@ def test_dense_to_sparse(self): df = DataFrame({'A': [nan, nan, nan, 1, 2], 'B': [1, 2, nan, nan, nan]}) sdf = df.to_sparse() - tm.assert_isinstance(sdf, SparseDataFrame) + tm.assertIsInstance(sdf, SparseDataFrame) self.assertTrue(np.isnan(sdf.default_fill_value)) - tm.assert_isinstance(sdf['A'].sp_index, BlockIndex) + tm.assertIsInstance(sdf['A'].sp_index, BlockIndex) tm.assert_frame_equal(sdf.to_dense(), df) sdf = df.to_sparse(kind='integer') - tm.assert_isinstance(sdf['A'].sp_index, IntIndex) + tm.assertIsInstance(sdf['A'].sp_index, IntIndex) df = DataFrame({'A': [0, 0, 0, 1, 2], 'B': [1, 2, 0, 0, 0]}, dtype=float) @@ -1172,7 +1172,7 @@ def _compare_to_dense(a, b, da, db, op): if isinstance(a, DataFrame) and isinstance(db, DataFrame): mixed_result = op(a, db) - tm.assert_isinstance(mixed_result, SparseDataFrame) + tm.assertIsInstance(mixed_result, SparseDataFrame) assert_sp_frame_equal(mixed_result, sparse_result, exact_indices=False) @@ -1220,7 +1220,7 @@ def test_op_corners(self): self.assertTrue(empty.empty) foo = self.frame + self.empty - tm.assert_isinstance(foo.index, DatetimeIndex) + tm.assertIsInstance(foo.index, DatetimeIndex) assert_frame_equal(foo, self.frame * np.nan) foo = self.empty + self.frame @@ -1240,8 +1240,10 @@ def test_getitem(self): self.assertRaises(Exception, sdf.__getitem__, ['a', 'd']) def test_icol(self): + # 10711 deprecated + # 2227 - result = self.frame.icol(0) + result = self.frame.iloc[:, 0] self.assertTrue(isinstance(result, SparseSeries)) assert_sp_series_equal(result, self.frame['A']) @@ -1249,7 +1251,7 @@ def test_icol(self): data = {'A': [0, 1]} iframe = SparseDataFrame(data, default_kind='integer') self.assertEqual(type(iframe['A'].sp_index), - type(iframe.icol(0).sp_index)) + type(iframe.iloc[:, 0].sp_index)) def test_set_value(self): @@ -1304,7 +1306,7 @@ def _check_frame(frame): # insert SparseSeries frame['E'] = frame['A'] - tm.assert_isinstance(frame['E'], SparseSeries) + tm.assertIsInstance(frame['E'], SparseSeries) assert_sp_series_equal(frame['E'], frame['A'], check_names=False) # insert SparseSeries differently-indexed @@ -1318,7 +1320,7 @@ def _check_frame(frame): # insert Series frame['F'] = frame['A'].to_dense() - tm.assert_isinstance(frame['F'], SparseSeries) + tm.assertIsInstance(frame['F'], SparseSeries) assert_sp_series_equal(frame['F'], frame['A'], check_names=False) # insert Series differently-indexed @@ -1331,7 +1333,7 @@ def _check_frame(frame): # insert ndarray frame['H'] = np.random.randn(N) - tm.assert_isinstance(frame['H'], SparseSeries) + tm.assertIsInstance(frame['H'], SparseSeries) to_sparsify = np.random.randn(N) to_sparsify[N // 2:] = frame.default_fill_value @@ -1407,7 +1409,7 @@ def test_append(self): def test_apply(self): applied = self.frame.apply(np.sqrt) - tm.assert_isinstance(applied, SparseDataFrame) + tm.assertIsInstance(applied, SparseDataFrame) assert_almost_equal(applied.values, np.sqrt(self.frame.values)) applied = self.fill_frame.apply(np.sqrt) @@ -1415,7 +1417,7 @@ def test_apply(self): # agg / broadcast broadcasted = self.frame.apply(np.sum, broadcast=True) - tm.assert_isinstance(broadcasted, SparseDataFrame) + tm.assertIsInstance(broadcasted, SparseDataFrame) assert_frame_equal(broadcasted.to_dense(), self.frame.to_dense().apply(np.sum, broadcast=True)) @@ -1443,7 +1445,7 @@ def test_apply_nonuq(self): def test_applymap(self): # just test that it works result = self.frame.applymap(lambda x: x * 2) - tm.assert_isinstance(result, SparseDataFrame) + tm.assertIsInstance(result, SparseDataFrame) def test_astype(self): self.assertRaises(Exception, self.frame.astype, np.int64) @@ -1635,7 +1637,7 @@ def test_count(self): def test_cumsum(self): result = self.frame.cumsum() expected = self.frame.to_dense().cumsum() - tm.assert_isinstance(result, SparseDataFrame) + tm.assertIsInstance(result, SparseDataFrame) assert_frame_equal(result.to_dense(), expected) def _check_all(self, check_func): @@ -1794,9 +1796,9 @@ def test_from_dict(self): def test_pickle(self): def _test_roundtrip(panel): result = self.round_trip_pickle(panel) - tm.assert_isinstance(result.items, Index) - tm.assert_isinstance(result.major_axis, Index) - tm.assert_isinstance(result.minor_axis, Index) + tm.assertIsInstance(result.items, Index) + tm.assertIsInstance(result.major_axis, Index) + tm.assertIsInstance(result.minor_axis, Index) assert_sp_panel_equal(panel, result) _test_roundtrip(self.panel) @@ -1804,7 +1806,7 @@ def _test_roundtrip(panel): def test_dense_to_sparse(self): wp = Panel.from_dict(self.data_dict) dwp = wp.to_sparse() - tm.assert_isinstance(dwp['ItemA']['A'], SparseSeries) + tm.assertIsInstance(dwp['ItemA']['A'], SparseSeries) def test_to_dense(self): dwp = self.panel.to_dense() diff --git a/pandas/src/datetime/np_datetime_strings.c b/pandas/src/datetime/np_datetime_strings.c index 44363fd930510..f7835971ed0b7 100644 --- a/pandas/src/datetime/np_datetime_strings.c +++ b/pandas/src/datetime/np_datetime_strings.c @@ -117,6 +117,7 @@ get_localtime(NPY_TIME_T *ts, struct tm *tms) return -1; } +#if 0 /* * Wraps `gmtime` functionality for multiple platforms. This * converts a time value to a time structure in UTC. @@ -161,6 +162,7 @@ get_gmtime(NPY_TIME_T *ts, struct tm *tms) "to a UTC time", func_name); return -1; } +#endif /* * Converts a datetimestruct in UTC to a datetimestruct in local time, @@ -1144,7 +1146,7 @@ make_iso_8601_datetime(pandas_datetimestruct *dts, char *outstr, int outlen, #ifdef _WIN32 tmplen = _snprintf(substr, sublen, "%04" NPY_INT64_FMT, dts->year); #else - tmplen = snprintf(substr, sublen, "%04" NPY_INT64_FMT, (long long)dts->year); + tmplen = snprintf(substr, sublen, "%04" NPY_INT64_FMT, dts->year); #endif /* If it ran out of space or there isn't space for the NULL terminator */ if (tmplen < 0 || tmplen > sublen) { diff --git a/pandas/src/generate_code.py b/pandas/src/generate_code.py index 598cdff30e4f7..29a991a9acfd3 100644 --- a/pandas/src/generate_code.py +++ b/pandas/src/generate_code.py @@ -1,12 +1,24 @@ +""" +This file generates `generated.pyx` which is then included in `../algos.pyx` +during building. To regenerate `generated.pyx`, just run: + + `python generate_code.py`. + +""" + from __future__ import print_function -# we only need to be able to run this file on 2.7 -# don't introduce a pandas/pandas.compat import -# or we get a bootstrapping problem -from StringIO import StringIO +import os +from pandas.compat import StringIO import numpy as np _int64_max = np.iinfo(np.int64).max +warning_to_new_contributors = """ +# DO NOT EDIT THIS FILE: This file was autogenerated from generate_code.py, so +# please edit that file and then run `python2 generate_code.py` to re-generate +# this file. +""" + header = """ cimport numpy as np cimport cython @@ -23,6 +35,9 @@ from cpython cimport PyFloat_Check cimport cpython +cdef extern from "numpy/npy_math.h": + double NAN "NPY_NAN" + import numpy as np isnan = np.isnan @@ -70,29 +85,31 @@ return arr.asobject else: return np.array(arr, dtype=np.object_) - """ -take_1d_template = """@cython.wraparound(False) -def take_1d_%(name)s_%(dest)s(ndarray[%(c_type_in)s] values, - ndarray[int64_t] indexer, - ndarray[%(c_type_out)s] out, +take_1d_template = """ +@cython.wraparound(False) +@cython.boundscheck(False) +def take_1d_%(name)s_%(dest)s(%(c_type_in)s[:] values, + int64_t[:] indexer, + %(c_type_out)s[:] out, fill_value=np.nan): cdef: Py_ssize_t i, n, idx %(c_type_out)s fv - n = len(indexer) + n = indexer.shape[0] fv = fill_value - for i from 0 <= i < n: - idx = indexer[i] - if idx == -1: - out[i] = fv - else: - out[i] = %(preval)svalues[idx]%(postval)s + %(nogil)s + %(tab)sfor i from 0 <= i < n: + %(tab)s idx = indexer[i] + %(tab)s if idx == -1: + %(tab)s out[i] = fv + %(tab)s else: + %(tab)s out[i] = %(preval)svalues[idx]%(postval)s """ inner_take_2d_axis0_template = """\ @@ -134,7 +151,6 @@ def take_1d_%(name)s_%(dest)s(ndarray[%(c_type_in)s] values, else: for j from 0 <= j < k: out[i, j] = %(preval)svalues[idx, j]%(postval)s - """ take_2d_axis0_template = """\ @@ -241,7 +257,6 @@ def take_2d_multi_%(name)s_%(dest)s(ndarray[%(c_type_in)s, ndim=2] values, out[i, j] = fv else: out[i, j] = %(preval)svalues[idx, idx1[j]]%(postval)s - """ @@ -332,7 +347,6 @@ def backfill_%(name)s(ndarray[%(c_type)s] old, ndarray[%(c_type)s] new, cur = prev return indexer - """ @@ -396,7 +410,6 @@ def pad_%(name)s(ndarray[%(c_type)s] old, ndarray[%(c_type)s] new, cur = next return indexer - """ pad_1d_template = """@cython.boundscheck(False) @@ -431,7 +444,6 @@ def pad_inplace_%(name)s(ndarray[%(c_type)s] values, else: fill_count = 0 val = values[i] - """ pad_2d_template = """@cython.boundscheck(False) @@ -592,12 +604,11 @@ def is_monotonic_%(name)s(ndarray[%(c_type)s] arr, bint timelike): ''' Returns ------- - is_monotonic_inc, is_monotonic_dec, is_unique + is_monotonic_inc, is_monotonic_dec ''' cdef: Py_ssize_t i, n %(c_type)s prev, cur - bint is_unique = 1 bint is_monotonic_inc = 1 bint is_monotonic_dec = 1 @@ -606,33 +617,40 @@ def is_monotonic_%(name)s(ndarray[%(c_type)s] arr, bint timelike): if n == 1: if arr[0] != arr[0] or (timelike and arr[0] == iNaT): # single value is NaN - return False, False, True + return False, False else: - return True, True, True + return True, True elif n < 2: - return True, True, True + return True, True if timelike and arr[0] == iNaT: - return False, False, None - - prev = arr[0] - for i in range(1, n): - cur = arr[i] - if timelike and cur == iNaT: - return False, False, None - if cur < prev: - is_monotonic_inc = 0 - elif cur > prev: - is_monotonic_dec = 0 - elif cur == prev: - is_unique = 0 - else: - # cur or prev is NaN - return False, False, None - if not is_monotonic_inc and not is_monotonic_dec: - return False, False, None - prev = cur - return is_monotonic_inc, is_monotonic_dec, is_unique + return False, False + + %(nogil)s + %(tab)sprev = arr[0] + %(tab)sfor i in range(1, n): + %(tab)s cur = arr[i] + %(tab)s if timelike and cur == iNaT: + %(tab)s is_monotonic_inc = 0 + %(tab)s is_monotonic_dec = 0 + %(tab)s break + %(tab)s if cur < prev: + %(tab)s is_monotonic_inc = 0 + %(tab)s elif cur > prev: + %(tab)s is_monotonic_dec = 0 + %(tab)s elif cur == prev: + %(tab)s pass # is_unique = 0 + %(tab)s else: + %(tab)s # cur or prev is NaN + %(tab)s is_monotonic_inc = 0 + %(tab)s is_monotonic_dec = 0 + %(tab)s break + %(tab)s if not is_monotonic_inc and not is_monotonic_dec: + %(tab)s is_monotonic_inc = 0 + %(tab)s is_monotonic_dec = 0 + %(tab)s break + %(tab)s prev = cur + return is_monotonic_inc, is_monotonic_dec """ map_indices_template = """@cython.wraparound(False) @@ -656,7 +674,6 @@ def is_monotonic_%(name)s(ndarray[%(c_type)s] arr, bint timelike): result[index[i]] = i return result - """ groupby_template = """@cython.wraparound(False) @@ -686,11 +703,10 @@ def groupby_%(name)s(ndarray[%(c_type)s] index, ndarray labels): result[key] = [idx] return result - """ group_last_template = """@cython.wraparound(False) -@cython.wraparound(False) +@cython.boundscheck(False) def group_last_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, ndarray[int64_t] counts, ndarray[%(c_type)s, ndim=2] values, @@ -699,7 +715,7 @@ def group_last_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, Only aggregates on axis=0 ''' cdef: - Py_ssize_t i, j, N, K, lab + Py_ssize_t i, j, N, K, lab, ncounts = len(counts) %(dest_type2)s val, count ndarray[%(dest_type2)s, ndim=2] resx ndarray[int64_t, ndim=2] nobs @@ -712,30 +728,31 @@ def group_last_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, N, K = ( values).shape - for i in range(N): - lab = labels[i] - if lab < 0: - continue + with nogil: + for i in range(N): + lab = labels[i] + if lab < 0: + continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + counts[lab] += 1 + for j in range(K): + val = values[i, j] - # not nan - if val == val: - nobs[lab, j] += 1 - resx[lab, j] = val + # not nan + if val == val: + nobs[lab, j] += 1 + resx[lab, j] = val - for i in range(len(counts)): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = %(nan_val)s - else: - out[i, j] = resx[i, j] + for i in range(ncounts): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = %(nan_val)s + else: + out[i, j] = resx[i, j] """ group_last_bin_template = """@cython.wraparound(False) -@cython.wraparound(False) +@cython.boundscheck(False) def group_last_bin_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, ndarray[int64_t] counts, ndarray[%(c_type)s, ndim=2] values, @@ -751,6 +768,8 @@ def group_last_bin_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, nobs = np.zeros_like(out) resx = np.empty_like(out) + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: @@ -758,30 +777,31 @@ def group_last_bin_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, N, K = ( values).shape - b = 0 - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 - - counts[b] += 1 - for j in range(K): - val = values[i, j] - - # not nan - if val == val: - nobs[b, j] += 1 - resx[b, j] = val - - for i in range(ngroups): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = %(nan_val)s - else: - out[i, j] = resx[i, j] + with nogil: + b = 0 + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 + + counts[b] += 1 + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[b, j] += 1 + resx[b, j] = val + + for i in range(ngroups): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = %(nan_val)s + else: + out[i, j] = resx[i, j] """ -group_nth_bin_template = """@cython.boundscheck(False) -@cython.wraparound(False) +group_nth_bin_template = """@cython.wraparound(False) +@cython.boundscheck(False) def group_nth_bin_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, ndarray[int64_t] counts, ndarray[%(c_type)s, ndim=2] values, @@ -797,6 +817,8 @@ def group_nth_bin_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, nobs = np.zeros_like(out) resx = np.empty_like(out) + if len(bin) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: @@ -804,31 +826,32 @@ def group_nth_bin_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, N, K = ( values).shape - b = 0 - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + with nogil: + b = 0 + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 - counts[b] += 1 - for j in range(K): - val = values[i, j] + counts[b] += 1 + for j in range(K): + val = values[i, j] - # not nan - if val == val: - nobs[b, j] += 1 - if nobs[b, j] == rank: - resx[b, j] = val + # not nan + if val == val: + nobs[b, j] += 1 + if nobs[b, j] == rank: + resx[b, j] = val - for i in range(ngroups): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = %(nan_val)s - else: - out[i, j] = resx[i, j] + for i in range(ngroups): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = %(nan_val)s + else: + out[i, j] = resx[i, j] """ -group_nth_template = """@cython.boundscheck(False) -@cython.wraparound(False) +group_nth_template = """@cython.wraparound(False) +@cython.boundscheck(False) def group_nth_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, ndarray[int64_t] counts, ndarray[%(c_type)s, ndim=2] values, @@ -837,7 +860,7 @@ def group_nth_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, Only aggregates on axis=0 ''' cdef: - Py_ssize_t i, j, N, K, lab + Py_ssize_t i, j, N, K, lab, ncounts = len(counts) %(dest_type2)s val, count ndarray[%(dest_type2)s, ndim=2] resx ndarray[int64_t, ndim=2] nobs @@ -850,31 +873,32 @@ def group_nth_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, N, K = ( values).shape - for i in range(N): - lab = labels[i] - if lab < 0: - continue + with nogil: + for i in range(N): + lab = labels[i] + if lab < 0: + continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + counts[lab] += 1 + for j in range(K): + val = values[i, j] - # not nan - if val == val: - nobs[lab, j] += 1 - if nobs[lab, j] == rank: - resx[lab, j] = val + # not nan + if val == val: + nobs[lab, j] += 1 + if nobs[lab, j] == rank: + resx[lab, j] = val - for i in range(len(counts)): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = %(nan_val)s - else: - out[i, j] = resx[i, j] + for i in range(ncounts): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = %(nan_val)s + else: + out[i, j] = resx[i, j] """ -group_add_template = """@cython.boundscheck(False) -@cython.wraparound(False) +group_add_template = """@cython.wraparound(False) +@cython.boundscheck(False) def group_add_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, ndarray[int64_t] counts, ndarray[%(c_type)s, ndim=2] values, @@ -883,7 +907,7 @@ def group_add_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, Only aggregates on axis=0 ''' cdef: - Py_ssize_t i, j, N, K, lab + Py_ssize_t i, j, N, K, lab, ncounts = len(counts) %(dest_type2)s val, count ndarray[%(dest_type2)s, ndim=2] sumx, nobs @@ -895,44 +919,50 @@ def group_add_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, N, K = ( values).shape - if K > 1: - for i in range(N): - lab = labels[i] - if lab < 0: - continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + with nogil: - # not nan - if val == val: - nobs[lab, j] += 1 - sumx[lab, j] += val - else: - for i in range(N): - lab = labels[i] - if lab < 0: - continue + if K > 1: - counts[lab] += 1 - val = values[i, 0] + for i in range(N): + lab = labels[i] + if lab < 0: + continue - # not nan - if val == val: - nobs[lab, 0] += 1 - sumx[lab, 0] += val + counts[lab] += 1 + for j in range(K): + val = values[i, j] - for i in range(len(counts)): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = sumx[i, j] + # not nan + if val == val: + nobs[lab, j] += 1 + sumx[lab, j] += val + + else: + + for i in range(N): + lab = labels[i] + if lab < 0: + continue + + counts[lab] += 1 + val = values[i, 0] + + # not nan + if val == val: + nobs[lab, 0] += 1 + sumx[lab, 0] += val + + for i in range(ncounts): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = sumx[i, j] """ -group_add_bin_template = """@cython.boundscheck(False) -@cython.wraparound(False) +group_add_bin_template = """@cython.wraparound(False) +@cython.boundscheck(False) def group_add_bin_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, ndarray[int64_t] counts, ndarray[%(dest_type2)s, ndim=2] values, @@ -948,49 +978,54 @@ def group_add_bin_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, nobs = np.zeros_like(out) sumx = np.zeros_like(out) + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: ngroups = len(bins) + 1 N, K = ( values).shape - b = 0 - if K > 1: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + with nogil: - counts[b] += 1 - for j in range(K): - val = values[i, j] + b = 0 + if K > 1: - # not nan - if val == val: - nobs[b, j] += 1 - sumx[b, j] += val - else: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 - counts[b] += 1 - val = values[i, 0] + counts[b] += 1 + for j in range(K): + val = values[i, j] - # not nan - if val == val: - nobs[b, 0] += 1 - sumx[b, 0] += val + # not nan + if val == val: + nobs[b, j] += 1 + sumx[b, j] += val + else: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 - for i in range(ngroups): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = sumx[i, j] + counts[b] += 1 + val = values[i, 0] + + # not nan + if val == val: + nobs[b, 0] += 1 + sumx[b, 0] += val + + for i in range(ngroups): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = sumx[i, j] """ -group_prod_template = """@cython.boundscheck(False) -@cython.wraparound(False) +group_prod_template = """@cython.wraparound(False) +@cython.boundscheck(False) def group_prod_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, ndarray[int64_t] counts, ndarray[%(c_type)s, ndim=2] values, @@ -999,7 +1034,7 @@ def group_prod_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, Only aggregates on axis=0 ''' cdef: - Py_ssize_t i, j, N, K, lab + Py_ssize_t i, j, N, K, lab, ncounts = len(counts) %(dest_type2)s val, count ndarray[%(dest_type2)s, ndim=2] prodx, nobs @@ -1011,44 +1046,45 @@ def group_prod_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, N, K = ( values).shape - if K > 1: - for i in range(N): - lab = labels[i] - if lab < 0: - continue + with nogil: + if K > 1: + for i in range(N): + lab = labels[i] + if lab < 0: + continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + counts[lab] += 1 + for j in range(K): + val = values[i, j] - # not nan - if val == val: - nobs[lab, j] += 1 - prodx[lab, j] *= val - else: - for i in range(N): - lab = labels[i] - if lab < 0: - continue + # not nan + if val == val: + nobs[lab, j] += 1 + prodx[lab, j] *= val + else: + for i in range(N): + lab = labels[i] + if lab < 0: + continue - counts[lab] += 1 - val = values[i, 0] + counts[lab] += 1 + val = values[i, 0] - # not nan - if val == val: - nobs[lab, 0] += 1 - prodx[lab, 0] *= val + # not nan + if val == val: + nobs[lab, 0] += 1 + prodx[lab, 0] *= val - for i in range(len(counts)): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = prodx[i, j] + for i in range(ncounts): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = prodx[i, j] """ -group_prod_bin_template = """@cython.boundscheck(False) -@cython.wraparound(False) +group_prod_bin_template = """@cython.wraparound(False) +@cython.boundscheck(False) def group_prod_bin_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, ndarray[int64_t] counts, ndarray[%(dest_type2)s, ndim=2] values, @@ -1064,70 +1100,75 @@ def group_prod_bin_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, nobs = np.zeros_like(out) prodx = np.ones_like(out) + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: ngroups = len(bins) + 1 N, K = ( values).shape - b = 0 - if K > 1: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + with nogil: - counts[b] += 1 - for j in range(K): - val = values[i, j] + b = 0 + if K > 1: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 - # not nan - if val == val: - nobs[b, j] += 1 - prodx[b, j] *= val - else: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + counts[b] += 1 + for j in range(K): + val = values[i, j] - counts[b] += 1 - val = values[i, 0] + # not nan + if val == val: + nobs[b, j] += 1 + prodx[b, j] *= val + else: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 - # not nan - if val == val: - nobs[b, 0] += 1 - prodx[b, 0] *= val + counts[b] += 1 + val = values[i, 0] - for i in range(ngroups): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = prodx[i, j] + # not nan + if val == val: + nobs[b, 0] += 1 + prodx[b, 0] *= val + + for i in range(ngroups): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = prodx[i, j] """ group_var_template = """@cython.wraparound(False) @cython.boundscheck(False) +@cython.cdivision(True) def group_var_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, ndarray[int64_t] counts, ndarray[%(dest_type2)s, ndim=2] values, ndarray[int64_t] labels): cdef: - Py_ssize_t i, j, N, K, lab - %(dest_type2)s val, ct - ndarray[%(dest_type2)s, ndim=2] nobs, sumx, sumxx + Py_ssize_t i, j, N, K, lab, ncounts = len(counts) + %(dest_type2)s val, ct, oldmean + ndarray[%(dest_type2)s, ndim=2] nobs, mean if not len(values) == len(labels): raise AssertionError("len(index) != len(labels)") nobs = np.zeros_like(out) - sumx = np.zeros_like(out) - sumxx = np.zeros_like(out) + mean = np.zeros_like(out) N, K = ( values).shape - if K > 1: - for i in range(N): + out[:, :] = 0.0 + with nogil: + for i in range(N): lab = labels[i] if lab < 0: continue @@ -1140,32 +1181,18 @@ def group_var_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, # not nan if val == val: nobs[lab, j] += 1 - sumx[lab, j] += val - sumxx[lab, j] += val * val - else: - for i in range(N): + oldmean = mean[lab, j] + mean[lab, j] += (val - oldmean) / nobs[lab, j] + out[lab, j] += (val - mean[lab, j]) * (val - oldmean) - lab = labels[i] - if lab < 0: - continue + for i in range(ncounts): + for j in range(K): + ct = nobs[i, j] + if ct < 2: + out[i, j] = NAN + else: + out[i, j] /= (ct - 1) - counts[lab] += 1 - val = values[i, 0] - # not nan - if val == val: - nobs[lab, 0] += 1 - sumx[lab, 0] += val - sumxx[lab, 0] += val * val - - - for i in range(len(counts)): - for j in range(K): - ct = nobs[i, j] - if ct < 2: - out[i, j] = nan - else: - out[i, j] = ((ct * sumxx[i, j] - sumx[i, j] * sumx[i, j]) / - (ct * ct - ct)) """ group_var_bin_template = """@cython.wraparound(False) @@ -1184,6 +1211,8 @@ def group_var_bin_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, sumx = np.zeros_like(out) sumxx = np.zeros_like(out) + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: @@ -1191,44 +1220,45 @@ def group_var_bin_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, N, K = ( values).shape - b = 0 - if K > 1: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + with nogil: + b = 0 + if K > 1: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 - counts[b] += 1 + counts[b] += 1 - for j in range(K): - val = values[i, j] + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[b, j] += 1 + sumx[b, j] += val + sumxx[b, j] += val * val + else: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 + + counts[b] += 1 + val = values[i, 0] # not nan if val == val: - nobs[b, j] += 1 - sumx[b, j] += val - sumxx[b, j] += val * val - else: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + nobs[b, 0] += 1 + sumx[b, 0] += val + sumxx[b, 0] += val * val - counts[b] += 1 - val = values[i, 0] - - # not nan - if val == val: - nobs[b, 0] += 1 - sumx[b, 0] += val - sumxx[b, 0] += val * val - - for i in range(ngroups): - for j in range(K): - ct = nobs[i, j] - if ct < 2: - out[i, j] = nan - else: - out[i, j] = ((ct * sumxx[i, j] - sumx[i, j] * sumx[i, j]) / - (ct * ct - ct)) + for i in range(ngroups): + for j in range(K): + ct = nobs[i, j] + if ct < 2: + out[i, j] = NAN + else: + out[i, j] = ((ct * sumxx[i, j] - sumx[i, j] * sumx[i, j]) / + (ct * ct - ct)) """ group_count_template = """@cython.boundscheck(False) @@ -1241,36 +1271,36 @@ def group_count_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, Only aggregates on axis=0 ''' cdef: - Py_ssize_t i, j, lab + Py_ssize_t i, j, lab, ncounts = len(counts) Py_ssize_t N = values.shape[0], K = values.shape[1] %(c_type)s val ndarray[int64_t, ndim=2] nobs = np.zeros((out.shape[0], out.shape[1]), dtype=np.int64) if len(values) != len(labels): - raise AssertionError("len(index) != len(labels)") - - for i in range(N): - lab = labels[i] - if lab < 0: - continue + raise AssertionError("len(index) != len(labels)") - counts[lab] += 1 - for j in range(K): - val = values[i, j] - # not nan - nobs[lab, j] += val == val and val != iNaT + %(nogil)s + %(tab)sfor i in range(N): + %(tab)s lab = labels[i] + %(tab)s if lab < 0: + %(tab)s continue - for i in range(len(counts)): - for j in range(K): - out[i, j] = nobs[i, j] + %(tab)s counts[lab] += 1 + %(tab)s for j in range(K): + %(tab)s val = values[i, j] + %(tab)s # not nan + %(tab)s nobs[lab, j] += val == val and val != iNaT + %(tab)sfor i in range(ncounts): + %(tab)s for j in range(K): + %(tab)s out[i, j] = nobs[i, j] """ -group_count_bin_template = """@cython.boundscheck(False) -@cython.wraparound(False) +group_count_bin_template = """@cython.wraparound(False) +@cython.boundscheck(False) def group_count_bin_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, ndarray[int64_t] counts, ndarray[%(c_type)s, ndim=2] values, @@ -1285,25 +1315,27 @@ def group_count_bin_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, ndarray[int64_t, ndim=2] nobs = np.zeros((out.shape[0], out.shape[1]), dtype=np.int64) + if len(bins) == 0: + return ngroups = len(bins) + (bins[len(bins) - 1] != N) - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 - - counts[b] += 1 - for j in range(K): - val = values[i, j] + %(nogil)s + %(tab)sfor i in range(N): + %(tab)s while b < ngroups - 1 and i >= bins[b]: + %(tab)s b += 1 - # not nan - nobs[b, j] += val == val and val != iNaT - - for i in range(ngroups): - for j in range(K): - out[i, j] = nobs[i, j] + %(tab)s counts[b] += 1 + %(tab)s for j in range(K): + %(tab)s val = values[i, j] + %(tab)s # not nan + %(tab)s nobs[b, j] += val == val and val != iNaT + %(tab)sfor i in range(ngroups): + %(tab)s for j in range(K): + %(tab)s out[i, j] = nobs[i, j] """ + # add passing bin edges, instead of labels @@ -1329,6 +1361,8 @@ def group_min_bin_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, minx = np.empty_like(out) minx.fill(%(inf_val)s) + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: @@ -1336,41 +1370,42 @@ def group_min_bin_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, N, K = ( values).shape - b = 0 - if K > 1: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + with nogil: + b = 0 + if K > 1: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 + + counts[b] += 1 + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[b, j] += 1 + if val < minx[b, j]: + minx[b, j] = val + else: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 - counts[b] += 1 - for j in range(K): - val = values[i, j] + counts[b] += 1 + val = values[i, 0] # not nan if val == val: - nobs[b, j] += 1 - if val < minx[b, j]: - minx[b, j] = val - else: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + nobs[b, 0] += 1 + if val < minx[b, 0]: + minx[b, 0] = val - counts[b] += 1 - val = values[i, 0] - - # not nan - if val == val: - nobs[b, 0] += 1 - if val < minx[b, 0]: - minx[b, 0] = val - - for i in range(ngroups): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = %(nan_val)s - else: - out[i, j] = minx[i, j] + for i in range(ngroups): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = %(nan_val)s + else: + out[i, j] = minx[i, j] """ group_max_template = """@cython.wraparound(False) @@ -1383,7 +1418,7 @@ def group_max_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, Only aggregates on axis=0 ''' cdef: - Py_ssize_t i, j, N, K, lab + Py_ssize_t i, j, N, K, lab, ncounts = len(counts) %(dest_type2)s val, count ndarray[%(dest_type2)s, ndim=2] maxx, nobs @@ -1397,42 +1432,43 @@ def group_max_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, N, K = ( values).shape - if K > 1: - for i in range(N): - lab = labels[i] - if lab < 0: - continue + with nogil: + if K > 1: + for i in range(N): + lab = labels[i] + if lab < 0: + continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + counts[lab] += 1 + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[lab, j] += 1 + if val > maxx[lab, j]: + maxx[lab, j] = val + else: + for i in range(N): + lab = labels[i] + if lab < 0: + continue + + counts[lab] += 1 + val = values[i, 0] # not nan if val == val: - nobs[lab, j] += 1 - if val > maxx[lab, j]: - maxx[lab, j] = val - else: - for i in range(N): - lab = labels[i] - if lab < 0: - continue + nobs[lab, 0] += 1 + if val > maxx[lab, 0]: + maxx[lab, 0] = val - counts[lab] += 1 - val = values[i, 0] - - # not nan - if val == val: - nobs[lab, 0] += 1 - if val > maxx[lab, 0]: - maxx[lab, 0] = val - - for i in range(len(counts)): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = %(nan_val)s - else: - out[i, j] = maxx[i, j] + for i in range(ncounts): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = %(nan_val)s + else: + out[i, j] = maxx[i, j] """ group_max_bin_template = """@cython.wraparound(False) @@ -1453,6 +1489,8 @@ def group_max_bin_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, maxx = np.empty_like(out) maxx.fill(-%(inf_val)s) + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: @@ -1460,41 +1498,42 @@ def group_max_bin_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, N, K = ( values).shape - b = 0 - if K > 1: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + with nogil: + b = 0 + if K > 1: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 + + counts[b] += 1 + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[b, j] += 1 + if val > maxx[b, j]: + maxx[b, j] = val + else: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 - counts[b] += 1 - for j in range(K): - val = values[i, j] + counts[b] += 1 + val = values[i, 0] # not nan if val == val: - nobs[b, j] += 1 - if val > maxx[b, j]: - maxx[b, j] = val - else: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + nobs[b, 0] += 1 + if val > maxx[b, 0]: + maxx[b, 0] = val - counts[b] += 1 - val = values[i, 0] - - # not nan - if val == val: - nobs[b, 0] += 1 - if val > maxx[b, 0]: - maxx[b, 0] = val - - for i in range(ngroups): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = %(nan_val)s - else: - out[i, j] = maxx[i, j] + for i in range(ngroups): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = %(nan_val)s + else: + out[i, j] = maxx[i, j] """ @@ -1508,7 +1547,7 @@ def group_min_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, Only aggregates on axis=0 ''' cdef: - Py_ssize_t i, j, N, K, lab + Py_ssize_t i, j, N, K, lab, ncounts = len(counts) %(dest_type2)s val, count ndarray[%(dest_type2)s, ndim=2] minx, nobs @@ -1522,42 +1561,43 @@ def group_min_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, N, K = ( values).shape - if K > 1: - for i in range(N): - lab = labels[i] - if lab < 0: - continue + with nogil: + if K > 1: + for i in range(N): + lab = labels[i] + if lab < 0: + continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + counts[lab] += 1 + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[lab, j] += 1 + if val < minx[lab, j]: + minx[lab, j] = val + else: + for i in range(N): + lab = labels[i] + if lab < 0: + continue + + counts[lab] += 1 + val = values[i, 0] # not nan if val == val: - nobs[lab, j] += 1 - if val < minx[lab, j]: - minx[lab, j] = val - else: - for i in range(N): - lab = labels[i] - if lab < 0: - continue + nobs[lab, 0] += 1 + if val < minx[lab, 0]: + minx[lab, 0] = val - counts[lab] += 1 - val = values[i, 0] - - # not nan - if val == val: - nobs[lab, 0] += 1 - if val < minx[lab, 0]: - minx[lab, 0] = val - - for i in range(len(counts)): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = %(nan_val)s - else: - out[i, j] = minx[i, j] + for i in range(ncounts): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = %(nan_val)s + else: + out[i, j] = minx[i, j] """ @@ -1568,7 +1608,7 @@ def group_mean_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, ndarray[%(dest_type2)s, ndim=2] values, ndarray[int64_t] labels): cdef: - Py_ssize_t i, j, N, K, lab + Py_ssize_t i, j, N, K, lab, ncounts = len(counts) %(dest_type2)s val, count ndarray[%(dest_type2)s, ndim=2] sumx, nobs @@ -1580,42 +1620,44 @@ def group_mean_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, N, K = ( values).shape - if K > 1: - for i in range(N): - lab = labels[i] - if lab < 0: - continue + with nogil: + if K > 1: + for i in range(N): + lab = labels[i] + if lab < 0: + continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + counts[lab] += 1 + for j in range(K): + val = values[i, j] + # not nan + if val == val: + nobs[lab, j] += 1 + sumx[lab, j] += val + else: + for i in range(N): + lab = labels[i] + if lab < 0: + continue + + counts[lab] += 1 + val = values[i, 0] # not nan if val == val: - nobs[lab, j] += 1 - sumx[lab, j] += val - else: - for i in range(N): - lab = labels[i] - if lab < 0: - continue + nobs[lab, 0] += 1 + sumx[lab, 0] += val - counts[lab] += 1 - val = values[i, 0] - # not nan - if val == val: - nobs[lab, 0] += 1 - sumx[lab, 0] += val - - for i in range(len(counts)): - for j in range(K): - count = nobs[i, j] - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = sumx[i, j] / count + for i in range(ncounts): + for j in range(K): + count = nobs[i, j] + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = sumx[i, j] / count """ group_mean_bin_template = """ +@cython.boundscheck(False) def group_mean_bin_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, ndarray[int64_t] counts, ndarray[%(dest_type2)s, ndim=2] values, @@ -1629,45 +1671,48 @@ def group_mean_bin_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, sumx = np.zeros_like(out) N, K = ( values).shape + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: ngroups = len(bins) + 1 - b = 0 - if K > 1: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + with nogil: + b = 0 + if K > 1: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 + + counts[b] += 1 + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[b, j] += 1 + sumx[b, j] += val + else: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 - counts[b] += 1 - for j in range(K): - val = values[i, j] + counts[b] += 1 + val = values[i, 0] # not nan if val == val: - nobs[b, j] += 1 - sumx[b, j] += val - else: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + nobs[b, 0] += 1 + sumx[b, 0] += val - counts[b] += 1 - val = values[i, 0] - - # not nan - if val == val: - nobs[b, 0] += 1 - sumx[b, 0] += val - - for i in range(ngroups): - for j in range(K): - count = nobs[i, j] - if count == 0: - out[i, j] = nan - else: - out[i, j] = sumx[i, j] / count + for i in range(ngroups): + for j in range(K): + count = nobs[i, j] + if count == 0: + out[i, j] = NAN + else: + out[i, j] = sumx[i, j] / count """ group_ohlc_template = """@cython.wraparound(False) @@ -1682,9 +1727,11 @@ def group_ohlc_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, cdef: Py_ssize_t i, j, N, K, ngroups, b %(dest_type2)s val, count - %(dest_type2)s vopen, vhigh, vlow, vclose, NA + %(dest_type2)s vopen, vhigh, vlow, vclose bint got_first = 0 + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: @@ -1695,55 +1742,55 @@ def group_ohlc_%(name)s(ndarray[%(dest_type2)s, ndim=2] out, if out.shape[1] != 4: raise ValueError('Output array must have 4 columns') - NA = np.nan - b = 0 if K > 1: raise NotImplementedError("Argument 'values' must have only " "one dimension") else: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - if not got_first: - out[b, 0] = NA - out[b, 1] = NA - out[b, 2] = NA - out[b, 3] = NA - else: - out[b, 0] = vopen - out[b, 1] = vhigh - out[b, 2] = vlow - out[b, 3] = vclose - b += 1 - got_first = 0 - counts[b] += 1 - val = values[i, 0] - - # not nan - if val == val: - if not got_first: - got_first = 1 - vopen = val - vlow = val - vhigh = val - else: - if val < vlow: + with nogil: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + if not got_first: + out[b, 0] = NAN + out[b, 1] = NAN + out[b, 2] = NAN + out[b, 3] = NAN + else: + out[b, 0] = vopen + out[b, 1] = vhigh + out[b, 2] = vlow + out[b, 3] = vclose + b += 1 + got_first = 0 + + counts[b] += 1 + val = values[i, 0] + + # not nan + if val == val: + if not got_first: + got_first = 1 + vopen = val vlow = val - if val > vhigh: vhigh = val - vclose = val - - if not got_first: - out[b, 0] = NA - out[b, 1] = NA - out[b, 2] = NA - out[b, 3] = NA - else: - out[b, 0] = vopen - out[b, 1] = vhigh - out[b, 2] = vlow - out[b, 3] = vclose + else: + if val < vlow: + vlow = val + if val > vhigh: + vhigh = val + vclose = val + + if not got_first: + out[b, 0] = NAN + out[b, 1] = NAN + out[b, 2] = NAN + out[b, 3] = NAN + else: + out[b, 0] = vopen + out[b, 1] = vhigh + out[b, 2] = vlow + out[b, 3] = vclose """ arrmap_template = """@cython.wraparound(False) @@ -1760,7 +1807,6 @@ def arrmap_%(name)s(ndarray[%(c_type)s] index, object func): result[i] = func(index[i]) return maybe_convert_objects(result) - """ #---------------------------------------------------------------------- @@ -1812,7 +1858,6 @@ def left_join_indexer_unique_%(name)s(ndarray[%(c_type)s] left, indexer[i] = -1 i += 1 return indexer - """ # @cython.wraparound(False) @@ -1919,7 +1964,6 @@ def left_join_indexer_%(name)s(ndarray[%(c_type)s] left, j += 1 return result, lindexer, rindexer - """ @@ -2015,7 +2059,6 @@ def inner_join_indexer_%(name)s(ndarray[%(c_type)s] left, j += 1 return result, lindexer, rindexer - """ @@ -2088,7 +2131,7 @@ def outer_join_indexer_%(name)s(ndarray[%(c_type)s] left, rindexer[j] = j result[j] = right[j] elif nright == 0: - for i in range(nright): + for i in range(nleft): lindexer[i] = i rindexer[i] = -1 result[i] = left[i] @@ -2147,7 +2190,6 @@ def outer_join_indexer_%(name)s(ndarray[%(c_type)s] left, j += 1 return result, lindexer, rindexer - """ outer_join_template = """@cython.wraparound(False) @@ -2245,7 +2287,6 @@ def outer_join_indexer_%(name)s(ndarray[%(c_type)s] left, count += 1 return result, lindexer, rindexer - """ # ensure_dtype functions @@ -2259,7 +2300,6 @@ def outer_join_indexer_%(name)s(ndarray[%(c_type)s] left, return arr.astype(np.%(dtype)s) else: return np.array(arr, dtype=np.%(dtype)s) - """ ensure_functions = [ @@ -2303,19 +2343,19 @@ def put2d_%(name)s_%(dest_type)s(ndarray[%(c_type)s, ndim=2, cast=True] values, def generate_put_template(template, use_ints=True, use_floats=True, use_objects=False, use_datelikes=False): floats_list = [ - ('float64', 'float64_t', 'float64_t', 'np.float64'), - ('float32', 'float32_t', 'float32_t', 'np.float32'), + ('float64', 'float64_t', 'float64_t', 'np.float64', True), + ('float32', 'float32_t', 'float32_t', 'np.float32', True), ] ints_list = [ - ('int8', 'int8_t', 'float32_t', 'np.float32'), - ('int16', 'int16_t', 'float32_t', 'np.float32'), - ('int32', 'int32_t', 'float64_t', 'np.float64'), - ('int64', 'int64_t', 'float64_t', 'np.float64'), + ('int8', 'int8_t', 'float32_t', 'np.float32', True), + ('int16', 'int16_t', 'float32_t', 'np.float32', True), + ('int32', 'int32_t', 'float64_t', 'np.float64', True), + ('int64', 'int64_t', 'float64_t', 'np.float64', True), ] date_like_list = [ - ('int64', 'int64_t', 'float64_t', 'np.float64'), + ('int64', 'int64_t', 'float64_t', 'np.float64', True), ] - object_list = [('object', 'object', 'object', 'np.object_')] + object_list = [('object', 'object', 'object', 'np.object_', False)] function_list = [] if use_floats: function_list.extend(floats_list) @@ -2327,28 +2367,31 @@ def generate_put_template(template, use_ints=True, use_floats=True, function_list.extend(date_like_list) output = StringIO() - for name, c_type, dest_type, dest_dtype in function_list: + for name, c_type, dest_type, dest_dtype, nogil in function_list: func = template % {'name': name, 'c_type': c_type, 'dest_type': dest_type.replace('_t', ''), 'dest_type2': dest_type, - 'dest_dtype': dest_dtype} + 'dest_dtype': dest_dtype, + 'nogil' : 'with nogil:' if nogil else '', + 'tab' : ' ' if nogil else '' } output.write(func) + output.write("\n") return output.getvalue() def generate_put_min_max_template(template, use_ints=True, use_floats=True, use_objects=False, use_datelikes=False): floats_list = [ - ('float64', 'float64_t', 'nan', 'np.inf'), - ('float32', 'float32_t', 'nan', 'np.inf'), + ('float64', 'float64_t', 'NAN', 'np.inf', True), + ('float32', 'float32_t', 'NAN', 'np.inf', True), ] ints_list = [ - ('int64', 'int64_t', 'iNaT', _int64_max), + ('int64', 'int64_t', 'iNaT', _int64_max, True), ] date_like_list = [ - ('int64', 'int64_t', 'iNaT', _int64_max), + ('int64', 'int64_t', 'iNaT', _int64_max, True), ] - object_list = [('object', 'object', 'nan', 'np.inf')] + object_list = [('object', 'object', 'np.nan', 'np.inf', False)] function_list = [] if use_floats: function_list.extend(floats_list) @@ -2360,27 +2403,30 @@ def generate_put_min_max_template(template, use_ints=True, use_floats=True, function_list.extend(date_like_list) output = StringIO() - for name, dest_type, nan_val, inf_val in function_list: + for name, dest_type, nan_val, inf_val, nogil in function_list: func = template % {'name': name, 'dest_type2': dest_type, 'nan_val': nan_val, - 'inf_val': inf_val} + 'inf_val': inf_val, + 'nogil' : "with nogil:" if nogil else '', + 'tab' : ' ' if nogil else '' } output.write(func) + output.write("\n") return output.getvalue() def generate_put_selection_template(template, use_ints=True, use_floats=True, use_objects=False, use_datelikes=False): floats_list = [ - ('float64', 'float64_t', 'float64_t', 'nan'), - ('float32', 'float32_t', 'float32_t', 'nan'), + ('float64', 'float64_t', 'float64_t', 'NAN', True), + ('float32', 'float32_t', 'float32_t', 'NAN', True), ] ints_list = [ - ('int64', 'int64_t', 'int64_t', 'iNaT'), + ('int64', 'int64_t', 'int64_t', 'iNaT', True), ] date_like_list = [ - ('int64', 'int64_t', 'int64_t', 'iNaT'), + ('int64', 'int64_t', 'int64_t', 'iNaT', True), ] - object_list = [('object', 'object', 'object', 'nan')] + object_list = [('object', 'object', 'object', 'np.nan', False)] function_list = [] if use_floats: function_list.extend(floats_list) @@ -2392,72 +2438,97 @@ def generate_put_selection_template(template, use_ints=True, use_floats=True, function_list.extend(date_like_list) output = StringIO() - for name, c_type, dest_type, nan_val in function_list: + for name, c_type, dest_type, nan_val, nogil in function_list: + + if nogil: + nogil = "with nogil:" + tab = ' ' + else: + nogil = '' + tab = '' + func = template % {'name': name, 'c_type': c_type, 'dest_type2': dest_type, - 'nan_val': nan_val} + 'nan_val': nan_val, + 'nogil' : nogil, + 'tab' : tab } output.write(func) + output.write("\n") return output.getvalue() def generate_take_template(template, exclude=None): - # name, dest, ctypein, ctypeout, preval, postval, cancopy + # name, dest, ctypein, ctypeout, preval, postval, cancopy, nogil function_list = [ - ('bool', 'bool', 'uint8_t', 'uint8_t', '', '', True), + ('bool', 'bool', 'uint8_t', 'uint8_t', '', '', True, True), ('bool', 'object', 'uint8_t', 'object', - 'True if ', ' > 0 else False', False), - ('int8', 'int8', 'int8_t', 'int8_t', '', '', True), - ('int8', 'int32', 'int8_t', 'int32_t', '', '', False), - ('int8', 'int64', 'int8_t', 'int64_t', '', '', False), - ('int8', 'float64', 'int8_t', 'float64_t', '', '', False), - ('int16', 'int16', 'int16_t', 'int16_t', '', '', True), - ('int16', 'int32', 'int16_t', 'int32_t', '', '', False), - ('int16', 'int64', 'int16_t', 'int64_t', '', '', False), - ('int16', 'float64', 'int16_t', 'float64_t', '', '', False), - ('int32', 'int32', 'int32_t', 'int32_t', '', '', True), - ('int32', 'int64', 'int32_t', 'int64_t', '', '', False), - ('int32', 'float64', 'int32_t', 'float64_t', '', '', False), - ('int64', 'int64', 'int64_t', 'int64_t', '', '', True), - ('int64', 'float64', 'int64_t', 'float64_t', '', '', False), - ('float32', 'float32', 'float32_t', 'float32_t', '', '', True), - ('float32', 'float64', 'float32_t', 'float64_t', '', '', False), - ('float64', 'float64', 'float64_t', 'float64_t', '', '', True), - ('object', 'object', 'object', 'object', '', '', False) + 'True if ', ' > 0 else False', False, False), + ('int8', 'int8', 'int8_t', 'int8_t', '', '', True, False), + ('int8', 'int32', 'int8_t', 'int32_t', '', '', False, True), + ('int8', 'int64', 'int8_t', 'int64_t', '', '', False, True), + ('int8', 'float64', 'int8_t', 'float64_t', '', '', False, True), + ('int16', 'int16', 'int16_t', 'int16_t', '', '', True, True), + ('int16', 'int32', 'int16_t', 'int32_t', '', '', False, True), + ('int16', 'int64', 'int16_t', 'int64_t', '', '', False, True), + ('int16', 'float64', 'int16_t', 'float64_t', '', '', False, True), + ('int32', 'int32', 'int32_t', 'int32_t', '', '', True, True), + ('int32', 'int64', 'int32_t', 'int64_t', '', '', False, True), + ('int32', 'float64', 'int32_t', 'float64_t', '', '', False, True), + ('int64', 'int64', 'int64_t', 'int64_t', '', '', True, True), + ('int64', 'float64', 'int64_t', 'float64_t', '', '', False, True), + ('float32', 'float32', 'float32_t', 'float32_t', '', '', True, True), + ('float32', 'float64', 'float32_t', 'float64_t', '', '', False, True), + ('float64', 'float64', 'float64_t', 'float64_t', '', '', True, True), + ('object', 'object', 'object', 'object', '', '', False, False), ] output = StringIO() for (name, dest, c_type_in, c_type_out, - preval, postval, can_copy) in function_list: + preval, postval, can_copy, nogil) in function_list: + if exclude is not None and name in exclude: continue + if nogil: + nogil = "with nogil:" + tab = ' ' + else: + nogil = '' + tab = '' + func = template % {'name': name, 'dest': dest, 'c_type_in': c_type_in, 'c_type_out': c_type_out, 'preval': preval, 'postval': postval, - 'can_copy': 'True' if can_copy else 'False'} + 'can_copy': 'True' if can_copy else 'False', + 'nogil' : nogil, + 'tab' : tab } output.write(func) + output.write("\n") return output.getvalue() def generate_from_template(template, exclude=None): # name, ctype, capable of holding NA function_list = [ - ('float64', 'float64_t', 'np.float64', True), - ('float32', 'float32_t', 'np.float32', True), - ('object', 'object', 'object', True), - ('int32', 'int32_t', 'np.int32', False), - ('int64', 'int64_t', 'np.int64', False), - ('bool', 'uint8_t', 'np.bool', False) + ('float64', 'float64_t', 'np.float64', True, True), + ('float32', 'float32_t', 'np.float32', True, True), + ('object', 'object', 'object', True, False), + ('int32', 'int32_t', 'np.int32', False, True), + ('int64', 'int64_t', 'np.int64', False, True), + ('bool', 'uint8_t', 'np.bool', False, True) ] output = StringIO() - for name, c_type, dtype, can_hold_na in function_list: + for name, c_type, dtype, can_hold_na, nogil in function_list: if exclude is not None and name in exclude: continue func = template % {'name': name, 'c_type': c_type, 'dtype': dtype, - 'raise_on_na': 'False' if can_hold_na else 'True'} + 'raise_on_na': 'False' if can_hold_na else 'True', + 'nogil' : 'with nogil:' if nogil else '', + 'tab' : ' ' if nogil else '' } output.write(func) + output.write("\n") return output.getvalue() put_2d = [diff_2d_template] @@ -2506,8 +2577,14 @@ def generate_from_template(template, exclude=None): take_2d_multi_template] -def generate_take_cython_file(path='generated.pyx'): +def generate_take_cython_file(): + # Put `generated.pyx` in the same directory as this file + directory = os.path.dirname(os.path.realpath(__file__)) + filename = 'generated.pyx' + path = os.path.join(directory, filename) + with open(path, 'w') as f: + print(warning_to_new_contributors, file=f) print(header, file=f) print(generate_ensure_dtypes(), file=f) @@ -2536,13 +2613,7 @@ def generate_take_cython_file(path='generated.pyx'): print(generate_put_selection_template(template, use_ints=True, use_datelikes=True, use_objects=True), - file=f) - - # for template in templates_1d_datetime: - # print >> f, generate_from_template_datetime(template) - - # for template in templates_2d_datetime: - # print >> f, generate_from_template_datetime(template, ndim=2) + file=f) for template in nobool_1d_templates: print(generate_from_template(template, exclude=['bool']), file=f) diff --git a/pandas/src/generated.pyx b/pandas/src/generated.pyx index 428decd4dca10..d4cf7824c8911 100644 --- a/pandas/src/generated.pyx +++ b/pandas/src/generated.pyx @@ -1,4 +1,9 @@ +# DO NOT EDIT THIS FILE: This file was autogenerated from generate_code.py, so +# please edit that file and then run `python2 generate_code.py` to re-generate +# this file. + + cimport numpy as np cimport cython @@ -14,6 +19,9 @@ from cpython cimport (PyDict_New, PyDict_GetItem, PyDict_SetItem, from cpython cimport PyFloat_Check cimport cpython +cdef extern from "numpy/npy_math.h": + double NAN "NPY_NAN" + import numpy as np isnan = np.isnan @@ -63,7 +71,6 @@ cpdef ensure_object(object arr): return np.array(arr, dtype=np.object_) - cpdef ensure_float64(object arr): if util.is_array(arr): if ( arr).descr.type_num == NPY_FLOAT64: @@ -73,7 +80,6 @@ cpdef ensure_float64(object arr): else: return np.array(arr, dtype=np.float64) - cpdef ensure_float32(object arr): if util.is_array(arr): if ( arr).descr.type_num == NPY_FLOAT32: @@ -83,7 +89,6 @@ cpdef ensure_float32(object arr): else: return np.array(arr, dtype=np.float32) - cpdef ensure_int8(object arr): if util.is_array(arr): if ( arr).descr.type_num == NPY_INT8: @@ -93,7 +98,6 @@ cpdef ensure_int8(object arr): else: return np.array(arr, dtype=np.int8) - cpdef ensure_int16(object arr): if util.is_array(arr): if ( arr).descr.type_num == NPY_INT16: @@ -103,7 +107,6 @@ cpdef ensure_int16(object arr): else: return np.array(arr, dtype=np.int16) - cpdef ensure_int32(object arr): if util.is_array(arr): if ( arr).descr.type_num == NPY_INT32: @@ -113,7 +116,6 @@ cpdef ensure_int32(object arr): else: return np.array(arr, dtype=np.int32) - cpdef ensure_int64(object arr): if util.is_array(arr): if ( arr).descr.type_num == NPY_INT64: @@ -123,7 +125,6 @@ cpdef ensure_int64(object arr): else: return np.array(arr, dtype=np.int64) - @cython.wraparound(False) @cython.boundscheck(False) cpdef map_indices_float64(ndarray[float64_t] index): @@ -1228,6 +1229,7 @@ def backfill_inplace_float64(ndarray[float64_t] values, else: fill_count = 0 val = values[i] + @cython.boundscheck(False) @cython.wraparound(False) def backfill_inplace_float32(ndarray[float32_t] values, @@ -1260,6 +1262,7 @@ def backfill_inplace_float32(ndarray[float32_t] values, else: fill_count = 0 val = values[i] + @cython.boundscheck(False) @cython.wraparound(False) def backfill_inplace_object(ndarray[object] values, @@ -1292,6 +1295,7 @@ def backfill_inplace_object(ndarray[object] values, else: fill_count = 0 val = values[i] + @cython.boundscheck(False) @cython.wraparound(False) def backfill_inplace_int32(ndarray[int32_t] values, @@ -1324,6 +1328,7 @@ def backfill_inplace_int32(ndarray[int32_t] values, else: fill_count = 0 val = values[i] + @cython.boundscheck(False) @cython.wraparound(False) def backfill_inplace_int64(ndarray[int64_t] values, @@ -1356,6 +1361,7 @@ def backfill_inplace_int64(ndarray[int64_t] values, else: fill_count = 0 val = values[i] + @cython.boundscheck(False) @cython.wraparound(False) def backfill_inplace_bool(ndarray[uint8_t] values, @@ -1389,6 +1395,7 @@ def backfill_inplace_bool(ndarray[uint8_t] values, fill_count = 0 val = values[i] + @cython.boundscheck(False) @cython.wraparound(False) def pad_2d_inplace_float64(ndarray[float64_t, ndim=2] values, @@ -1423,6 +1430,7 @@ def pad_2d_inplace_float64(ndarray[float64_t, ndim=2] values, else: fill_count = 0 val = values[j, i] + @cython.boundscheck(False) @cython.wraparound(False) def pad_2d_inplace_float32(ndarray[float32_t, ndim=2] values, @@ -1457,6 +1465,7 @@ def pad_2d_inplace_float32(ndarray[float32_t, ndim=2] values, else: fill_count = 0 val = values[j, i] + @cython.boundscheck(False) @cython.wraparound(False) def pad_2d_inplace_object(ndarray[object, ndim=2] values, @@ -1491,6 +1500,7 @@ def pad_2d_inplace_object(ndarray[object, ndim=2] values, else: fill_count = 0 val = values[j, i] + @cython.boundscheck(False) @cython.wraparound(False) def pad_2d_inplace_int32(ndarray[int32_t, ndim=2] values, @@ -1525,6 +1535,7 @@ def pad_2d_inplace_int32(ndarray[int32_t, ndim=2] values, else: fill_count = 0 val = values[j, i] + @cython.boundscheck(False) @cython.wraparound(False) def pad_2d_inplace_int64(ndarray[int64_t, ndim=2] values, @@ -1559,6 +1570,7 @@ def pad_2d_inplace_int64(ndarray[int64_t, ndim=2] values, else: fill_count = 0 val = values[j, i] + @cython.boundscheck(False) @cython.wraparound(False) def pad_2d_inplace_bool(ndarray[uint8_t, ndim=2] values, @@ -1594,6 +1606,7 @@ def pad_2d_inplace_bool(ndarray[uint8_t, ndim=2] values, fill_count = 0 val = values[j, i] + @cython.boundscheck(False) @cython.wraparound(False) def backfill_2d_inplace_float64(ndarray[float64_t, ndim=2] values, @@ -1628,6 +1641,7 @@ def backfill_2d_inplace_float64(ndarray[float64_t, ndim=2] values, else: fill_count = 0 val = values[j, i] + @cython.boundscheck(False) @cython.wraparound(False) def backfill_2d_inplace_float32(ndarray[float32_t, ndim=2] values, @@ -1662,6 +1676,7 @@ def backfill_2d_inplace_float32(ndarray[float32_t, ndim=2] values, else: fill_count = 0 val = values[j, i] + @cython.boundscheck(False) @cython.wraparound(False) def backfill_2d_inplace_object(ndarray[object, ndim=2] values, @@ -1696,6 +1711,7 @@ def backfill_2d_inplace_object(ndarray[object, ndim=2] values, else: fill_count = 0 val = values[j, i] + @cython.boundscheck(False) @cython.wraparound(False) def backfill_2d_inplace_int32(ndarray[int32_t, ndim=2] values, @@ -1730,6 +1746,7 @@ def backfill_2d_inplace_int32(ndarray[int32_t, ndim=2] values, else: fill_count = 0 val = values[j, i] + @cython.boundscheck(False) @cython.wraparound(False) def backfill_2d_inplace_int64(ndarray[int64_t, ndim=2] values, @@ -1764,6 +1781,7 @@ def backfill_2d_inplace_int64(ndarray[int64_t, ndim=2] values, else: fill_count = 0 val = values[j, i] + @cython.boundscheck(False) @cython.wraparound(False) def backfill_2d_inplace_bool(ndarray[uint8_t, ndim=2] values, @@ -1799,18 +1817,18 @@ def backfill_2d_inplace_bool(ndarray[uint8_t, ndim=2] values, fill_count = 0 val = values[j, i] + @cython.boundscheck(False) @cython.wraparound(False) def is_monotonic_float64(ndarray[float64_t] arr, bint timelike): ''' Returns ------- - is_monotonic_inc, is_monotonic_dec, is_unique + is_monotonic_inc, is_monotonic_dec ''' cdef: Py_ssize_t i, n float64_t prev, cur - bint is_unique = 1 bint is_monotonic_inc = 1 bint is_monotonic_dec = 1 @@ -1819,45 +1837,52 @@ def is_monotonic_float64(ndarray[float64_t] arr, bint timelike): if n == 1: if arr[0] != arr[0] or (timelike and arr[0] == iNaT): # single value is NaN - return False, False, True + return False, False else: - return True, True, True + return True, True elif n < 2: - return True, True, True + return True, True if timelike and arr[0] == iNaT: - return False, False, None + return False, False + + with nogil: + prev = arr[0] + for i in range(1, n): + cur = arr[i] + if timelike and cur == iNaT: + is_monotonic_inc = 0 + is_monotonic_dec = 0 + break + if cur < prev: + is_monotonic_inc = 0 + elif cur > prev: + is_monotonic_dec = 0 + elif cur == prev: + pass # is_unique = 0 + else: + # cur or prev is NaN + is_monotonic_inc = 0 + is_monotonic_dec = 0 + break + if not is_monotonic_inc and not is_monotonic_dec: + is_monotonic_inc = 0 + is_monotonic_dec = 0 + break + prev = cur + return is_monotonic_inc, is_monotonic_dec - prev = arr[0] - for i in range(1, n): - cur = arr[i] - if timelike and cur == iNaT: - return False, False, None - if cur < prev: - is_monotonic_inc = 0 - elif cur > prev: - is_monotonic_dec = 0 - elif cur == prev: - is_unique = 0 - else: - # cur or prev is NaN - return False, False, None - if not is_monotonic_inc and not is_monotonic_dec: - return False, False, None - prev = cur - return is_monotonic_inc, is_monotonic_dec, is_unique @cython.boundscheck(False) @cython.wraparound(False) def is_monotonic_float32(ndarray[float32_t] arr, bint timelike): ''' Returns ------- - is_monotonic_inc, is_monotonic_dec, is_unique + is_monotonic_inc, is_monotonic_dec ''' cdef: Py_ssize_t i, n float32_t prev, cur - bint is_unique = 1 bint is_monotonic_inc = 1 bint is_monotonic_dec = 1 @@ -1866,45 +1891,52 @@ def is_monotonic_float32(ndarray[float32_t] arr, bint timelike): if n == 1: if arr[0] != arr[0] or (timelike and arr[0] == iNaT): # single value is NaN - return False, False, True + return False, False else: - return True, True, True + return True, True elif n < 2: - return True, True, True + return True, True if timelike and arr[0] == iNaT: - return False, False, None + return False, False + + with nogil: + prev = arr[0] + for i in range(1, n): + cur = arr[i] + if timelike and cur == iNaT: + is_monotonic_inc = 0 + is_monotonic_dec = 0 + break + if cur < prev: + is_monotonic_inc = 0 + elif cur > prev: + is_monotonic_dec = 0 + elif cur == prev: + pass # is_unique = 0 + else: + # cur or prev is NaN + is_monotonic_inc = 0 + is_monotonic_dec = 0 + break + if not is_monotonic_inc and not is_monotonic_dec: + is_monotonic_inc = 0 + is_monotonic_dec = 0 + break + prev = cur + return is_monotonic_inc, is_monotonic_dec - prev = arr[0] - for i in range(1, n): - cur = arr[i] - if timelike and cur == iNaT: - return False, False, None - if cur < prev: - is_monotonic_inc = 0 - elif cur > prev: - is_monotonic_dec = 0 - elif cur == prev: - is_unique = 0 - else: - # cur or prev is NaN - return False, False, None - if not is_monotonic_inc and not is_monotonic_dec: - return False, False, None - prev = cur - return is_monotonic_inc, is_monotonic_dec, is_unique @cython.boundscheck(False) @cython.wraparound(False) def is_monotonic_object(ndarray[object] arr, bint timelike): ''' Returns ------- - is_monotonic_inc, is_monotonic_dec, is_unique + is_monotonic_inc, is_monotonic_dec ''' cdef: Py_ssize_t i, n object prev, cur - bint is_unique = 1 bint is_monotonic_inc = 1 bint is_monotonic_dec = 1 @@ -1913,45 +1945,52 @@ def is_monotonic_object(ndarray[object] arr, bint timelike): if n == 1: if arr[0] != arr[0] or (timelike and arr[0] == iNaT): # single value is NaN - return False, False, True + return False, False else: - return True, True, True + return True, True elif n < 2: - return True, True, True + return True, True if timelike and arr[0] == iNaT: - return False, False, None + return False, False + prev = arr[0] for i in range(1, n): cur = arr[i] if timelike and cur == iNaT: - return False, False, None + is_monotonic_inc = 0 + is_monotonic_dec = 0 + break if cur < prev: is_monotonic_inc = 0 elif cur > prev: is_monotonic_dec = 0 elif cur == prev: - is_unique = 0 + pass # is_unique = 0 else: # cur or prev is NaN - return False, False, None + is_monotonic_inc = 0 + is_monotonic_dec = 0 + break if not is_monotonic_inc and not is_monotonic_dec: - return False, False, None + is_monotonic_inc = 0 + is_monotonic_dec = 0 + break prev = cur - return is_monotonic_inc, is_monotonic_dec, is_unique + return is_monotonic_inc, is_monotonic_dec + @cython.boundscheck(False) @cython.wraparound(False) def is_monotonic_int32(ndarray[int32_t] arr, bint timelike): ''' Returns ------- - is_monotonic_inc, is_monotonic_dec, is_unique + is_monotonic_inc, is_monotonic_dec ''' cdef: Py_ssize_t i, n int32_t prev, cur - bint is_unique = 1 bint is_monotonic_inc = 1 bint is_monotonic_dec = 1 @@ -1960,45 +1999,52 @@ def is_monotonic_int32(ndarray[int32_t] arr, bint timelike): if n == 1: if arr[0] != arr[0] or (timelike and arr[0] == iNaT): # single value is NaN - return False, False, True + return False, False else: - return True, True, True + return True, True elif n < 2: - return True, True, True + return True, True if timelike and arr[0] == iNaT: - return False, False, None + return False, False + + with nogil: + prev = arr[0] + for i in range(1, n): + cur = arr[i] + if timelike and cur == iNaT: + is_monotonic_inc = 0 + is_monotonic_dec = 0 + break + if cur < prev: + is_monotonic_inc = 0 + elif cur > prev: + is_monotonic_dec = 0 + elif cur == prev: + pass # is_unique = 0 + else: + # cur or prev is NaN + is_monotonic_inc = 0 + is_monotonic_dec = 0 + break + if not is_monotonic_inc and not is_monotonic_dec: + is_monotonic_inc = 0 + is_monotonic_dec = 0 + break + prev = cur + return is_monotonic_inc, is_monotonic_dec - prev = arr[0] - for i in range(1, n): - cur = arr[i] - if timelike and cur == iNaT: - return False, False, None - if cur < prev: - is_monotonic_inc = 0 - elif cur > prev: - is_monotonic_dec = 0 - elif cur == prev: - is_unique = 0 - else: - # cur or prev is NaN - return False, False, None - if not is_monotonic_inc and not is_monotonic_dec: - return False, False, None - prev = cur - return is_monotonic_inc, is_monotonic_dec, is_unique @cython.boundscheck(False) @cython.wraparound(False) def is_monotonic_int64(ndarray[int64_t] arr, bint timelike): ''' Returns ------- - is_monotonic_inc, is_monotonic_dec, is_unique + is_monotonic_inc, is_monotonic_dec ''' cdef: Py_ssize_t i, n int64_t prev, cur - bint is_unique = 1 bint is_monotonic_inc = 1 bint is_monotonic_dec = 1 @@ -2007,45 +2053,52 @@ def is_monotonic_int64(ndarray[int64_t] arr, bint timelike): if n == 1: if arr[0] != arr[0] or (timelike and arr[0] == iNaT): # single value is NaN - return False, False, True + return False, False else: - return True, True, True + return True, True elif n < 2: - return True, True, True + return True, True if timelike and arr[0] == iNaT: - return False, False, None + return False, False + + with nogil: + prev = arr[0] + for i in range(1, n): + cur = arr[i] + if timelike and cur == iNaT: + is_monotonic_inc = 0 + is_monotonic_dec = 0 + break + if cur < prev: + is_monotonic_inc = 0 + elif cur > prev: + is_monotonic_dec = 0 + elif cur == prev: + pass # is_unique = 0 + else: + # cur or prev is NaN + is_monotonic_inc = 0 + is_monotonic_dec = 0 + break + if not is_monotonic_inc and not is_monotonic_dec: + is_monotonic_inc = 0 + is_monotonic_dec = 0 + break + prev = cur + return is_monotonic_inc, is_monotonic_dec - prev = arr[0] - for i in range(1, n): - cur = arr[i] - if timelike and cur == iNaT: - return False, False, None - if cur < prev: - is_monotonic_inc = 0 - elif cur > prev: - is_monotonic_dec = 0 - elif cur == prev: - is_unique = 0 - else: - # cur or prev is NaN - return False, False, None - if not is_monotonic_inc and not is_monotonic_dec: - return False, False, None - prev = cur - return is_monotonic_inc, is_monotonic_dec, is_unique @cython.boundscheck(False) @cython.wraparound(False) def is_monotonic_bool(ndarray[uint8_t] arr, bint timelike): ''' Returns ------- - is_monotonic_inc, is_monotonic_dec, is_unique + is_monotonic_inc, is_monotonic_dec ''' cdef: Py_ssize_t i, n uint8_t prev, cur - bint is_unique = 1 bint is_monotonic_inc = 1 bint is_monotonic_dec = 1 @@ -2054,33 +2107,41 @@ def is_monotonic_bool(ndarray[uint8_t] arr, bint timelike): if n == 1: if arr[0] != arr[0] or (timelike and arr[0] == iNaT): # single value is NaN - return False, False, True + return False, False else: - return True, True, True + return True, True elif n < 2: - return True, True, True + return True, True if timelike and arr[0] == iNaT: - return False, False, None + return False, False + + with nogil: + prev = arr[0] + for i in range(1, n): + cur = arr[i] + if timelike and cur == iNaT: + is_monotonic_inc = 0 + is_monotonic_dec = 0 + break + if cur < prev: + is_monotonic_inc = 0 + elif cur > prev: + is_monotonic_dec = 0 + elif cur == prev: + pass # is_unique = 0 + else: + # cur or prev is NaN + is_monotonic_inc = 0 + is_monotonic_dec = 0 + break + if not is_monotonic_inc and not is_monotonic_dec: + is_monotonic_inc = 0 + is_monotonic_dec = 0 + break + prev = cur + return is_monotonic_inc, is_monotonic_dec - prev = arr[0] - for i in range(1, n): - cur = arr[i] - if timelike and cur == iNaT: - return False, False, None - if cur < prev: - is_monotonic_inc = 0 - elif cur > prev: - is_monotonic_dec = 0 - elif cur == prev: - is_unique = 0 - else: - # cur or prev is NaN - return False, False, None - if not is_monotonic_inc and not is_monotonic_dec: - return False, False, None - prev = cur - return is_monotonic_inc, is_monotonic_dec, is_unique @cython.wraparound(False) @cython.boundscheck(False) @@ -2342,37 +2403,45 @@ def arrmap_bool(ndarray[uint8_t] index, object func): return maybe_convert_objects(result) + @cython.wraparound(False) -def take_1d_bool_bool(ndarray[uint8_t] values, - ndarray[int64_t] indexer, - ndarray[uint8_t] out, +@cython.boundscheck(False) +def take_1d_bool_bool(uint8_t[:] values, + int64_t[:] indexer, + uint8_t[:] out, fill_value=np.nan): cdef: Py_ssize_t i, n, idx uint8_t fv - n = len(indexer) + n = indexer.shape[0] fv = fill_value - for i from 0 <= i < n: - idx = indexer[i] - if idx == -1: - out[i] = fv - else: - out[i] = values[idx] + + with nogil: + for i from 0 <= i < n: + idx = indexer[i] + if idx == -1: + out[i] = fv + else: + out[i] = values[idx] + @cython.wraparound(False) -def take_1d_bool_object(ndarray[uint8_t] values, - ndarray[int64_t] indexer, - ndarray[object] out, +@cython.boundscheck(False) +def take_1d_bool_object(uint8_t[:] values, + int64_t[:] indexer, + object[:] out, fill_value=np.nan): cdef: Py_ssize_t i, n, idx object fv - n = len(indexer) + n = indexer.shape[0] fv = fill_value + + for i from 0 <= i < n: idx = indexer[i] if idx == -1: @@ -2380,18 +2449,22 @@ def take_1d_bool_object(ndarray[uint8_t] values, else: out[i] = True if values[idx] > 0 else False + @cython.wraparound(False) -def take_1d_int8_int8(ndarray[int8_t] values, - ndarray[int64_t] indexer, - ndarray[int8_t] out, +@cython.boundscheck(False) +def take_1d_int8_int8(int8_t[:] values, + int64_t[:] indexer, + int8_t[:] out, fill_value=np.nan): cdef: Py_ssize_t i, n, idx int8_t fv - n = len(indexer) + n = indexer.shape[0] fv = fill_value + + for i from 0 <= i < n: idx = indexer[i] if idx == -1: @@ -2399,303 +2472,367 @@ def take_1d_int8_int8(ndarray[int8_t] values, else: out[i] = values[idx] + @cython.wraparound(False) -def take_1d_int8_int32(ndarray[int8_t] values, - ndarray[int64_t] indexer, - ndarray[int32_t] out, +@cython.boundscheck(False) +def take_1d_int8_int32(int8_t[:] values, + int64_t[:] indexer, + int32_t[:] out, fill_value=np.nan): cdef: Py_ssize_t i, n, idx int32_t fv - n = len(indexer) + n = indexer.shape[0] fv = fill_value - for i from 0 <= i < n: - idx = indexer[i] - if idx == -1: - out[i] = fv - else: - out[i] = values[idx] + + with nogil: + for i from 0 <= i < n: + idx = indexer[i] + if idx == -1: + out[i] = fv + else: + out[i] = values[idx] + @cython.wraparound(False) -def take_1d_int8_int64(ndarray[int8_t] values, - ndarray[int64_t] indexer, - ndarray[int64_t] out, +@cython.boundscheck(False) +def take_1d_int8_int64(int8_t[:] values, + int64_t[:] indexer, + int64_t[:] out, fill_value=np.nan): cdef: Py_ssize_t i, n, idx int64_t fv - n = len(indexer) + n = indexer.shape[0] fv = fill_value - for i from 0 <= i < n: - idx = indexer[i] - if idx == -1: - out[i] = fv - else: - out[i] = values[idx] + + with nogil: + for i from 0 <= i < n: + idx = indexer[i] + if idx == -1: + out[i] = fv + else: + out[i] = values[idx] + @cython.wraparound(False) -def take_1d_int8_float64(ndarray[int8_t] values, - ndarray[int64_t] indexer, - ndarray[float64_t] out, +@cython.boundscheck(False) +def take_1d_int8_float64(int8_t[:] values, + int64_t[:] indexer, + float64_t[:] out, fill_value=np.nan): cdef: Py_ssize_t i, n, idx float64_t fv - n = len(indexer) + n = indexer.shape[0] fv = fill_value - for i from 0 <= i < n: - idx = indexer[i] - if idx == -1: - out[i] = fv - else: - out[i] = values[idx] + + with nogil: + for i from 0 <= i < n: + idx = indexer[i] + if idx == -1: + out[i] = fv + else: + out[i] = values[idx] + @cython.wraparound(False) -def take_1d_int16_int16(ndarray[int16_t] values, - ndarray[int64_t] indexer, - ndarray[int16_t] out, +@cython.boundscheck(False) +def take_1d_int16_int16(int16_t[:] values, + int64_t[:] indexer, + int16_t[:] out, fill_value=np.nan): cdef: Py_ssize_t i, n, idx int16_t fv - n = len(indexer) + n = indexer.shape[0] fv = fill_value - for i from 0 <= i < n: - idx = indexer[i] - if idx == -1: - out[i] = fv - else: - out[i] = values[idx] + + with nogil: + for i from 0 <= i < n: + idx = indexer[i] + if idx == -1: + out[i] = fv + else: + out[i] = values[idx] + @cython.wraparound(False) -def take_1d_int16_int32(ndarray[int16_t] values, - ndarray[int64_t] indexer, - ndarray[int32_t] out, +@cython.boundscheck(False) +def take_1d_int16_int32(int16_t[:] values, + int64_t[:] indexer, + int32_t[:] out, fill_value=np.nan): cdef: Py_ssize_t i, n, idx int32_t fv - n = len(indexer) + n = indexer.shape[0] fv = fill_value - for i from 0 <= i < n: - idx = indexer[i] - if idx == -1: - out[i] = fv - else: - out[i] = values[idx] + + with nogil: + for i from 0 <= i < n: + idx = indexer[i] + if idx == -1: + out[i] = fv + else: + out[i] = values[idx] + @cython.wraparound(False) -def take_1d_int16_int64(ndarray[int16_t] values, - ndarray[int64_t] indexer, - ndarray[int64_t] out, +@cython.boundscheck(False) +def take_1d_int16_int64(int16_t[:] values, + int64_t[:] indexer, + int64_t[:] out, fill_value=np.nan): cdef: Py_ssize_t i, n, idx int64_t fv - n = len(indexer) + n = indexer.shape[0] fv = fill_value - for i from 0 <= i < n: - idx = indexer[i] - if idx == -1: - out[i] = fv - else: - out[i] = values[idx] + + with nogil: + for i from 0 <= i < n: + idx = indexer[i] + if idx == -1: + out[i] = fv + else: + out[i] = values[idx] + @cython.wraparound(False) -def take_1d_int16_float64(ndarray[int16_t] values, - ndarray[int64_t] indexer, - ndarray[float64_t] out, +@cython.boundscheck(False) +def take_1d_int16_float64(int16_t[:] values, + int64_t[:] indexer, + float64_t[:] out, fill_value=np.nan): cdef: Py_ssize_t i, n, idx float64_t fv - n = len(indexer) + n = indexer.shape[0] fv = fill_value - for i from 0 <= i < n: - idx = indexer[i] - if idx == -1: - out[i] = fv - else: - out[i] = values[idx] + + with nogil: + for i from 0 <= i < n: + idx = indexer[i] + if idx == -1: + out[i] = fv + else: + out[i] = values[idx] + @cython.wraparound(False) -def take_1d_int32_int32(ndarray[int32_t] values, - ndarray[int64_t] indexer, - ndarray[int32_t] out, +@cython.boundscheck(False) +def take_1d_int32_int32(int32_t[:] values, + int64_t[:] indexer, + int32_t[:] out, fill_value=np.nan): cdef: Py_ssize_t i, n, idx int32_t fv - n = len(indexer) + n = indexer.shape[0] fv = fill_value - for i from 0 <= i < n: - idx = indexer[i] - if idx == -1: - out[i] = fv - else: - out[i] = values[idx] + + with nogil: + for i from 0 <= i < n: + idx = indexer[i] + if idx == -1: + out[i] = fv + else: + out[i] = values[idx] + @cython.wraparound(False) -def take_1d_int32_int64(ndarray[int32_t] values, - ndarray[int64_t] indexer, - ndarray[int64_t] out, +@cython.boundscheck(False) +def take_1d_int32_int64(int32_t[:] values, + int64_t[:] indexer, + int64_t[:] out, fill_value=np.nan): cdef: Py_ssize_t i, n, idx int64_t fv - n = len(indexer) + n = indexer.shape[0] fv = fill_value - for i from 0 <= i < n: - idx = indexer[i] - if idx == -1: - out[i] = fv - else: - out[i] = values[idx] + + with nogil: + for i from 0 <= i < n: + idx = indexer[i] + if idx == -1: + out[i] = fv + else: + out[i] = values[idx] + @cython.wraparound(False) -def take_1d_int32_float64(ndarray[int32_t] values, - ndarray[int64_t] indexer, - ndarray[float64_t] out, +@cython.boundscheck(False) +def take_1d_int32_float64(int32_t[:] values, + int64_t[:] indexer, + float64_t[:] out, fill_value=np.nan): cdef: Py_ssize_t i, n, idx float64_t fv - n = len(indexer) + n = indexer.shape[0] fv = fill_value - for i from 0 <= i < n: - idx = indexer[i] - if idx == -1: - out[i] = fv - else: - out[i] = values[idx] -@cython.wraparound(False) -def take_1d_int64_int64(ndarray[int64_t] values, - ndarray[int64_t] indexer, - ndarray[int64_t] out, + with nogil: + for i from 0 <= i < n: + idx = indexer[i] + if idx == -1: + out[i] = fv + else: + out[i] = values[idx] + + +@cython.wraparound(False) +@cython.boundscheck(False) +def take_1d_int64_int64(int64_t[:] values, + int64_t[:] indexer, + int64_t[:] out, fill_value=np.nan): cdef: Py_ssize_t i, n, idx int64_t fv - n = len(indexer) + n = indexer.shape[0] fv = fill_value - for i from 0 <= i < n: - idx = indexer[i] - if idx == -1: - out[i] = fv - else: - out[i] = values[idx] + + with nogil: + for i from 0 <= i < n: + idx = indexer[i] + if idx == -1: + out[i] = fv + else: + out[i] = values[idx] + @cython.wraparound(False) -def take_1d_int64_float64(ndarray[int64_t] values, - ndarray[int64_t] indexer, - ndarray[float64_t] out, +@cython.boundscheck(False) +def take_1d_int64_float64(int64_t[:] values, + int64_t[:] indexer, + float64_t[:] out, fill_value=np.nan): cdef: Py_ssize_t i, n, idx float64_t fv - n = len(indexer) + n = indexer.shape[0] fv = fill_value - for i from 0 <= i < n: - idx = indexer[i] - if idx == -1: - out[i] = fv - else: - out[i] = values[idx] + + with nogil: + for i from 0 <= i < n: + idx = indexer[i] + if idx == -1: + out[i] = fv + else: + out[i] = values[idx] + @cython.wraparound(False) -def take_1d_float32_float32(ndarray[float32_t] values, - ndarray[int64_t] indexer, - ndarray[float32_t] out, +@cython.boundscheck(False) +def take_1d_float32_float32(float32_t[:] values, + int64_t[:] indexer, + float32_t[:] out, fill_value=np.nan): cdef: Py_ssize_t i, n, idx float32_t fv - n = len(indexer) + n = indexer.shape[0] fv = fill_value - for i from 0 <= i < n: - idx = indexer[i] - if idx == -1: - out[i] = fv - else: - out[i] = values[idx] + + with nogil: + for i from 0 <= i < n: + idx = indexer[i] + if idx == -1: + out[i] = fv + else: + out[i] = values[idx] + @cython.wraparound(False) -def take_1d_float32_float64(ndarray[float32_t] values, - ndarray[int64_t] indexer, - ndarray[float64_t] out, +@cython.boundscheck(False) +def take_1d_float32_float64(float32_t[:] values, + int64_t[:] indexer, + float64_t[:] out, fill_value=np.nan): cdef: Py_ssize_t i, n, idx float64_t fv - n = len(indexer) + n = indexer.shape[0] fv = fill_value - for i from 0 <= i < n: - idx = indexer[i] - if idx == -1: - out[i] = fv - else: - out[i] = values[idx] + + with nogil: + for i from 0 <= i < n: + idx = indexer[i] + if idx == -1: + out[i] = fv + else: + out[i] = values[idx] + @cython.wraparound(False) -def take_1d_float64_float64(ndarray[float64_t] values, - ndarray[int64_t] indexer, - ndarray[float64_t] out, +@cython.boundscheck(False) +def take_1d_float64_float64(float64_t[:] values, + int64_t[:] indexer, + float64_t[:] out, fill_value=np.nan): cdef: Py_ssize_t i, n, idx float64_t fv - n = len(indexer) + n = indexer.shape[0] fv = fill_value - for i from 0 <= i < n: - idx = indexer[i] - if idx == -1: - out[i] = fv - else: - out[i] = values[idx] + + with nogil: + for i from 0 <= i < n: + idx = indexer[i] + if idx == -1: + out[i] = fv + else: + out[i] = values[idx] + @cython.wraparound(False) -def take_1d_object_object(ndarray[object] values, - ndarray[int64_t] indexer, - ndarray[object] out, +@cython.boundscheck(False) +def take_1d_object_object(object[:] values, + int64_t[:] indexer, + object[:] out, fill_value=np.nan): cdef: Py_ssize_t i, n, idx object fv - n = len(indexer) + n = indexer.shape[0] fv = fill_value + + for i from 0 <= i < n: idx = indexer[i] if idx == -1: @@ -2750,7 +2887,6 @@ cdef inline take_2d_axis0_bool_bool_memview(uint8_t[:, :] values, out[i, j] = values[idx, j] - @cython.wraparound(False) @cython.boundscheck(False) def take_2d_axis0_bool_bool(ndarray[uint8_t, ndim=2] values, @@ -2851,7 +2987,6 @@ cdef inline take_2d_axis0_bool_object_memview(uint8_t[:, :] values, out[i, j] = True if values[idx, j] > 0 else False - @cython.wraparound(False) @cython.boundscheck(False) def take_2d_axis0_bool_object(ndarray[uint8_t, ndim=2] values, @@ -2952,7 +3087,6 @@ cdef inline take_2d_axis0_int8_int8_memview(int8_t[:, :] values, out[i, j] = values[idx, j] - @cython.wraparound(False) @cython.boundscheck(False) def take_2d_axis0_int8_int8(ndarray[int8_t, ndim=2] values, @@ -3053,7 +3187,6 @@ cdef inline take_2d_axis0_int8_int32_memview(int8_t[:, :] values, out[i, j] = values[idx, j] - @cython.wraparound(False) @cython.boundscheck(False) def take_2d_axis0_int8_int32(ndarray[int8_t, ndim=2] values, @@ -3154,7 +3287,6 @@ cdef inline take_2d_axis0_int8_int64_memview(int8_t[:, :] values, out[i, j] = values[idx, j] - @cython.wraparound(False) @cython.boundscheck(False) def take_2d_axis0_int8_int64(ndarray[int8_t, ndim=2] values, @@ -3255,7 +3387,6 @@ cdef inline take_2d_axis0_int8_float64_memview(int8_t[:, :] values, out[i, j] = values[idx, j] - @cython.wraparound(False) @cython.boundscheck(False) def take_2d_axis0_int8_float64(ndarray[int8_t, ndim=2] values, @@ -3356,7 +3487,6 @@ cdef inline take_2d_axis0_int16_int16_memview(int16_t[:, :] values, out[i, j] = values[idx, j] - @cython.wraparound(False) @cython.boundscheck(False) def take_2d_axis0_int16_int16(ndarray[int16_t, ndim=2] values, @@ -3457,7 +3587,6 @@ cdef inline take_2d_axis0_int16_int32_memview(int16_t[:, :] values, out[i, j] = values[idx, j] - @cython.wraparound(False) @cython.boundscheck(False) def take_2d_axis0_int16_int32(ndarray[int16_t, ndim=2] values, @@ -3558,7 +3687,6 @@ cdef inline take_2d_axis0_int16_int64_memview(int16_t[:, :] values, out[i, j] = values[idx, j] - @cython.wraparound(False) @cython.boundscheck(False) def take_2d_axis0_int16_int64(ndarray[int16_t, ndim=2] values, @@ -3659,7 +3787,6 @@ cdef inline take_2d_axis0_int16_float64_memview(int16_t[:, :] values, out[i, j] = values[idx, j] - @cython.wraparound(False) @cython.boundscheck(False) def take_2d_axis0_int16_float64(ndarray[int16_t, ndim=2] values, @@ -3760,7 +3887,6 @@ cdef inline take_2d_axis0_int32_int32_memview(int32_t[:, :] values, out[i, j] = values[idx, j] - @cython.wraparound(False) @cython.boundscheck(False) def take_2d_axis0_int32_int32(ndarray[int32_t, ndim=2] values, @@ -3861,7 +3987,6 @@ cdef inline take_2d_axis0_int32_int64_memview(int32_t[:, :] values, out[i, j] = values[idx, j] - @cython.wraparound(False) @cython.boundscheck(False) def take_2d_axis0_int32_int64(ndarray[int32_t, ndim=2] values, @@ -3962,7 +4087,6 @@ cdef inline take_2d_axis0_int32_float64_memview(int32_t[:, :] values, out[i, j] = values[idx, j] - @cython.wraparound(False) @cython.boundscheck(False) def take_2d_axis0_int32_float64(ndarray[int32_t, ndim=2] values, @@ -4063,7 +4187,6 @@ cdef inline take_2d_axis0_int64_int64_memview(int64_t[:, :] values, out[i, j] = values[idx, j] - @cython.wraparound(False) @cython.boundscheck(False) def take_2d_axis0_int64_int64(ndarray[int64_t, ndim=2] values, @@ -4164,7 +4287,6 @@ cdef inline take_2d_axis0_int64_float64_memview(int64_t[:, :] values, out[i, j] = values[idx, j] - @cython.wraparound(False) @cython.boundscheck(False) def take_2d_axis0_int64_float64(ndarray[int64_t, ndim=2] values, @@ -4265,7 +4387,6 @@ cdef inline take_2d_axis0_float32_float32_memview(float32_t[:, :] values, out[i, j] = values[idx, j] - @cython.wraparound(False) @cython.boundscheck(False) def take_2d_axis0_float32_float32(ndarray[float32_t, ndim=2] values, @@ -4366,7 +4487,6 @@ cdef inline take_2d_axis0_float32_float64_memview(float32_t[:, :] values, out[i, j] = values[idx, j] - @cython.wraparound(False) @cython.boundscheck(False) def take_2d_axis0_float32_float64(ndarray[float32_t, ndim=2] values, @@ -4467,7 +4587,6 @@ cdef inline take_2d_axis0_float64_float64_memview(float64_t[:, :] values, out[i, j] = values[idx, j] - @cython.wraparound(False) @cython.boundscheck(False) def take_2d_axis0_float64_float64(ndarray[float64_t, ndim=2] values, @@ -4568,7 +4687,6 @@ cdef inline take_2d_axis0_object_object_memview(object[:, :] values, out[i, j] = values[idx, j] - @cython.wraparound(False) @cython.boundscheck(False) def take_2d_axis0_object_object(ndarray[object, ndim=2] values, @@ -4686,6 +4804,7 @@ def take_2d_axis1_bool_bool(ndarray[uint8_t, ndim=2] values, out[i, j] = fv else: out[i, j] = values[i, idx] + @cython.wraparound(False) @cython.boundscheck(False) cdef inline take_2d_axis1_bool_object_memview(uint8_t[:, :] values, @@ -4748,6 +4867,7 @@ def take_2d_axis1_bool_object(ndarray[uint8_t, ndim=2] values, out[i, j] = fv else: out[i, j] = True if values[i, idx] > 0 else False + @cython.wraparound(False) @cython.boundscheck(False) cdef inline take_2d_axis1_int8_int8_memview(int8_t[:, :] values, @@ -4810,6 +4930,7 @@ def take_2d_axis1_int8_int8(ndarray[int8_t, ndim=2] values, out[i, j] = fv else: out[i, j] = values[i, idx] + @cython.wraparound(False) @cython.boundscheck(False) cdef inline take_2d_axis1_int8_int32_memview(int8_t[:, :] values, @@ -4872,6 +4993,7 @@ def take_2d_axis1_int8_int32(ndarray[int8_t, ndim=2] values, out[i, j] = fv else: out[i, j] = values[i, idx] + @cython.wraparound(False) @cython.boundscheck(False) cdef inline take_2d_axis1_int8_int64_memview(int8_t[:, :] values, @@ -4934,6 +5056,7 @@ def take_2d_axis1_int8_int64(ndarray[int8_t, ndim=2] values, out[i, j] = fv else: out[i, j] = values[i, idx] + @cython.wraparound(False) @cython.boundscheck(False) cdef inline take_2d_axis1_int8_float64_memview(int8_t[:, :] values, @@ -4996,6 +5119,7 @@ def take_2d_axis1_int8_float64(ndarray[int8_t, ndim=2] values, out[i, j] = fv else: out[i, j] = values[i, idx] + @cython.wraparound(False) @cython.boundscheck(False) cdef inline take_2d_axis1_int16_int16_memview(int16_t[:, :] values, @@ -5058,6 +5182,7 @@ def take_2d_axis1_int16_int16(ndarray[int16_t, ndim=2] values, out[i, j] = fv else: out[i, j] = values[i, idx] + @cython.wraparound(False) @cython.boundscheck(False) cdef inline take_2d_axis1_int16_int32_memview(int16_t[:, :] values, @@ -5120,6 +5245,7 @@ def take_2d_axis1_int16_int32(ndarray[int16_t, ndim=2] values, out[i, j] = fv else: out[i, j] = values[i, idx] + @cython.wraparound(False) @cython.boundscheck(False) cdef inline take_2d_axis1_int16_int64_memview(int16_t[:, :] values, @@ -5182,6 +5308,7 @@ def take_2d_axis1_int16_int64(ndarray[int16_t, ndim=2] values, out[i, j] = fv else: out[i, j] = values[i, idx] + @cython.wraparound(False) @cython.boundscheck(False) cdef inline take_2d_axis1_int16_float64_memview(int16_t[:, :] values, @@ -5244,6 +5371,7 @@ def take_2d_axis1_int16_float64(ndarray[int16_t, ndim=2] values, out[i, j] = fv else: out[i, j] = values[i, idx] + @cython.wraparound(False) @cython.boundscheck(False) cdef inline take_2d_axis1_int32_int32_memview(int32_t[:, :] values, @@ -5306,6 +5434,7 @@ def take_2d_axis1_int32_int32(ndarray[int32_t, ndim=2] values, out[i, j] = fv else: out[i, j] = values[i, idx] + @cython.wraparound(False) @cython.boundscheck(False) cdef inline take_2d_axis1_int32_int64_memview(int32_t[:, :] values, @@ -5368,6 +5497,7 @@ def take_2d_axis1_int32_int64(ndarray[int32_t, ndim=2] values, out[i, j] = fv else: out[i, j] = values[i, idx] + @cython.wraparound(False) @cython.boundscheck(False) cdef inline take_2d_axis1_int32_float64_memview(int32_t[:, :] values, @@ -5430,6 +5560,7 @@ def take_2d_axis1_int32_float64(ndarray[int32_t, ndim=2] values, out[i, j] = fv else: out[i, j] = values[i, idx] + @cython.wraparound(False) @cython.boundscheck(False) cdef inline take_2d_axis1_int64_int64_memview(int64_t[:, :] values, @@ -5492,6 +5623,7 @@ def take_2d_axis1_int64_int64(ndarray[int64_t, ndim=2] values, out[i, j] = fv else: out[i, j] = values[i, idx] + @cython.wraparound(False) @cython.boundscheck(False) cdef inline take_2d_axis1_int64_float64_memview(int64_t[:, :] values, @@ -5554,6 +5686,7 @@ def take_2d_axis1_int64_float64(ndarray[int64_t, ndim=2] values, out[i, j] = fv else: out[i, j] = values[i, idx] + @cython.wraparound(False) @cython.boundscheck(False) cdef inline take_2d_axis1_float32_float32_memview(float32_t[:, :] values, @@ -5616,6 +5749,7 @@ def take_2d_axis1_float32_float32(ndarray[float32_t, ndim=2] values, out[i, j] = fv else: out[i, j] = values[i, idx] + @cython.wraparound(False) @cython.boundscheck(False) cdef inline take_2d_axis1_float32_float64_memview(float32_t[:, :] values, @@ -5678,6 +5812,7 @@ def take_2d_axis1_float32_float64(ndarray[float32_t, ndim=2] values, out[i, j] = fv else: out[i, j] = values[i, idx] + @cython.wraparound(False) @cython.boundscheck(False) cdef inline take_2d_axis1_float64_float64_memview(float64_t[:, :] values, @@ -5740,6 +5875,7 @@ def take_2d_axis1_float64_float64(ndarray[float64_t, ndim=2] values, out[i, j] = fv else: out[i, j] = values[i, idx] + @cython.wraparound(False) @cython.boundscheck(False) cdef inline take_2d_axis1_object_object_memview(object[:, :] values, @@ -5803,6 +5939,7 @@ def take_2d_axis1_object_object(ndarray[object, ndim=2] values, else: out[i, j] = values[i, idx] + @cython.wraparound(False) @cython.boundscheck(False) def take_2d_multi_bool_bool(ndarray[uint8_t, ndim=2] values, @@ -6379,6 +6516,7 @@ def diff_2d_float64(ndarray[float64_t, ndim=2] arr, for i in range(sx): for j in range(start, stop): out[i, j] = arr[i, j] - arr[i, j - periods] + @cython.boundscheck(False) @cython.wraparound(False) def diff_2d_float32(ndarray[float32_t, ndim=2] arr, @@ -6422,6 +6560,7 @@ def diff_2d_float32(ndarray[float32_t, ndim=2] arr, for i in range(sx): for j in range(start, stop): out[i, j] = arr[i, j] - arr[i, j - periods] + @cython.boundscheck(False) @cython.wraparound(False) def diff_2d_int8(ndarray[int8_t, ndim=2] arr, @@ -6465,6 +6604,7 @@ def diff_2d_int8(ndarray[int8_t, ndim=2] arr, for i in range(sx): for j in range(start, stop): out[i, j] = arr[i, j] - arr[i, j - periods] + @cython.boundscheck(False) @cython.wraparound(False) def diff_2d_int16(ndarray[int16_t, ndim=2] arr, @@ -6508,6 +6648,7 @@ def diff_2d_int16(ndarray[int16_t, ndim=2] arr, for i in range(sx): for j in range(start, stop): out[i, j] = arr[i, j] - arr[i, j - periods] + @cython.boundscheck(False) @cython.wraparound(False) def diff_2d_int32(ndarray[int32_t, ndim=2] arr, @@ -6551,6 +6692,7 @@ def diff_2d_int32(ndarray[int32_t, ndim=2] arr, for i in range(sx): for j in range(start, stop): out[i, j] = arr[i, j] - arr[i, j - periods] + @cython.boundscheck(False) @cython.wraparound(False) def diff_2d_int64(ndarray[int64_t, ndim=2] arr, @@ -6595,8 +6737,9 @@ def diff_2d_int64(ndarray[int64_t, ndim=2] arr, for j in range(start, stop): out[i, j] = arr[i, j] - arr[i, j - periods] -@cython.boundscheck(False) + @cython.wraparound(False) +@cython.boundscheck(False) def group_add_float64(ndarray[float64_t, ndim=2] out, ndarray[int64_t] counts, ndarray[float64_t, ndim=2] values, @@ -6605,7 +6748,7 @@ def group_add_float64(ndarray[float64_t, ndim=2] out, Only aggregates on axis=0 ''' cdef: - Py_ssize_t i, j, N, K, lab + Py_ssize_t i, j, N, K, lab, ncounts = len(counts) float64_t val, count ndarray[float64_t, ndim=2] sumx, nobs @@ -6617,42 +6760,49 @@ def group_add_float64(ndarray[float64_t, ndim=2] out, N, K = ( values).shape - if K > 1: - for i in range(N): - lab = labels[i] - if lab < 0: - continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + with nogil: + + if K > 1: + + for i in range(N): + lab = labels[i] + if lab < 0: + continue + + counts[lab] += 1 + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[lab, j] += 1 + sumx[lab, j] += val + + else: + + for i in range(N): + lab = labels[i] + if lab < 0: + continue + + counts[lab] += 1 + val = values[i, 0] # not nan if val == val: - nobs[lab, j] += 1 - sumx[lab, j] += val - else: - for i in range(N): - lab = labels[i] - if lab < 0: - continue - - counts[lab] += 1 - val = values[i, 0] + nobs[lab, 0] += 1 + sumx[lab, 0] += val - # not nan - if val == val: - nobs[lab, 0] += 1 - sumx[lab, 0] += val + for i in range(ncounts): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = sumx[i, j] - for i in range(len(counts)): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = sumx[i, j] -@cython.boundscheck(False) @cython.wraparound(False) +@cython.boundscheck(False) def group_add_float32(ndarray[float32_t, ndim=2] out, ndarray[int64_t] counts, ndarray[float32_t, ndim=2] values, @@ -6661,7 +6811,7 @@ def group_add_float32(ndarray[float32_t, ndim=2] out, Only aggregates on axis=0 ''' cdef: - Py_ssize_t i, j, N, K, lab + Py_ssize_t i, j, N, K, lab, ncounts = len(counts) float32_t val, count ndarray[float32_t, ndim=2] sumx, nobs @@ -6673,43 +6823,50 @@ def group_add_float32(ndarray[float32_t, ndim=2] out, N, K = ( values).shape - if K > 1: - for i in range(N): - lab = labels[i] - if lab < 0: - continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + with nogil: + + if K > 1: + + for i in range(N): + lab = labels[i] + if lab < 0: + continue + + counts[lab] += 1 + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[lab, j] += 1 + sumx[lab, j] += val + + else: + + for i in range(N): + lab = labels[i] + if lab < 0: + continue + + counts[lab] += 1 + val = values[i, 0] # not nan if val == val: - nobs[lab, j] += 1 - sumx[lab, j] += val - else: - for i in range(N): - lab = labels[i] - if lab < 0: - continue - - counts[lab] += 1 - val = values[i, 0] + nobs[lab, 0] += 1 + sumx[lab, 0] += val - # not nan - if val == val: - nobs[lab, 0] += 1 - sumx[lab, 0] += val + for i in range(ncounts): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = sumx[i, j] - for i in range(len(counts)): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = sumx[i, j] -@cython.boundscheck(False) @cython.wraparound(False) +@cython.boundscheck(False) def group_add_bin_float64(ndarray[float64_t, ndim=2] out, ndarray[int64_t] counts, ndarray[float64_t, ndim=2] values, @@ -6725,47 +6882,53 @@ def group_add_bin_float64(ndarray[float64_t, ndim=2] out, nobs = np.zeros_like(out) sumx = np.zeros_like(out) + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: ngroups = len(bins) + 1 N, K = ( values).shape - b = 0 - if K > 1: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + with nogil: - counts[b] += 1 - for j in range(K): - val = values[i, j] + b = 0 + if K > 1: + + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 + + counts[b] += 1 + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[b, j] += 1 + sumx[b, j] += val + else: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 + + counts[b] += 1 + val = values[i, 0] # not nan if val == val: - nobs[b, j] += 1 - sumx[b, j] += val - else: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 - - counts[b] += 1 - val = values[i, 0] + nobs[b, 0] += 1 + sumx[b, 0] += val - # not nan - if val == val: - nobs[b, 0] += 1 - sumx[b, 0] += val + for i in range(ngroups): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = sumx[i, j] - for i in range(ngroups): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = sumx[i, j] -@cython.boundscheck(False) @cython.wraparound(False) +@cython.boundscheck(False) def group_add_bin_float32(ndarray[float32_t, ndim=2] out, ndarray[int64_t] counts, ndarray[float32_t, ndim=2] values, @@ -6781,48 +6944,54 @@ def group_add_bin_float32(ndarray[float32_t, ndim=2] out, nobs = np.zeros_like(out) sumx = np.zeros_like(out) + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: ngroups = len(bins) + 1 N, K = ( values).shape - b = 0 - if K > 1: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + with nogil: - counts[b] += 1 - for j in range(K): - val = values[i, j] + b = 0 + if K > 1: + + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 + + counts[b] += 1 + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[b, j] += 1 + sumx[b, j] += val + else: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 + + counts[b] += 1 + val = values[i, 0] # not nan if val == val: - nobs[b, j] += 1 - sumx[b, j] += val - else: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + nobs[b, 0] += 1 + sumx[b, 0] += val - counts[b] += 1 - val = values[i, 0] - - # not nan - if val == val: - nobs[b, 0] += 1 - sumx[b, 0] += val + for i in range(ngroups): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = sumx[i, j] - for i in range(ngroups): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = sumx[i, j] -@cython.boundscheck(False) @cython.wraparound(False) +@cython.boundscheck(False) def group_prod_float64(ndarray[float64_t, ndim=2] out, ndarray[int64_t] counts, ndarray[float64_t, ndim=2] values, @@ -6831,7 +7000,7 @@ def group_prod_float64(ndarray[float64_t, ndim=2] out, Only aggregates on axis=0 ''' cdef: - Py_ssize_t i, j, N, K, lab + Py_ssize_t i, j, N, K, lab, ncounts = len(counts) float64_t val, count ndarray[float64_t, ndim=2] prodx, nobs @@ -6843,42 +7012,44 @@ def group_prod_float64(ndarray[float64_t, ndim=2] out, N, K = ( values).shape - if K > 1: - for i in range(N): - lab = labels[i] - if lab < 0: - continue + with nogil: + if K > 1: + for i in range(N): + lab = labels[i] + if lab < 0: + continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + counts[lab] += 1 + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[lab, j] += 1 + prodx[lab, j] *= val + else: + for i in range(N): + lab = labels[i] + if lab < 0: + continue + + counts[lab] += 1 + val = values[i, 0] # not nan if val == val: - nobs[lab, j] += 1 - prodx[lab, j] *= val - else: - for i in range(N): - lab = labels[i] - if lab < 0: - continue - - counts[lab] += 1 - val = values[i, 0] + nobs[lab, 0] += 1 + prodx[lab, 0] *= val - # not nan - if val == val: - nobs[lab, 0] += 1 - prodx[lab, 0] *= val + for i in range(ncounts): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = prodx[i, j] - for i in range(len(counts)): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = prodx[i, j] -@cython.boundscheck(False) @cython.wraparound(False) +@cython.boundscheck(False) def group_prod_float32(ndarray[float32_t, ndim=2] out, ndarray[int64_t] counts, ndarray[float32_t, ndim=2] values, @@ -6887,7 +7058,7 @@ def group_prod_float32(ndarray[float32_t, ndim=2] out, Only aggregates on axis=0 ''' cdef: - Py_ssize_t i, j, N, K, lab + Py_ssize_t i, j, N, K, lab, ncounts = len(counts) float32_t val, count ndarray[float32_t, ndim=2] prodx, nobs @@ -6899,43 +7070,45 @@ def group_prod_float32(ndarray[float32_t, ndim=2] out, N, K = ( values).shape - if K > 1: - for i in range(N): - lab = labels[i] - if lab < 0: - continue + with nogil: + if K > 1: + for i in range(N): + lab = labels[i] + if lab < 0: + continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + counts[lab] += 1 + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[lab, j] += 1 + prodx[lab, j] *= val + else: + for i in range(N): + lab = labels[i] + if lab < 0: + continue + + counts[lab] += 1 + val = values[i, 0] # not nan if val == val: - nobs[lab, j] += 1 - prodx[lab, j] *= val - else: - for i in range(N): - lab = labels[i] - if lab < 0: - continue - - counts[lab] += 1 - val = values[i, 0] + nobs[lab, 0] += 1 + prodx[lab, 0] *= val - # not nan - if val == val: - nobs[lab, 0] += 1 - prodx[lab, 0] *= val + for i in range(ncounts): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = prodx[i, j] - for i in range(len(counts)): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = prodx[i, j] -@cython.boundscheck(False) @cython.wraparound(False) +@cython.boundscheck(False) def group_prod_bin_float64(ndarray[float64_t, ndim=2] out, ndarray[int64_t] counts, ndarray[float64_t, ndim=2] values, @@ -6951,47 +7124,52 @@ def group_prod_bin_float64(ndarray[float64_t, ndim=2] out, nobs = np.zeros_like(out) prodx = np.ones_like(out) + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: ngroups = len(bins) + 1 N, K = ( values).shape - b = 0 - if K > 1: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + with nogil: - counts[b] += 1 - for j in range(K): - val = values[i, j] + b = 0 + if K > 1: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 + + counts[b] += 1 + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[b, j] += 1 + prodx[b, j] *= val + else: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 + + counts[b] += 1 + val = values[i, 0] # not nan if val == val: - nobs[b, j] += 1 - prodx[b, j] *= val - else: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + nobs[b, 0] += 1 + prodx[b, 0] *= val - counts[b] += 1 - val = values[i, 0] - - # not nan - if val == val: - nobs[b, 0] += 1 - prodx[b, 0] *= val + for i in range(ngroups): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = prodx[i, j] - for i in range(ngroups): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = prodx[i, j] -@cython.boundscheck(False) @cython.wraparound(False) +@cython.boundscheck(False) def group_prod_bin_float32(ndarray[float32_t, ndim=2] out, ndarray[int64_t] counts, ndarray[float32_t, ndim=2] values, @@ -7007,69 +7185,75 @@ def group_prod_bin_float32(ndarray[float32_t, ndim=2] out, nobs = np.zeros_like(out) prodx = np.ones_like(out) + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: ngroups = len(bins) + 1 N, K = ( values).shape - b = 0 - if K > 1: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + with nogil: - counts[b] += 1 - for j in range(K): - val = values[i, j] + b = 0 + if K > 1: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 + + counts[b] += 1 + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[b, j] += 1 + prodx[b, j] *= val + else: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 + + counts[b] += 1 + val = values[i, 0] # not nan if val == val: - nobs[b, j] += 1 - prodx[b, j] *= val - else: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + nobs[b, 0] += 1 + prodx[b, 0] *= val - counts[b] += 1 - val = values[i, 0] - - # not nan - if val == val: - nobs[b, 0] += 1 - prodx[b, 0] *= val + for i in range(ngroups): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = prodx[i, j] - for i in range(ngroups): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = prodx[i, j] @cython.wraparound(False) @cython.boundscheck(False) +@cython.cdivision(True) def group_var_float64(ndarray[float64_t, ndim=2] out, ndarray[int64_t] counts, ndarray[float64_t, ndim=2] values, ndarray[int64_t] labels): cdef: - Py_ssize_t i, j, N, K, lab - float64_t val, ct - ndarray[float64_t, ndim=2] nobs, sumx, sumxx + Py_ssize_t i, j, N, K, lab, ncounts = len(counts) + float64_t val, ct, oldmean + ndarray[float64_t, ndim=2] nobs, mean if not len(values) == len(labels): raise AssertionError("len(index) != len(labels)") nobs = np.zeros_like(out) - sumx = np.zeros_like(out) - sumxx = np.zeros_like(out) + mean = np.zeros_like(out) N, K = ( values).shape - if K > 1: - for i in range(N): + out[:, :] = 0.0 + with nogil: + for i in range(N): lab = labels[i] if lab < 0: continue @@ -7082,55 +7266,43 @@ def group_var_float64(ndarray[float64_t, ndim=2] out, # not nan if val == val: nobs[lab, j] += 1 - sumx[lab, j] += val - sumxx[lab, j] += val * val - else: - for i in range(N): - - lab = labels[i] - if lab < 0: - continue + oldmean = mean[lab, j] + mean[lab, j] += (val - oldmean) / nobs[lab, j] + out[lab, j] += (val - mean[lab, j]) * (val - oldmean) - counts[lab] += 1 - val = values[i, 0] - # not nan - if val == val: - nobs[lab, 0] += 1 - sumx[lab, 0] += val - sumxx[lab, 0] += val * val + for i in range(ncounts): + for j in range(K): + ct = nobs[i, j] + if ct < 2: + out[i, j] = NAN + else: + out[i, j] /= (ct - 1) - for i in range(len(counts)): - for j in range(K): - ct = nobs[i, j] - if ct < 2: - out[i, j] = nan - else: - out[i, j] = ((ct * sumxx[i, j] - sumx[i, j] * sumx[i, j]) / - (ct * ct - ct)) @cython.wraparound(False) @cython.boundscheck(False) +@cython.cdivision(True) def group_var_float32(ndarray[float32_t, ndim=2] out, ndarray[int64_t] counts, ndarray[float32_t, ndim=2] values, ndarray[int64_t] labels): cdef: - Py_ssize_t i, j, N, K, lab - float32_t val, ct - ndarray[float32_t, ndim=2] nobs, sumx, sumxx + Py_ssize_t i, j, N, K, lab, ncounts = len(counts) + float32_t val, ct, oldmean + ndarray[float32_t, ndim=2] nobs, mean if not len(values) == len(labels): raise AssertionError("len(index) != len(labels)") nobs = np.zeros_like(out) - sumx = np.zeros_like(out) - sumxx = np.zeros_like(out) + mean = np.zeros_like(out) N, K = ( values).shape - if K > 1: - for i in range(N): + out[:, :] = 0.0 + with nogil: + for i in range(N): lab = labels[i] if lab < 0: continue @@ -7143,32 +7315,19 @@ def group_var_float32(ndarray[float32_t, ndim=2] out, # not nan if val == val: nobs[lab, j] += 1 - sumx[lab, j] += val - sumxx[lab, j] += val * val - else: - for i in range(N): + oldmean = mean[lab, j] + mean[lab, j] += (val - oldmean) / nobs[lab, j] + out[lab, j] += (val - mean[lab, j]) * (val - oldmean) - lab = labels[i] - if lab < 0: - continue - - counts[lab] += 1 - val = values[i, 0] - # not nan - if val == val: - nobs[lab, 0] += 1 - sumx[lab, 0] += val - sumxx[lab, 0] += val * val + for i in range(ncounts): + for j in range(K): + ct = nobs[i, j] + if ct < 2: + out[i, j] = NAN + else: + out[i, j] /= (ct - 1) - for i in range(len(counts)): - for j in range(K): - ct = nobs[i, j] - if ct < 2: - out[i, j] = nan - else: - out[i, j] = ((ct * sumxx[i, j] - sumx[i, j] * sumx[i, j]) / - (ct * ct - ct)) @cython.wraparound(False) @cython.boundscheck(False) @@ -7186,6 +7345,8 @@ def group_var_bin_float64(ndarray[float64_t, ndim=2] out, sumx = np.zeros_like(out) sumxx = np.zeros_like(out) + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: @@ -7193,44 +7354,46 @@ def group_var_bin_float64(ndarray[float64_t, ndim=2] out, N, K = ( values).shape - b = 0 - if K > 1: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + with nogil: + b = 0 + if K > 1: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 - counts[b] += 1 + counts[b] += 1 - for j in range(K): - val = values[i, j] + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[b, j] += 1 + sumx[b, j] += val + sumxx[b, j] += val * val + else: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 + + counts[b] += 1 + val = values[i, 0] # not nan if val == val: - nobs[b, j] += 1 - sumx[b, j] += val - sumxx[b, j] += val * val - else: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 - - counts[b] += 1 - val = values[i, 0] + nobs[b, 0] += 1 + sumx[b, 0] += val + sumxx[b, 0] += val * val - # not nan - if val == val: - nobs[b, 0] += 1 - sumx[b, 0] += val - sumxx[b, 0] += val * val + for i in range(ngroups): + for j in range(K): + ct = nobs[i, j] + if ct < 2: + out[i, j] = NAN + else: + out[i, j] = ((ct * sumxx[i, j] - sumx[i, j] * sumx[i, j]) / + (ct * ct - ct)) - for i in range(ngroups): - for j in range(K): - ct = nobs[i, j] - if ct < 2: - out[i, j] = nan - else: - out[i, j] = ((ct * sumxx[i, j] - sumx[i, j] * sumx[i, j]) / - (ct * ct - ct)) @cython.wraparound(False) @cython.boundscheck(False) def group_var_bin_float32(ndarray[float32_t, ndim=2] out, @@ -7247,6 +7410,8 @@ def group_var_bin_float32(ndarray[float32_t, ndim=2] out, sumx = np.zeros_like(out) sumxx = np.zeros_like(out) + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: @@ -7254,44 +7419,46 @@ def group_var_bin_float32(ndarray[float32_t, ndim=2] out, N, K = ( values).shape - b = 0 - if K > 1: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + with nogil: + b = 0 + if K > 1: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 - counts[b] += 1 + counts[b] += 1 - for j in range(K): - val = values[i, j] + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[b, j] += 1 + sumx[b, j] += val + sumxx[b, j] += val * val + else: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 + + counts[b] += 1 + val = values[i, 0] # not nan if val == val: - nobs[b, j] += 1 - sumx[b, j] += val - sumxx[b, j] += val * val - else: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + nobs[b, 0] += 1 + sumx[b, 0] += val + sumxx[b, 0] += val * val - counts[b] += 1 - val = values[i, 0] - - # not nan - if val == val: - nobs[b, 0] += 1 - sumx[b, 0] += val - sumxx[b, 0] += val * val + for i in range(ngroups): + for j in range(K): + ct = nobs[i, j] + if ct < 2: + out[i, j] = NAN + else: + out[i, j] = ((ct * sumxx[i, j] - sumx[i, j] * sumx[i, j]) / + (ct * ct - ct)) - for i in range(ngroups): - for j in range(K): - ct = nobs[i, j] - if ct < 2: - out[i, j] = nan - else: - out[i, j] = ((ct * sumxx[i, j] - sumx[i, j] * sumx[i, j]) / - (ct * ct - ct)) @cython.wraparound(False) @cython.boundscheck(False) @@ -7300,7 +7467,7 @@ def group_mean_float64(ndarray[float64_t, ndim=2] out, ndarray[float64_t, ndim=2] values, ndarray[int64_t] labels): cdef: - Py_ssize_t i, j, N, K, lab + Py_ssize_t i, j, N, K, lab, ncounts = len(counts) float64_t val, count ndarray[float64_t, ndim=2] sumx, nobs @@ -7312,39 +7479,41 @@ def group_mean_float64(ndarray[float64_t, ndim=2] out, N, K = ( values).shape - if K > 1: - for i in range(N): - lab = labels[i] - if lab < 0: - continue + with nogil: + if K > 1: + for i in range(N): + lab = labels[i] + if lab < 0: + continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + counts[lab] += 1 + for j in range(K): + val = values[i, j] + # not nan + if val == val: + nobs[lab, j] += 1 + sumx[lab, j] += val + else: + for i in range(N): + lab = labels[i] + if lab < 0: + continue + + counts[lab] += 1 + val = values[i, 0] # not nan if val == val: - nobs[lab, j] += 1 - sumx[lab, j] += val - else: - for i in range(N): - lab = labels[i] - if lab < 0: - continue + nobs[lab, 0] += 1 + sumx[lab, 0] += val - counts[lab] += 1 - val = values[i, 0] - # not nan - if val == val: - nobs[lab, 0] += 1 - sumx[lab, 0] += val + for i in range(ncounts): + for j in range(K): + count = nobs[i, j] + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = sumx[i, j] / count - for i in range(len(counts)): - for j in range(K): - count = nobs[i, j] - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = sumx[i, j] / count @cython.wraparound(False) @cython.boundscheck(False) def group_mean_float32(ndarray[float32_t, ndim=2] out, @@ -7352,7 +7521,7 @@ def group_mean_float32(ndarray[float32_t, ndim=2] out, ndarray[float32_t, ndim=2] values, ndarray[int64_t] labels): cdef: - Py_ssize_t i, j, N, K, lab + Py_ssize_t i, j, N, K, lab, ncounts = len(counts) float32_t val, count ndarray[float32_t, ndim=2] sumx, nobs @@ -7364,41 +7533,44 @@ def group_mean_float32(ndarray[float32_t, ndim=2] out, N, K = ( values).shape - if K > 1: - for i in range(N): - lab = labels[i] - if lab < 0: - continue + with nogil: + if K > 1: + for i in range(N): + lab = labels[i] + if lab < 0: + continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + counts[lab] += 1 + for j in range(K): + val = values[i, j] + # not nan + if val == val: + nobs[lab, j] += 1 + sumx[lab, j] += val + else: + for i in range(N): + lab = labels[i] + if lab < 0: + continue + + counts[lab] += 1 + val = values[i, 0] # not nan if val == val: - nobs[lab, j] += 1 - sumx[lab, j] += val - else: - for i in range(N): - lab = labels[i] - if lab < 0: - continue + nobs[lab, 0] += 1 + sumx[lab, 0] += val - counts[lab] += 1 - val = values[i, 0] - # not nan - if val == val: - nobs[lab, 0] += 1 - sumx[lab, 0] += val + for i in range(ncounts): + for j in range(K): + count = nobs[i, j] + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = sumx[i, j] / count - for i in range(len(counts)): - for j in range(K): - count = nobs[i, j] - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = sumx[i, j] / count +@cython.boundscheck(False) def group_mean_bin_float64(ndarray[float64_t, ndim=2] out, ndarray[int64_t] counts, ndarray[float64_t, ndim=2] values, @@ -7412,46 +7584,51 @@ def group_mean_bin_float64(ndarray[float64_t, ndim=2] out, sumx = np.zeros_like(out) N, K = ( values).shape + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: ngroups = len(bins) + 1 - b = 0 - if K > 1: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + with nogil: + b = 0 + if K > 1: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 - counts[b] += 1 - for j in range(K): - val = values[i, j] + counts[b] += 1 + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[b, j] += 1 + sumx[b, j] += val + else: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 + + counts[b] += 1 + val = values[i, 0] # not nan if val == val: - nobs[b, j] += 1 - sumx[b, j] += val - else: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + nobs[b, 0] += 1 + sumx[b, 0] += val - counts[b] += 1 - val = values[i, 0] - - # not nan - if val == val: - nobs[b, 0] += 1 - sumx[b, 0] += val + for i in range(ngroups): + for j in range(K): + count = nobs[i, j] + if count == 0: + out[i, j] = NAN + else: + out[i, j] = sumx[i, j] / count - for i in range(ngroups): - for j in range(K): - count = nobs[i, j] - if count == 0: - out[i, j] = nan - else: - out[i, j] = sumx[i, j] / count +@cython.boundscheck(False) def group_mean_bin_float32(ndarray[float32_t, ndim=2] out, ndarray[int64_t] counts, ndarray[float32_t, ndim=2] values, @@ -7465,45 +7642,49 @@ def group_mean_bin_float32(ndarray[float32_t, ndim=2] out, sumx = np.zeros_like(out) N, K = ( values).shape + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: ngroups = len(bins) + 1 - b = 0 - if K > 1: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + with nogil: + b = 0 + if K > 1: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 - counts[b] += 1 - for j in range(K): - val = values[i, j] + counts[b] += 1 + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[b, j] += 1 + sumx[b, j] += val + else: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 + + counts[b] += 1 + val = values[i, 0] # not nan if val == val: - nobs[b, j] += 1 - sumx[b, j] += val - else: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 - - counts[b] += 1 - val = values[i, 0] + nobs[b, 0] += 1 + sumx[b, 0] += val - # not nan - if val == val: - nobs[b, 0] += 1 - sumx[b, 0] += val + for i in range(ngroups): + for j in range(K): + count = nobs[i, j] + if count == 0: + out[i, j] = NAN + else: + out[i, j] = sumx[i, j] / count - for i in range(ngroups): - for j in range(K): - count = nobs[i, j] - if count == 0: - out[i, j] = nan - else: - out[i, j] = sumx[i, j] / count @cython.wraparound(False) @cython.boundscheck(False) @@ -7517,9 +7698,11 @@ def group_ohlc_float64(ndarray[float64_t, ndim=2] out, cdef: Py_ssize_t i, j, N, K, ngroups, b float64_t val, count - float64_t vopen, vhigh, vlow, vclose, NA + float64_t vopen, vhigh, vlow, vclose bint got_first = 0 + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: @@ -7530,55 +7713,56 @@ def group_ohlc_float64(ndarray[float64_t, ndim=2] out, if out.shape[1] != 4: raise ValueError('Output array must have 4 columns') - NA = np.nan - b = 0 if K > 1: raise NotImplementedError("Argument 'values' must have only " "one dimension") else: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - if not got_first: - out[b, 0] = NA - out[b, 1] = NA - out[b, 2] = NA - out[b, 3] = NA - else: - out[b, 0] = vopen - out[b, 1] = vhigh - out[b, 2] = vlow - out[b, 3] = vclose - b += 1 - got_first = 0 - counts[b] += 1 - val = values[i, 0] + with nogil: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + if not got_first: + out[b, 0] = NAN + out[b, 1] = NAN + out[b, 2] = NAN + out[b, 3] = NAN + else: + out[b, 0] = vopen + out[b, 1] = vhigh + out[b, 2] = vlow + out[b, 3] = vclose + b += 1 + got_first = 0 - # not nan - if val == val: - if not got_first: - got_first = 1 - vopen = val - vlow = val - vhigh = val - else: - if val < vlow: + counts[b] += 1 + val = values[i, 0] + + # not nan + if val == val: + if not got_first: + got_first = 1 + vopen = val vlow = val - if val > vhigh: vhigh = val - vclose = val + else: + if val < vlow: + vlow = val + if val > vhigh: + vhigh = val + vclose = val + + if not got_first: + out[b, 0] = NAN + out[b, 1] = NAN + out[b, 2] = NAN + out[b, 3] = NAN + else: + out[b, 0] = vopen + out[b, 1] = vhigh + out[b, 2] = vlow + out[b, 3] = vclose - if not got_first: - out[b, 0] = NA - out[b, 1] = NA - out[b, 2] = NA - out[b, 3] = NA - else: - out[b, 0] = vopen - out[b, 1] = vhigh - out[b, 2] = vlow - out[b, 3] = vclose @cython.wraparound(False) @cython.boundscheck(False) def group_ohlc_float32(ndarray[float32_t, ndim=2] out, @@ -7591,9 +7775,11 @@ def group_ohlc_float32(ndarray[float32_t, ndim=2] out, cdef: Py_ssize_t i, j, N, K, ngroups, b float32_t val, count - float32_t vopen, vhigh, vlow, vclose, NA + float32_t vopen, vhigh, vlow, vclose bint got_first = 0 + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: @@ -7604,58 +7790,59 @@ def group_ohlc_float32(ndarray[float32_t, ndim=2] out, if out.shape[1] != 4: raise ValueError('Output array must have 4 columns') - NA = np.nan - b = 0 if K > 1: raise NotImplementedError("Argument 'values' must have only " "one dimension") else: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - if not got_first: - out[b, 0] = NA - out[b, 1] = NA - out[b, 2] = NA - out[b, 3] = NA - else: - out[b, 0] = vopen - out[b, 1] = vhigh - out[b, 2] = vlow - out[b, 3] = vclose - b += 1 - got_first = 0 - counts[b] += 1 - val = values[i, 0] + with nogil: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + if not got_first: + out[b, 0] = NAN + out[b, 1] = NAN + out[b, 2] = NAN + out[b, 3] = NAN + else: + out[b, 0] = vopen + out[b, 1] = vhigh + out[b, 2] = vlow + out[b, 3] = vclose + b += 1 + got_first = 0 - # not nan - if val == val: - if not got_first: - got_first = 1 - vopen = val - vlow = val - vhigh = val - else: - if val < vlow: + counts[b] += 1 + val = values[i, 0] + + # not nan + if val == val: + if not got_first: + got_first = 1 + vopen = val vlow = val - if val > vhigh: vhigh = val - vclose = val + else: + if val < vlow: + vlow = val + if val > vhigh: + vhigh = val + vclose = val + + if not got_first: + out[b, 0] = NAN + out[b, 1] = NAN + out[b, 2] = NAN + out[b, 3] = NAN + else: + out[b, 0] = vopen + out[b, 1] = vhigh + out[b, 2] = vlow + out[b, 3] = vclose - if not got_first: - out[b, 0] = NA - out[b, 1] = NA - out[b, 2] = NA - out[b, 3] = NA - else: - out[b, 0] = vopen - out[b, 1] = vhigh - out[b, 2] = vlow - out[b, 3] = vclose @cython.wraparound(False) -@cython.wraparound(False) +@cython.boundscheck(False) def group_last_float64(ndarray[float64_t, ndim=2] out, ndarray[int64_t] counts, ndarray[float64_t, ndim=2] values, @@ -7664,7 +7851,7 @@ def group_last_float64(ndarray[float64_t, ndim=2] out, Only aggregates on axis=0 ''' cdef: - Py_ssize_t i, j, N, K, lab + Py_ssize_t i, j, N, K, lab, ncounts = len(counts) float64_t val, count ndarray[float64_t, ndim=2] resx ndarray[int64_t, ndim=2] nobs @@ -7677,28 +7864,30 @@ def group_last_float64(ndarray[float64_t, ndim=2] out, N, K = ( values).shape - for i in range(N): - lab = labels[i] - if lab < 0: - continue + with nogil: + for i in range(N): + lab = labels[i] + if lab < 0: + continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + counts[lab] += 1 + for j in range(K): + val = values[i, j] - # not nan - if val == val: - nobs[lab, j] += 1 - resx[lab, j] = val + # not nan + if val == val: + nobs[lab, j] += 1 + resx[lab, j] = val + + for i in range(ncounts): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = resx[i, j] - for i in range(len(counts)): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = resx[i, j] -@cython.wraparound(False) @cython.wraparound(False) +@cython.boundscheck(False) def group_last_float32(ndarray[float32_t, ndim=2] out, ndarray[int64_t] counts, ndarray[float32_t, ndim=2] values, @@ -7707,7 +7896,7 @@ def group_last_float32(ndarray[float32_t, ndim=2] out, Only aggregates on axis=0 ''' cdef: - Py_ssize_t i, j, N, K, lab + Py_ssize_t i, j, N, K, lab, ncounts = len(counts) float32_t val, count ndarray[float32_t, ndim=2] resx ndarray[int64_t, ndim=2] nobs @@ -7720,28 +7909,30 @@ def group_last_float32(ndarray[float32_t, ndim=2] out, N, K = ( values).shape - for i in range(N): - lab = labels[i] - if lab < 0: - continue + with nogil: + for i in range(N): + lab = labels[i] + if lab < 0: + continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + counts[lab] += 1 + for j in range(K): + val = values[i, j] - # not nan - if val == val: - nobs[lab, j] += 1 - resx[lab, j] = val + # not nan + if val == val: + nobs[lab, j] += 1 + resx[lab, j] = val + + for i in range(ncounts): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = resx[i, j] - for i in range(len(counts)): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = resx[i, j] -@cython.wraparound(False) @cython.wraparound(False) +@cython.boundscheck(False) def group_last_int64(ndarray[int64_t, ndim=2] out, ndarray[int64_t] counts, ndarray[int64_t, ndim=2] values, @@ -7750,7 +7941,7 @@ def group_last_int64(ndarray[int64_t, ndim=2] out, Only aggregates on axis=0 ''' cdef: - Py_ssize_t i, j, N, K, lab + Py_ssize_t i, j, N, K, lab, ncounts = len(counts) int64_t val, count ndarray[int64_t, ndim=2] resx ndarray[int64_t, ndim=2] nobs @@ -7763,29 +7954,31 @@ def group_last_int64(ndarray[int64_t, ndim=2] out, N, K = ( values).shape - for i in range(N): - lab = labels[i] - if lab < 0: - continue + with nogil: + for i in range(N): + lab = labels[i] + if lab < 0: + continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + counts[lab] += 1 + for j in range(K): + val = values[i, j] - # not nan - if val == val: - nobs[lab, j] += 1 - resx[lab, j] = val + # not nan + if val == val: + nobs[lab, j] += 1 + resx[lab, j] = val + + for i in range(ncounts): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = iNaT + else: + out[i, j] = resx[i, j] - for i in range(len(counts)): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = iNaT - else: - out[i, j] = resx[i, j] @cython.wraparound(False) -@cython.wraparound(False) +@cython.boundscheck(False) def group_last_bin_float64(ndarray[float64_t, ndim=2] out, ndarray[int64_t] counts, ndarray[float64_t, ndim=2] values, @@ -7801,6 +7994,8 @@ def group_last_bin_float64(ndarray[float64_t, ndim=2] out, nobs = np.zeros_like(out) resx = np.empty_like(out) + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: @@ -7808,28 +8003,30 @@ def group_last_bin_float64(ndarray[float64_t, ndim=2] out, N, K = ( values).shape - b = 0 - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + with nogil: + b = 0 + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 - counts[b] += 1 - for j in range(K): - val = values[i, j] + counts[b] += 1 + for j in range(K): + val = values[i, j] - # not nan - if val == val: - nobs[b, j] += 1 - resx[b, j] = val + # not nan + if val == val: + nobs[b, j] += 1 + resx[b, j] = val + + for i in range(ngroups): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = resx[i, j] - for i in range(ngroups): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = resx[i, j] -@cython.wraparound(False) @cython.wraparound(False) +@cython.boundscheck(False) def group_last_bin_float32(ndarray[float32_t, ndim=2] out, ndarray[int64_t] counts, ndarray[float32_t, ndim=2] values, @@ -7845,6 +8042,8 @@ def group_last_bin_float32(ndarray[float32_t, ndim=2] out, nobs = np.zeros_like(out) resx = np.empty_like(out) + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: @@ -7852,28 +8051,30 @@ def group_last_bin_float32(ndarray[float32_t, ndim=2] out, N, K = ( values).shape - b = 0 - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + with nogil: + b = 0 + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 - counts[b] += 1 - for j in range(K): - val = values[i, j] + counts[b] += 1 + for j in range(K): + val = values[i, j] - # not nan - if val == val: - nobs[b, j] += 1 - resx[b, j] = val + # not nan + if val == val: + nobs[b, j] += 1 + resx[b, j] = val + + for i in range(ngroups): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = resx[i, j] - for i in range(ngroups): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = resx[i, j] -@cython.wraparound(False) @cython.wraparound(False) +@cython.boundscheck(False) def group_last_bin_int64(ndarray[int64_t, ndim=2] out, ndarray[int64_t] counts, ndarray[int64_t, ndim=2] values, @@ -7889,6 +8090,8 @@ def group_last_bin_int64(ndarray[int64_t, ndim=2] out, nobs = np.zeros_like(out) resx = np.empty_like(out) + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: @@ -7896,29 +8099,31 @@ def group_last_bin_int64(ndarray[int64_t, ndim=2] out, N, K = ( values).shape - b = 0 - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + with nogil: + b = 0 + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 - counts[b] += 1 - for j in range(K): - val = values[i, j] + counts[b] += 1 + for j in range(K): + val = values[i, j] - # not nan - if val == val: - nobs[b, j] += 1 - resx[b, j] = val + # not nan + if val == val: + nobs[b, j] += 1 + resx[b, j] = val + + for i in range(ngroups): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = iNaT + else: + out[i, j] = resx[i, j] - for i in range(ngroups): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = iNaT - else: - out[i, j] = resx[i, j] -@cython.boundscheck(False) @cython.wraparound(False) +@cython.boundscheck(False) def group_nth_float64(ndarray[float64_t, ndim=2] out, ndarray[int64_t] counts, ndarray[float64_t, ndim=2] values, @@ -7927,7 +8132,7 @@ def group_nth_float64(ndarray[float64_t, ndim=2] out, Only aggregates on axis=0 ''' cdef: - Py_ssize_t i, j, N, K, lab + Py_ssize_t i, j, N, K, lab, ncounts = len(counts) float64_t val, count ndarray[float64_t, ndim=2] resx ndarray[int64_t, ndim=2] nobs @@ -7940,29 +8145,31 @@ def group_nth_float64(ndarray[float64_t, ndim=2] out, N, K = ( values).shape - for i in range(N): - lab = labels[i] - if lab < 0: - continue + with nogil: + for i in range(N): + lab = labels[i] + if lab < 0: + continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + counts[lab] += 1 + for j in range(K): + val = values[i, j] - # not nan - if val == val: - nobs[lab, j] += 1 - if nobs[lab, j] == rank: - resx[lab, j] = val + # not nan + if val == val: + nobs[lab, j] += 1 + if nobs[lab, j] == rank: + resx[lab, j] = val + + for i in range(ncounts): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = resx[i, j] - for i in range(len(counts)): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = resx[i, j] -@cython.boundscheck(False) @cython.wraparound(False) +@cython.boundscheck(False) def group_nth_float32(ndarray[float32_t, ndim=2] out, ndarray[int64_t] counts, ndarray[float32_t, ndim=2] values, @@ -7971,7 +8178,7 @@ def group_nth_float32(ndarray[float32_t, ndim=2] out, Only aggregates on axis=0 ''' cdef: - Py_ssize_t i, j, N, K, lab + Py_ssize_t i, j, N, K, lab, ncounts = len(counts) float32_t val, count ndarray[float32_t, ndim=2] resx ndarray[int64_t, ndim=2] nobs @@ -7984,29 +8191,31 @@ def group_nth_float32(ndarray[float32_t, ndim=2] out, N, K = ( values).shape - for i in range(N): - lab = labels[i] - if lab < 0: - continue + with nogil: + for i in range(N): + lab = labels[i] + if lab < 0: + continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + counts[lab] += 1 + for j in range(K): + val = values[i, j] - # not nan - if val == val: - nobs[lab, j] += 1 - if nobs[lab, j] == rank: - resx[lab, j] = val + # not nan + if val == val: + nobs[lab, j] += 1 + if nobs[lab, j] == rank: + resx[lab, j] = val + + for i in range(ncounts): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = resx[i, j] - for i in range(len(counts)): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = resx[i, j] -@cython.boundscheck(False) @cython.wraparound(False) +@cython.boundscheck(False) def group_nth_int64(ndarray[int64_t, ndim=2] out, ndarray[int64_t] counts, ndarray[int64_t, ndim=2] values, @@ -8015,7 +8224,7 @@ def group_nth_int64(ndarray[int64_t, ndim=2] out, Only aggregates on axis=0 ''' cdef: - Py_ssize_t i, j, N, K, lab + Py_ssize_t i, j, N, K, lab, ncounts = len(counts) int64_t val, count ndarray[int64_t, ndim=2] resx ndarray[int64_t, ndim=2] nobs @@ -8028,30 +8237,32 @@ def group_nth_int64(ndarray[int64_t, ndim=2] out, N, K = ( values).shape - for i in range(N): - lab = labels[i] - if lab < 0: - continue + with nogil: + for i in range(N): + lab = labels[i] + if lab < 0: + continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + counts[lab] += 1 + for j in range(K): + val = values[i, j] - # not nan - if val == val: - nobs[lab, j] += 1 - if nobs[lab, j] == rank: - resx[lab, j] = val + # not nan + if val == val: + nobs[lab, j] += 1 + if nobs[lab, j] == rank: + resx[lab, j] = val + + for i in range(ncounts): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = iNaT + else: + out[i, j] = resx[i, j] - for i in range(len(counts)): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = iNaT - else: - out[i, j] = resx[i, j] -@cython.boundscheck(False) @cython.wraparound(False) +@cython.boundscheck(False) def group_nth_bin_float64(ndarray[float64_t, ndim=2] out, ndarray[int64_t] counts, ndarray[float64_t, ndim=2] values, @@ -8067,6 +8278,8 @@ def group_nth_bin_float64(ndarray[float64_t, ndim=2] out, nobs = np.zeros_like(out) resx = np.empty_like(out) + if len(bin) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: @@ -8074,29 +8287,31 @@ def group_nth_bin_float64(ndarray[float64_t, ndim=2] out, N, K = ( values).shape - b = 0 - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + with nogil: + b = 0 + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 - counts[b] += 1 - for j in range(K): - val = values[i, j] + counts[b] += 1 + for j in range(K): + val = values[i, j] - # not nan - if val == val: - nobs[b, j] += 1 - if nobs[b, j] == rank: - resx[b, j] = val + # not nan + if val == val: + nobs[b, j] += 1 + if nobs[b, j] == rank: + resx[b, j] = val + + for i in range(ngroups): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = resx[i, j] - for i in range(ngroups): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = resx[i, j] -@cython.boundscheck(False) @cython.wraparound(False) +@cython.boundscheck(False) def group_nth_bin_float32(ndarray[float32_t, ndim=2] out, ndarray[int64_t] counts, ndarray[float32_t, ndim=2] values, @@ -8112,6 +8327,8 @@ def group_nth_bin_float32(ndarray[float32_t, ndim=2] out, nobs = np.zeros_like(out) resx = np.empty_like(out) + if len(bin) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: @@ -8119,29 +8336,31 @@ def group_nth_bin_float32(ndarray[float32_t, ndim=2] out, N, K = ( values).shape - b = 0 - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + with nogil: + b = 0 + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 - counts[b] += 1 - for j in range(K): - val = values[i, j] + counts[b] += 1 + for j in range(K): + val = values[i, j] - # not nan - if val == val: - nobs[b, j] += 1 - if nobs[b, j] == rank: - resx[b, j] = val + # not nan + if val == val: + nobs[b, j] += 1 + if nobs[b, j] == rank: + resx[b, j] = val + + for i in range(ngroups): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = resx[i, j] - for i in range(ngroups): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = resx[i, j] -@cython.boundscheck(False) @cython.wraparound(False) +@cython.boundscheck(False) def group_nth_bin_int64(ndarray[int64_t, ndim=2] out, ndarray[int64_t] counts, ndarray[int64_t, ndim=2] values, @@ -8157,6 +8376,8 @@ def group_nth_bin_int64(ndarray[int64_t, ndim=2] out, nobs = np.zeros_like(out) resx = np.empty_like(out) + if len(bin) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: @@ -8164,27 +8385,29 @@ def group_nth_bin_int64(ndarray[int64_t, ndim=2] out, N, K = ( values).shape - b = 0 - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + with nogil: + b = 0 + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 + + counts[b] += 1 + for j in range(K): + val = values[i, j] - counts[b] += 1 - for j in range(K): - val = values[i, j] + # not nan + if val == val: + nobs[b, j] += 1 + if nobs[b, j] == rank: + resx[b, j] = val - # not nan - if val == val: - nobs[b, j] += 1 - if nobs[b, j] == rank: - resx[b, j] = val + for i in range(ngroups): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = iNaT + else: + out[i, j] = resx[i, j] - for i in range(ngroups): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = iNaT - else: - out[i, j] = resx[i, j] @cython.wraparound(False) @cython.boundscheck(False) @@ -8196,7 +8419,7 @@ def group_min_float64(ndarray[float64_t, ndim=2] out, Only aggregates on axis=0 ''' cdef: - Py_ssize_t i, j, N, K, lab + Py_ssize_t i, j, N, K, lab, ncounts = len(counts) float64_t val, count ndarray[float64_t, ndim=2] minx, nobs @@ -8210,42 +8433,44 @@ def group_min_float64(ndarray[float64_t, ndim=2] out, N, K = ( values).shape - if K > 1: - for i in range(N): - lab = labels[i] - if lab < 0: - continue + with nogil: + if K > 1: + for i in range(N): + lab = labels[i] + if lab < 0: + continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + counts[lab] += 1 + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[lab, j] += 1 + if val < minx[lab, j]: + minx[lab, j] = val + else: + for i in range(N): + lab = labels[i] + if lab < 0: + continue + + counts[lab] += 1 + val = values[i, 0] # not nan if val == val: - nobs[lab, j] += 1 - if val < minx[lab, j]: - minx[lab, j] = val - else: - for i in range(N): - lab = labels[i] - if lab < 0: - continue + nobs[lab, 0] += 1 + if val < minx[lab, 0]: + minx[lab, 0] = val - counts[lab] += 1 - val = values[i, 0] - - # not nan - if val == val: - nobs[lab, 0] += 1 - if val < minx[lab, 0]: - minx[lab, 0] = val + for i in range(ncounts): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = minx[i, j] - for i in range(len(counts)): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = minx[i, j] @cython.wraparound(False) @cython.boundscheck(False) def group_min_float32(ndarray[float32_t, ndim=2] out, @@ -8256,7 +8481,7 @@ def group_min_float32(ndarray[float32_t, ndim=2] out, Only aggregates on axis=0 ''' cdef: - Py_ssize_t i, j, N, K, lab + Py_ssize_t i, j, N, K, lab, ncounts = len(counts) float32_t val, count ndarray[float32_t, ndim=2] minx, nobs @@ -8270,42 +8495,44 @@ def group_min_float32(ndarray[float32_t, ndim=2] out, N, K = ( values).shape - if K > 1: - for i in range(N): - lab = labels[i] - if lab < 0: - continue + with nogil: + if K > 1: + for i in range(N): + lab = labels[i] + if lab < 0: + continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + counts[lab] += 1 + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[lab, j] += 1 + if val < minx[lab, j]: + minx[lab, j] = val + else: + for i in range(N): + lab = labels[i] + if lab < 0: + continue + + counts[lab] += 1 + val = values[i, 0] # not nan if val == val: - nobs[lab, j] += 1 - if val < minx[lab, j]: - minx[lab, j] = val - else: - for i in range(N): - lab = labels[i] - if lab < 0: - continue - - counts[lab] += 1 - val = values[i, 0] + nobs[lab, 0] += 1 + if val < minx[lab, 0]: + minx[lab, 0] = val - # not nan - if val == val: - nobs[lab, 0] += 1 - if val < minx[lab, 0]: - minx[lab, 0] = val + for i in range(ncounts): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = minx[i, j] - for i in range(len(counts)): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = minx[i, j] @cython.wraparound(False) @cython.boundscheck(False) def group_min_int64(ndarray[int64_t, ndim=2] out, @@ -8316,7 +8543,7 @@ def group_min_int64(ndarray[int64_t, ndim=2] out, Only aggregates on axis=0 ''' cdef: - Py_ssize_t i, j, N, K, lab + Py_ssize_t i, j, N, K, lab, ncounts = len(counts) int64_t val, count ndarray[int64_t, ndim=2] minx, nobs @@ -8330,42 +8557,44 @@ def group_min_int64(ndarray[int64_t, ndim=2] out, N, K = ( values).shape - if K > 1: - for i in range(N): - lab = labels[i] - if lab < 0: - continue + with nogil: + if K > 1: + for i in range(N): + lab = labels[i] + if lab < 0: + continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + counts[lab] += 1 + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[lab, j] += 1 + if val < minx[lab, j]: + minx[lab, j] = val + else: + for i in range(N): + lab = labels[i] + if lab < 0: + continue + + counts[lab] += 1 + val = values[i, 0] # not nan if val == val: - nobs[lab, j] += 1 - if val < minx[lab, j]: - minx[lab, j] = val - else: - for i in range(N): - lab = labels[i] - if lab < 0: - continue + nobs[lab, 0] += 1 + if val < minx[lab, 0]: + minx[lab, 0] = val - counts[lab] += 1 - val = values[i, 0] - - # not nan - if val == val: - nobs[lab, 0] += 1 - if val < minx[lab, 0]: - minx[lab, 0] = val + for i in range(ncounts): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = iNaT + else: + out[i, j] = minx[i, j] - for i in range(len(counts)): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = iNaT - else: - out[i, j] = minx[i, j] @cython.wraparound(False) @cython.boundscheck(False) @@ -8386,6 +8615,8 @@ def group_min_bin_float64(ndarray[float64_t, ndim=2] out, minx = np.empty_like(out) minx.fill(np.inf) + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: @@ -8393,41 +8624,43 @@ def group_min_bin_float64(ndarray[float64_t, ndim=2] out, N, K = ( values).shape - b = 0 - if K > 1: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + with nogil: + b = 0 + if K > 1: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 - counts[b] += 1 - for j in range(K): - val = values[i, j] + counts[b] += 1 + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[b, j] += 1 + if val < minx[b, j]: + minx[b, j] = val + else: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 + + counts[b] += 1 + val = values[i, 0] # not nan if val == val: - nobs[b, j] += 1 - if val < minx[b, j]: - minx[b, j] = val - else: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + nobs[b, 0] += 1 + if val < minx[b, 0]: + minx[b, 0] = val - counts[b] += 1 - val = values[i, 0] - - # not nan - if val == val: - nobs[b, 0] += 1 - if val < minx[b, 0]: - minx[b, 0] = val + for i in range(ngroups): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = minx[i, j] - for i in range(ngroups): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = minx[i, j] @cython.wraparound(False) @cython.boundscheck(False) def group_min_bin_float32(ndarray[float32_t, ndim=2] out, @@ -8447,6 +8680,8 @@ def group_min_bin_float32(ndarray[float32_t, ndim=2] out, minx = np.empty_like(out) minx.fill(np.inf) + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: @@ -8454,41 +8689,43 @@ def group_min_bin_float32(ndarray[float32_t, ndim=2] out, N, K = ( values).shape - b = 0 - if K > 1: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + with nogil: + b = 0 + if K > 1: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 - counts[b] += 1 - for j in range(K): - val = values[i, j] + counts[b] += 1 + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[b, j] += 1 + if val < minx[b, j]: + minx[b, j] = val + else: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 + + counts[b] += 1 + val = values[i, 0] # not nan if val == val: - nobs[b, j] += 1 - if val < minx[b, j]: - minx[b, j] = val - else: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 - - counts[b] += 1 - val = values[i, 0] + nobs[b, 0] += 1 + if val < minx[b, 0]: + minx[b, 0] = val - # not nan - if val == val: - nobs[b, 0] += 1 - if val < minx[b, 0]: - minx[b, 0] = val + for i in range(ngroups): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = minx[i, j] - for i in range(ngroups): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = minx[i, j] @cython.wraparound(False) @cython.boundscheck(False) def group_min_bin_int64(ndarray[int64_t, ndim=2] out, @@ -8508,6 +8745,8 @@ def group_min_bin_int64(ndarray[int64_t, ndim=2] out, minx = np.empty_like(out) minx.fill(9223372036854775807) + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: @@ -8515,41 +8754,43 @@ def group_min_bin_int64(ndarray[int64_t, ndim=2] out, N, K = ( values).shape - b = 0 - if K > 1: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + with nogil: + b = 0 + if K > 1: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 - counts[b] += 1 - for j in range(K): - val = values[i, j] + counts[b] += 1 + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[b, j] += 1 + if val < minx[b, j]: + minx[b, j] = val + else: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 + + counts[b] += 1 + val = values[i, 0] # not nan if val == val: - nobs[b, j] += 1 - if val < minx[b, j]: - minx[b, j] = val - else: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 - - counts[b] += 1 - val = values[i, 0] + nobs[b, 0] += 1 + if val < minx[b, 0]: + minx[b, 0] = val - # not nan - if val == val: - nobs[b, 0] += 1 - if val < minx[b, 0]: - minx[b, 0] = val + for i in range(ngroups): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = iNaT + else: + out[i, j] = minx[i, j] - for i in range(ngroups): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = iNaT - else: - out[i, j] = minx[i, j] @cython.wraparound(False) @cython.boundscheck(False) @@ -8561,7 +8802,7 @@ def group_max_float64(ndarray[float64_t, ndim=2] out, Only aggregates on axis=0 ''' cdef: - Py_ssize_t i, j, N, K, lab + Py_ssize_t i, j, N, K, lab, ncounts = len(counts) float64_t val, count ndarray[float64_t, ndim=2] maxx, nobs @@ -8575,42 +8816,44 @@ def group_max_float64(ndarray[float64_t, ndim=2] out, N, K = ( values).shape - if K > 1: - for i in range(N): - lab = labels[i] - if lab < 0: - continue + with nogil: + if K > 1: + for i in range(N): + lab = labels[i] + if lab < 0: + continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + counts[lab] += 1 + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[lab, j] += 1 + if val > maxx[lab, j]: + maxx[lab, j] = val + else: + for i in range(N): + lab = labels[i] + if lab < 0: + continue + + counts[lab] += 1 + val = values[i, 0] # not nan if val == val: - nobs[lab, j] += 1 - if val > maxx[lab, j]: - maxx[lab, j] = val - else: - for i in range(N): - lab = labels[i] - if lab < 0: - continue - - counts[lab] += 1 - val = values[i, 0] + nobs[lab, 0] += 1 + if val > maxx[lab, 0]: + maxx[lab, 0] = val - # not nan - if val == val: - nobs[lab, 0] += 1 - if val > maxx[lab, 0]: - maxx[lab, 0] = val + for i in range(ncounts): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = maxx[i, j] - for i in range(len(counts)): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = maxx[i, j] @cython.wraparound(False) @cython.boundscheck(False) def group_max_float32(ndarray[float32_t, ndim=2] out, @@ -8621,7 +8864,7 @@ def group_max_float32(ndarray[float32_t, ndim=2] out, Only aggregates on axis=0 ''' cdef: - Py_ssize_t i, j, N, K, lab + Py_ssize_t i, j, N, K, lab, ncounts = len(counts) float32_t val, count ndarray[float32_t, ndim=2] maxx, nobs @@ -8635,42 +8878,44 @@ def group_max_float32(ndarray[float32_t, ndim=2] out, N, K = ( values).shape - if K > 1: - for i in range(N): - lab = labels[i] - if lab < 0: - continue + with nogil: + if K > 1: + for i in range(N): + lab = labels[i] + if lab < 0: + continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + counts[lab] += 1 + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[lab, j] += 1 + if val > maxx[lab, j]: + maxx[lab, j] = val + else: + for i in range(N): + lab = labels[i] + if lab < 0: + continue + + counts[lab] += 1 + val = values[i, 0] # not nan if val == val: - nobs[lab, j] += 1 - if val > maxx[lab, j]: - maxx[lab, j] = val - else: - for i in range(N): - lab = labels[i] - if lab < 0: - continue - - counts[lab] += 1 - val = values[i, 0] + nobs[lab, 0] += 1 + if val > maxx[lab, 0]: + maxx[lab, 0] = val - # not nan - if val == val: - nobs[lab, 0] += 1 - if val > maxx[lab, 0]: - maxx[lab, 0] = val + for i in range(ncounts): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = maxx[i, j] - for i in range(len(counts)): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = maxx[i, j] @cython.wraparound(False) @cython.boundscheck(False) def group_max_int64(ndarray[int64_t, ndim=2] out, @@ -8681,7 +8926,7 @@ def group_max_int64(ndarray[int64_t, ndim=2] out, Only aggregates on axis=0 ''' cdef: - Py_ssize_t i, j, N, K, lab + Py_ssize_t i, j, N, K, lab, ncounts = len(counts) int64_t val, count ndarray[int64_t, ndim=2] maxx, nobs @@ -8695,42 +8940,44 @@ def group_max_int64(ndarray[int64_t, ndim=2] out, N, K = ( values).shape - if K > 1: - for i in range(N): - lab = labels[i] - if lab < 0: - continue + with nogil: + if K > 1: + for i in range(N): + lab = labels[i] + if lab < 0: + continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + counts[lab] += 1 + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[lab, j] += 1 + if val > maxx[lab, j]: + maxx[lab, j] = val + else: + for i in range(N): + lab = labels[i] + if lab < 0: + continue + + counts[lab] += 1 + val = values[i, 0] # not nan if val == val: - nobs[lab, j] += 1 - if val > maxx[lab, j]: - maxx[lab, j] = val - else: - for i in range(N): - lab = labels[i] - if lab < 0: - continue - - counts[lab] += 1 - val = values[i, 0] + nobs[lab, 0] += 1 + if val > maxx[lab, 0]: + maxx[lab, 0] = val - # not nan - if val == val: - nobs[lab, 0] += 1 - if val > maxx[lab, 0]: - maxx[lab, 0] = val + for i in range(ncounts): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = iNaT + else: + out[i, j] = maxx[i, j] - for i in range(len(counts)): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = iNaT - else: - out[i, j] = maxx[i, j] @cython.wraparound(False) @cython.boundscheck(False) @@ -8750,48 +8997,52 @@ def group_max_bin_float64(ndarray[float64_t, ndim=2] out, maxx = np.empty_like(out) maxx.fill(-np.inf) + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: ngroups = len(bins) + 1 - N, K = ( values).shape + N, K = ( values).shape + + with nogil: + b = 0 + if K > 1: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 + + counts[b] += 1 + for j in range(K): + val = values[i, j] - b = 0 - if K > 1: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + # not nan + if val == val: + nobs[b, j] += 1 + if val > maxx[b, j]: + maxx[b, j] = val + else: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 - counts[b] += 1 - for j in range(K): - val = values[i, j] + counts[b] += 1 + val = values[i, 0] # not nan if val == val: - nobs[b, j] += 1 - if val > maxx[b, j]: - maxx[b, j] = val - else: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 - - counts[b] += 1 - val = values[i, 0] + nobs[b, 0] += 1 + if val > maxx[b, 0]: + maxx[b, 0] = val - # not nan - if val == val: - nobs[b, 0] += 1 - if val > maxx[b, 0]: - maxx[b, 0] = val + for i in range(ngroups): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = maxx[i, j] - for i in range(ngroups): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = maxx[i, j] @cython.wraparound(False) @cython.boundscheck(False) def group_max_bin_float32(ndarray[float32_t, ndim=2] out, @@ -8810,6 +9061,8 @@ def group_max_bin_float32(ndarray[float32_t, ndim=2] out, maxx = np.empty_like(out) maxx.fill(-np.inf) + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: @@ -8817,41 +9070,43 @@ def group_max_bin_float32(ndarray[float32_t, ndim=2] out, N, K = ( values).shape - b = 0 - if K > 1: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + with nogil: + b = 0 + if K > 1: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 - counts[b] += 1 - for j in range(K): - val = values[i, j] + counts[b] += 1 + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[b, j] += 1 + if val > maxx[b, j]: + maxx[b, j] = val + else: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 + + counts[b] += 1 + val = values[i, 0] # not nan if val == val: - nobs[b, j] += 1 - if val > maxx[b, j]: - maxx[b, j] = val - else: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + nobs[b, 0] += 1 + if val > maxx[b, 0]: + maxx[b, 0] = val - counts[b] += 1 - val = values[i, 0] - - # not nan - if val == val: - nobs[b, 0] += 1 - if val > maxx[b, 0]: - maxx[b, 0] = val + for i in range(ngroups): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = NAN + else: + out[i, j] = maxx[i, j] - for i in range(ngroups): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = nan - else: - out[i, j] = maxx[i, j] @cython.wraparound(False) @cython.boundscheck(False) def group_max_bin_int64(ndarray[int64_t, ndim=2] out, @@ -8870,6 +9125,8 @@ def group_max_bin_int64(ndarray[int64_t, ndim=2] out, maxx = np.empty_like(out) maxx.fill(-9223372036854775807) + if len(bins) == 0: + return if bins[len(bins) - 1] == len(values): ngroups = len(bins) else: @@ -8877,41 +9134,43 @@ def group_max_bin_int64(ndarray[int64_t, ndim=2] out, N, K = ( values).shape - b = 0 - if K > 1: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 + with nogil: + b = 0 + if K > 1: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 - counts[b] += 1 - for j in range(K): - val = values[i, j] + counts[b] += 1 + for j in range(K): + val = values[i, j] + + # not nan + if val == val: + nobs[b, j] += 1 + if val > maxx[b, j]: + maxx[b, j] = val + else: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 + + counts[b] += 1 + val = values[i, 0] # not nan if val == val: - nobs[b, j] += 1 - if val > maxx[b, j]: - maxx[b, j] = val - else: - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 - - counts[b] += 1 - val = values[i, 0] + nobs[b, 0] += 1 + if val > maxx[b, 0]: + maxx[b, 0] = val - # not nan - if val == val: - nobs[b, 0] += 1 - if val > maxx[b, 0]: - maxx[b, 0] = val + for i in range(ngroups): + for j in range(K): + if nobs[i, j] == 0: + out[i, j] = iNaT + else: + out[i, j] = maxx[i, j] - for i in range(ngroups): - for j in range(K): - if nobs[i, j] == 0: - out[i, j] = iNaT - else: - out[i, j] = maxx[i, j] @cython.boundscheck(False) @cython.wraparound(False) @@ -8923,31 +9182,32 @@ def group_count_float64(ndarray[float64_t, ndim=2] out, Only aggregates on axis=0 ''' cdef: - Py_ssize_t i, j, lab + Py_ssize_t i, j, lab, ncounts = len(counts) Py_ssize_t N = values.shape[0], K = values.shape[1] float64_t val ndarray[int64_t, ndim=2] nobs = np.zeros((out.shape[0], out.shape[1]), dtype=np.int64) if len(values) != len(labels): - raise AssertionError("len(index) != len(labels)") + raise AssertionError("len(index) != len(labels)") - for i in range(N): - lab = labels[i] - if lab < 0: - continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + with nogil: + for i in range(N): + lab = labels[i] + if lab < 0: + continue - # not nan - nobs[lab, j] += val == val and val != iNaT + counts[lab] += 1 + for j in range(K): + val = values[i, j] - for i in range(len(counts)): - for j in range(K): - out[i, j] = nobs[i, j] + # not nan + nobs[lab, j] += val == val and val != iNaT + for i in range(ncounts): + for j in range(K): + out[i, j] = nobs[i, j] @cython.boundscheck(False) @cython.wraparound(False) @@ -8959,31 +9219,32 @@ def group_count_float32(ndarray[float32_t, ndim=2] out, Only aggregates on axis=0 ''' cdef: - Py_ssize_t i, j, lab + Py_ssize_t i, j, lab, ncounts = len(counts) Py_ssize_t N = values.shape[0], K = values.shape[1] float32_t val ndarray[int64_t, ndim=2] nobs = np.zeros((out.shape[0], out.shape[1]), dtype=np.int64) if len(values) != len(labels): - raise AssertionError("len(index) != len(labels)") + raise AssertionError("len(index) != len(labels)") - for i in range(N): - lab = labels[i] - if lab < 0: - continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + with nogil: + for i in range(N): + lab = labels[i] + if lab < 0: + continue - # not nan - nobs[lab, j] += val == val and val != iNaT + counts[lab] += 1 + for j in range(K): + val = values[i, j] - for i in range(len(counts)): - for j in range(K): - out[i, j] = nobs[i, j] + # not nan + nobs[lab, j] += val == val and val != iNaT + for i in range(ncounts): + for j in range(K): + out[i, j] = nobs[i, j] @cython.boundscheck(False) @cython.wraparound(False) @@ -8995,31 +9256,32 @@ def group_count_int64(ndarray[int64_t, ndim=2] out, Only aggregates on axis=0 ''' cdef: - Py_ssize_t i, j, lab + Py_ssize_t i, j, lab, ncounts = len(counts) Py_ssize_t N = values.shape[0], K = values.shape[1] int64_t val ndarray[int64_t, ndim=2] nobs = np.zeros((out.shape[0], out.shape[1]), dtype=np.int64) if len(values) != len(labels): - raise AssertionError("len(index) != len(labels)") + raise AssertionError("len(index) != len(labels)") - for i in range(N): - lab = labels[i] - if lab < 0: - continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + with nogil: + for i in range(N): + lab = labels[i] + if lab < 0: + continue - # not nan - nobs[lab, j] += val == val and val != iNaT + counts[lab] += 1 + for j in range(K): + val = values[i, j] - for i in range(len(counts)): - for j in range(K): - out[i, j] = nobs[i, j] + # not nan + nobs[lab, j] += val == val and val != iNaT + for i in range(ncounts): + for j in range(K): + out[i, j] = nobs[i, j] @cython.boundscheck(False) @cython.wraparound(False) @@ -9031,15 +9293,17 @@ def group_count_object(ndarray[object, ndim=2] out, Only aggregates on axis=0 ''' cdef: - Py_ssize_t i, j, lab + Py_ssize_t i, j, lab, ncounts = len(counts) Py_ssize_t N = values.shape[0], K = values.shape[1] object val ndarray[int64_t, ndim=2] nobs = np.zeros((out.shape[0], out.shape[1]), dtype=np.int64) if len(values) != len(labels): - raise AssertionError("len(index) != len(labels)") + raise AssertionError("len(index) != len(labels)") + + for i in range(N): lab = labels[i] if lab < 0: @@ -9052,11 +9316,10 @@ def group_count_object(ndarray[object, ndim=2] out, # not nan nobs[lab, j] += val == val and val != iNaT - for i in range(len(counts)): + for i in range(ncounts): for j in range(K): out[i, j] = nobs[i, j] - @cython.boundscheck(False) @cython.wraparound(False) def group_count_int64(ndarray[int64_t, ndim=2] out, @@ -9067,35 +9330,36 @@ def group_count_int64(ndarray[int64_t, ndim=2] out, Only aggregates on axis=0 ''' cdef: - Py_ssize_t i, j, lab + Py_ssize_t i, j, lab, ncounts = len(counts) Py_ssize_t N = values.shape[0], K = values.shape[1] int64_t val ndarray[int64_t, ndim=2] nobs = np.zeros((out.shape[0], out.shape[1]), dtype=np.int64) if len(values) != len(labels): - raise AssertionError("len(index) != len(labels)") + raise AssertionError("len(index) != len(labels)") - for i in range(N): - lab = labels[i] - if lab < 0: - continue - counts[lab] += 1 - for j in range(K): - val = values[i, j] + with nogil: + for i in range(N): + lab = labels[i] + if lab < 0: + continue - # not nan - nobs[lab, j] += val == val and val != iNaT + counts[lab] += 1 + for j in range(K): + val = values[i, j] - for i in range(len(counts)): - for j in range(K): - out[i, j] = nobs[i, j] + # not nan + nobs[lab, j] += val == val and val != iNaT + for i in range(ncounts): + for j in range(K): + out[i, j] = nobs[i, j] -@cython.boundscheck(False) @cython.wraparound(False) +@cython.boundscheck(False) def group_count_bin_float64(ndarray[float64_t, ndim=2] out, ndarray[int64_t] counts, ndarray[float64_t, ndim=2] values, @@ -9110,26 +9374,28 @@ def group_count_bin_float64(ndarray[float64_t, ndim=2] out, ndarray[int64_t, ndim=2] nobs = np.zeros((out.shape[0], out.shape[1]), dtype=np.int64) + if len(bins) == 0: + return ngroups = len(bins) + (bins[len(bins) - 1] != N) - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 - - counts[b] += 1 - for j in range(K): - val = values[i, j] + with nogil: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 - # not nan - nobs[b, j] += val == val and val != iNaT + counts[b] += 1 + for j in range(K): + val = values[i, j] - for i in range(ngroups): - for j in range(K): - out[i, j] = nobs[i, j] + # not nan + nobs[b, j] += val == val and val != iNaT + for i in range(ngroups): + for j in range(K): + out[i, j] = nobs[i, j] -@cython.boundscheck(False) @cython.wraparound(False) +@cython.boundscheck(False) def group_count_bin_float32(ndarray[float32_t, ndim=2] out, ndarray[int64_t] counts, ndarray[float32_t, ndim=2] values, @@ -9144,26 +9410,28 @@ def group_count_bin_float32(ndarray[float32_t, ndim=2] out, ndarray[int64_t, ndim=2] nobs = np.zeros((out.shape[0], out.shape[1]), dtype=np.int64) + if len(bins) == 0: + return ngroups = len(bins) + (bins[len(bins) - 1] != N) - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 - - counts[b] += 1 - for j in range(K): - val = values[i, j] + with nogil: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 - # not nan - nobs[b, j] += val == val and val != iNaT + counts[b] += 1 + for j in range(K): + val = values[i, j] - for i in range(ngroups): - for j in range(K): - out[i, j] = nobs[i, j] + # not nan + nobs[b, j] += val == val and val != iNaT + for i in range(ngroups): + for j in range(K): + out[i, j] = nobs[i, j] -@cython.boundscheck(False) @cython.wraparound(False) +@cython.boundscheck(False) def group_count_bin_int64(ndarray[int64_t, ndim=2] out, ndarray[int64_t] counts, ndarray[int64_t, ndim=2] values, @@ -9178,26 +9446,28 @@ def group_count_bin_int64(ndarray[int64_t, ndim=2] out, ndarray[int64_t, ndim=2] nobs = np.zeros((out.shape[0], out.shape[1]), dtype=np.int64) + if len(bins) == 0: + return ngroups = len(bins) + (bins[len(bins) - 1] != N) - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 - - counts[b] += 1 - for j in range(K): - val = values[i, j] + with nogil: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 - # not nan - nobs[b, j] += val == val and val != iNaT + counts[b] += 1 + for j in range(K): + val = values[i, j] - for i in range(ngroups): - for j in range(K): - out[i, j] = nobs[i, j] + # not nan + nobs[b, j] += val == val and val != iNaT + for i in range(ngroups): + for j in range(K): + out[i, j] = nobs[i, j] -@cython.boundscheck(False) @cython.wraparound(False) +@cython.boundscheck(False) def group_count_bin_object(ndarray[object, ndim=2] out, ndarray[int64_t] counts, ndarray[object, ndim=2] values, @@ -9212,8 +9482,11 @@ def group_count_bin_object(ndarray[object, ndim=2] out, ndarray[int64_t, ndim=2] nobs = np.zeros((out.shape[0], out.shape[1]), dtype=np.int64) + if len(bins) == 0: + return ngroups = len(bins) + (bins[len(bins) - 1] != N) + for i in range(N): while b < ngroups - 1 and i >= bins[b]: b += 1 @@ -9229,9 +9502,8 @@ def group_count_bin_object(ndarray[object, ndim=2] out, for j in range(K): out[i, j] = nobs[i, j] - -@cython.boundscheck(False) @cython.wraparound(False) +@cython.boundscheck(False) def group_count_bin_int64(ndarray[int64_t, ndim=2] out, ndarray[int64_t] counts, ndarray[int64_t, ndim=2] values, @@ -9246,23 +9518,25 @@ def group_count_bin_int64(ndarray[int64_t, ndim=2] out, ndarray[int64_t, ndim=2] nobs = np.zeros((out.shape[0], out.shape[1]), dtype=np.int64) + if len(bins) == 0: + return ngroups = len(bins) + (bins[len(bins) - 1] != N) - for i in range(N): - while b < ngroups - 1 and i >= bins[b]: - b += 1 - - counts[b] += 1 - for j in range(K): - val = values[i, j] + with nogil: + for i in range(N): + while b < ngroups - 1 and i >= bins[b]: + b += 1 - # not nan - nobs[b, j] += val == val and val != iNaT + counts[b] += 1 + for j in range(K): + val = values[i, j] - for i in range(ngroups): - for j in range(K): - out[i, j] = nobs[i, j] + # not nan + nobs[b, j] += val == val and val != iNaT + for i in range(ngroups): + for j in range(K): + out[i, j] = nobs[i, j] @cython.wraparound(False) @@ -10071,7 +10345,7 @@ def outer_join_indexer_float64(ndarray[float64_t] left, rindexer[j] = j result[j] = right[j] elif nright == 0: - for i in range(nright): + for i in range(nleft): lindexer[i] = i rindexer[i] = -1 result[i] = left[i] @@ -10200,7 +10474,7 @@ def outer_join_indexer_float32(ndarray[float32_t] left, rindexer[j] = j result[j] = right[j] elif nright == 0: - for i in range(nright): + for i in range(nleft): lindexer[i] = i rindexer[i] = -1 result[i] = left[i] @@ -10329,7 +10603,7 @@ def outer_join_indexer_object(ndarray[object] left, rindexer[j] = j result[j] = right[j] elif nright == 0: - for i in range(nright): + for i in range(nleft): lindexer[i] = i rindexer[i] = -1 result[i] = left[i] @@ -10458,7 +10732,7 @@ def outer_join_indexer_int32(ndarray[int32_t] left, rindexer[j] = j result[j] = right[j] elif nright == 0: - for i in range(nright): + for i in range(nleft): lindexer[i] = i rindexer[i] = -1 result[i] = left[i] @@ -10587,7 +10861,7 @@ def outer_join_indexer_int64(ndarray[int64_t] left, rindexer[j] = j result[j] = right[j] elif nright == 0: - for i in range(nright): + for i in range(nleft): lindexer[i] = i rindexer[i] = -1 result[i] = left[i] diff --git a/pandas/src/headers/math.h b/pandas/src/headers/math.h index 8ccf11d07c3fe..34ad9f24a58f9 100644 --- a/pandas/src/headers/math.h +++ b/pandas/src/headers/math.h @@ -1,7 +1,7 @@ #ifndef _PANDAS_MATH_H_ #define _PANDAS_MATH_H_ -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER < 1800) #include __inline int signbit(double num) { return _copysign(1.0, num) < 0; } #else diff --git a/pandas/src/headers/stdint.h b/pandas/src/headers/stdint.h index b0fd235adc036..8746bf132d0f7 100644 --- a/pandas/src/headers/stdint.h +++ b/pandas/src/headers/stdint.h @@ -1,7 +1,7 @@ #ifndef _PANDAS_STDINT_H_ #define _PANDAS_STDINT_H_ -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER < 1900) #include "ms_stdint.h" #else #include diff --git a/pandas/src/khash.pxd b/pandas/src/khash.pxd index a8fd51a62cfbe..b28f43eecfac7 100644 --- a/pandas/src/khash.pxd +++ b/pandas/src/khash.pxd @@ -45,15 +45,15 @@ cdef extern from "khash_python.h": kh_cstr_t *keys size_t *vals - inline kh_str_t* kh_init_str() - inline void kh_destroy_str(kh_str_t*) - inline void kh_clear_str(kh_str_t*) - inline khint_t kh_get_str(kh_str_t*, kh_cstr_t) - inline void kh_resize_str(kh_str_t*, khint_t) - inline khint_t kh_put_str(kh_str_t*, kh_cstr_t, int*) - inline void kh_del_str(kh_str_t*, khint_t) + inline kh_str_t* kh_init_str() nogil + inline void kh_destroy_str(kh_str_t*) nogil + inline void kh_clear_str(kh_str_t*) nogil + inline khint_t kh_get_str(kh_str_t*, kh_cstr_t) nogil + inline void kh_resize_str(kh_str_t*, khint_t) nogil + inline khint_t kh_put_str(kh_str_t*, kh_cstr_t, int*) nogil + inline void kh_del_str(kh_str_t*, khint_t) nogil - bint kh_exist_str(kh_str_t*, khiter_t) + bint kh_exist_str(kh_str_t*, khiter_t) nogil ctypedef struct kh_int64_t: @@ -62,15 +62,15 @@ cdef extern from "khash_python.h": int64_t *keys size_t *vals - inline kh_int64_t* kh_init_int64() - inline void kh_destroy_int64(kh_int64_t*) - inline void kh_clear_int64(kh_int64_t*) - inline khint_t kh_get_int64(kh_int64_t*, int64_t) - inline void kh_resize_int64(kh_int64_t*, khint_t) - inline khint_t kh_put_int64(kh_int64_t*, int64_t, int*) - inline void kh_del_int64(kh_int64_t*, khint_t) + inline kh_int64_t* kh_init_int64() nogil + inline void kh_destroy_int64(kh_int64_t*) nogil + inline void kh_clear_int64(kh_int64_t*) nogil + inline khint_t kh_get_int64(kh_int64_t*, int64_t) nogil + inline void kh_resize_int64(kh_int64_t*, khint_t) nogil + inline khint_t kh_put_int64(kh_int64_t*, int64_t, int*) nogil + inline void kh_del_int64(kh_int64_t*, khint_t) nogil - bint kh_exist_int64(kh_int64_t*, khiter_t) + bint kh_exist_int64(kh_int64_t*, khiter_t) nogil ctypedef struct kh_float64_t: khint_t n_buckets, size, n_occupied, upper_bound @@ -78,15 +78,15 @@ cdef extern from "khash_python.h": float64_t *keys size_t *vals - inline kh_float64_t* kh_init_float64() - inline void kh_destroy_float64(kh_float64_t*) - inline void kh_clear_float64(kh_float64_t*) - inline khint_t kh_get_float64(kh_float64_t*, float64_t) - inline void kh_resize_float64(kh_float64_t*, khint_t) - inline khint_t kh_put_float64(kh_float64_t*, float64_t, int*) - inline void kh_del_float64(kh_float64_t*, khint_t) + inline kh_float64_t* kh_init_float64() nogil + inline void kh_destroy_float64(kh_float64_t*) nogil + inline void kh_clear_float64(kh_float64_t*) nogil + inline khint_t kh_get_float64(kh_float64_t*, float64_t) nogil + inline void kh_resize_float64(kh_float64_t*, khint_t) nogil + inline khint_t kh_put_float64(kh_float64_t*, float64_t, int*) nogil + inline void kh_del_float64(kh_float64_t*, khint_t) nogil - bint kh_exist_float64(kh_float64_t*, khiter_t) + bint kh_exist_float64(kh_float64_t*, khiter_t) nogil ctypedef struct kh_int32_t: khint_t n_buckets, size, n_occupied, upper_bound @@ -94,15 +94,15 @@ cdef extern from "khash_python.h": int32_t *keys size_t *vals - inline kh_int32_t* kh_init_int32() - inline void kh_destroy_int32(kh_int32_t*) - inline void kh_clear_int32(kh_int32_t*) - inline khint_t kh_get_int32(kh_int32_t*, int32_t) - inline void kh_resize_int32(kh_int32_t*, khint_t) - inline khint_t kh_put_int32(kh_int32_t*, int32_t, int*) - inline void kh_del_int32(kh_int32_t*, khint_t) + inline kh_int32_t* kh_init_int32() nogil + inline void kh_destroy_int32(kh_int32_t*) nogil + inline void kh_clear_int32(kh_int32_t*) nogil + inline khint_t kh_get_int32(kh_int32_t*, int32_t) nogil + inline void kh_resize_int32(kh_int32_t*, khint_t) nogil + inline khint_t kh_put_int32(kh_int32_t*, int32_t, int*) nogil + inline void kh_del_int32(kh_int32_t*, khint_t) nogil - bint kh_exist_int32(kh_int32_t*, khiter_t) + bint kh_exist_int32(kh_int32_t*, khiter_t) nogil # sweep factorize @@ -112,13 +112,12 @@ cdef extern from "khash_python.h": kh_cstr_t *keys PyObject **vals - inline kh_strbox_t* kh_init_strbox() - inline void kh_destroy_strbox(kh_strbox_t*) - inline void kh_clear_strbox(kh_strbox_t*) - inline khint_t kh_get_strbox(kh_strbox_t*, kh_cstr_t) - inline void kh_resize_strbox(kh_strbox_t*, khint_t) - inline khint_t kh_put_strbox(kh_strbox_t*, kh_cstr_t, int*) - inline void kh_del_strbox(kh_strbox_t*, khint_t) - - bint kh_exist_strbox(kh_strbox_t*, khiter_t) + inline kh_strbox_t* kh_init_strbox() nogil + inline void kh_destroy_strbox(kh_strbox_t*) nogil + inline void kh_clear_strbox(kh_strbox_t*) nogil + inline khint_t kh_get_strbox(kh_strbox_t*, kh_cstr_t) nogil + inline void kh_resize_strbox(kh_strbox_t*, khint_t) nogil + inline khint_t kh_put_strbox(kh_strbox_t*, kh_cstr_t, int*) nogil + inline void kh_del_strbox(kh_strbox_t*, khint_t) nogil + bint kh_exist_strbox(kh_strbox_t*, khiter_t) nogil diff --git a/pandas/src/msgpack/pack.h b/pandas/src/msgpack/pack.h index bb939d93ebeca..02379c9188424 100644 --- a/pandas/src/msgpack/pack.h +++ b/pandas/src/msgpack/pack.h @@ -26,7 +26,7 @@ extern "C" { #endif -#ifdef _MSC_VER +#if defined(_MSC_VER) && (_MSC_VER < 1900) #define inline __inline #endif @@ -34,18 +34,18 @@ typedef struct msgpack_packer { char *buf; size_t length; size_t buf_size; + bool use_bin_type; } msgpack_packer; typedef struct Packer Packer; -static inline int msgpack_pack_short(msgpack_packer* pk, short d); static inline int msgpack_pack_int(msgpack_packer* pk, int d); static inline int msgpack_pack_long(msgpack_packer* pk, long d); static inline int msgpack_pack_long_long(msgpack_packer* pk, long long d); static inline int msgpack_pack_unsigned_short(msgpack_packer* pk, unsigned short d); static inline int msgpack_pack_unsigned_int(msgpack_packer* pk, unsigned int d); static inline int msgpack_pack_unsigned_long(msgpack_packer* pk, unsigned long d); -static inline int msgpack_pack_unsigned_long_long(msgpack_packer* pk, unsigned long long d); +//static inline int msgpack_pack_unsigned_long_long(msgpack_packer* pk, unsigned long long d); static inline int msgpack_pack_uint8(msgpack_packer* pk, uint8_t d); static inline int msgpack_pack_uint16(msgpack_packer* pk, uint16_t d); @@ -68,8 +68,11 @@ static inline int msgpack_pack_array(msgpack_packer* pk, unsigned int n); static inline int msgpack_pack_map(msgpack_packer* pk, unsigned int n); static inline int msgpack_pack_raw(msgpack_packer* pk, size_t l); +static inline int msgpack_pack_bin(msgpack_packer* pk, size_t l); static inline int msgpack_pack_raw_body(msgpack_packer* pk, const void* b, size_t l); +static inline int msgpack_pack_ext(msgpack_packer* pk, char typecode, size_t l); + static inline int msgpack_pack_write(msgpack_packer* pk, const char *data, size_t l) { char* buf = pk->buf; @@ -90,14 +93,6 @@ static inline int msgpack_pack_write(msgpack_packer* pk, const char *data, size_ return 0; } -#define msgpack_pack_inline_func(name) \ - static inline int msgpack_pack ## name - -#define msgpack_pack_inline_func_cint(name) \ - static inline int msgpack_pack ## name - -#define msgpack_pack_user msgpack_packer* - #define msgpack_pack_append_buffer(user, buf, len) \ return msgpack_pack_write(user, (const char*)buf, len) diff --git a/pandas/src/msgpack/pack_template.h b/pandas/src/msgpack/pack_template.h index 65c959dd8ce63..5d1088f4b7d78 100644 --- a/pandas/src/msgpack/pack_template.h +++ b/pandas/src/msgpack/pack_template.h @@ -28,14 +28,6 @@ #define TAKE8_64(d) ((uint8_t*)&d)[7] #endif -#ifndef msgpack_pack_inline_func -#error msgpack_pack_inline_func template is not defined -#endif - -#ifndef msgpack_pack_user -#error msgpack_pack_user type is not defined -#endif - #ifndef msgpack_pack_append_buffer #error msgpack_pack_append_buffer callback is not defined #endif @@ -47,584 +39,524 @@ #define msgpack_pack_real_uint8(x, d) \ do { \ - if(d < (1<<7)) { \ - /* fixnum */ \ - msgpack_pack_append_buffer(x, &TAKE8_8(d), 1); \ - } else { \ - /* unsigned 8 */ \ - unsigned char buf[2] = {0xcc, TAKE8_8(d)}; \ - msgpack_pack_append_buffer(x, buf, 2); \ - } \ + if(d < (1<<7)) { \ + /* fixnum */ \ + msgpack_pack_append_buffer(x, &TAKE8_8(d), 1); \ + } else { \ + /* unsigned 8 */ \ + unsigned char buf[2] = {0xcc, TAKE8_8(d)}; \ + msgpack_pack_append_buffer(x, buf, 2); \ + } \ } while(0) #define msgpack_pack_real_uint16(x, d) \ do { \ - if(d < (1<<7)) { \ - /* fixnum */ \ - msgpack_pack_append_buffer(x, &TAKE8_16(d), 1); \ - } else if(d < (1<<8)) { \ - /* unsigned 8 */ \ - unsigned char buf[2] = {0xcc, TAKE8_16(d)}; \ - msgpack_pack_append_buffer(x, buf, 2); \ - } else { \ - /* unsigned 16 */ \ - unsigned char buf[3]; \ - buf[0] = 0xcd; _msgpack_store16(&buf[1], (uint16_t)d); \ - msgpack_pack_append_buffer(x, buf, 3); \ - } \ + if(d < (1<<7)) { \ + /* fixnum */ \ + msgpack_pack_append_buffer(x, &TAKE8_16(d), 1); \ + } else if(d < (1<<8)) { \ + /* unsigned 8 */ \ + unsigned char buf[2] = {0xcc, TAKE8_16(d)}; \ + msgpack_pack_append_buffer(x, buf, 2); \ + } else { \ + /* unsigned 16 */ \ + unsigned char buf[3]; \ + buf[0] = 0xcd; _msgpack_store16(&buf[1], (uint16_t)d); \ + msgpack_pack_append_buffer(x, buf, 3); \ + } \ } while(0) #define msgpack_pack_real_uint32(x, d) \ do { \ - if(d < (1<<8)) { \ - if(d < (1<<7)) { \ - /* fixnum */ \ - msgpack_pack_append_buffer(x, &TAKE8_32(d), 1); \ - } else { \ - /* unsigned 8 */ \ - unsigned char buf[2] = {0xcc, TAKE8_32(d)}; \ - msgpack_pack_append_buffer(x, buf, 2); \ - } \ - } else { \ - if(d < (1<<16)) { \ - /* unsigned 16 */ \ - unsigned char buf[3]; \ - buf[0] = 0xcd; _msgpack_store16(&buf[1], (uint16_t)d); \ - msgpack_pack_append_buffer(x, buf, 3); \ - } else { \ - /* unsigned 32 */ \ - unsigned char buf[5]; \ - buf[0] = 0xce; _msgpack_store32(&buf[1], (uint32_t)d); \ - msgpack_pack_append_buffer(x, buf, 5); \ - } \ - } \ + if(d < (1<<8)) { \ + if(d < (1<<7)) { \ + /* fixnum */ \ + msgpack_pack_append_buffer(x, &TAKE8_32(d), 1); \ + } else { \ + /* unsigned 8 */ \ + unsigned char buf[2] = {0xcc, TAKE8_32(d)}; \ + msgpack_pack_append_buffer(x, buf, 2); \ + } \ + } else { \ + if(d < (1<<16)) { \ + /* unsigned 16 */ \ + unsigned char buf[3]; \ + buf[0] = 0xcd; _msgpack_store16(&buf[1], (uint16_t)d); \ + msgpack_pack_append_buffer(x, buf, 3); \ + } else { \ + /* unsigned 32 */ \ + unsigned char buf[5]; \ + buf[0] = 0xce; _msgpack_store32(&buf[1], (uint32_t)d); \ + msgpack_pack_append_buffer(x, buf, 5); \ + } \ + } \ } while(0) #define msgpack_pack_real_uint64(x, d) \ do { \ - if(d < (1ULL<<8)) { \ - if(d < (1ULL<<7)) { \ - /* fixnum */ \ - msgpack_pack_append_buffer(x, &TAKE8_64(d), 1); \ - } else { \ - /* unsigned 8 */ \ - unsigned char buf[2] = {0xcc, TAKE8_64(d)}; \ - msgpack_pack_append_buffer(x, buf, 2); \ - } \ - } else { \ - if(d < (1ULL<<16)) { \ - /* unsigned 16 */ \ - unsigned char buf[3]; \ - buf[0] = 0xcd; _msgpack_store16(&buf[1], (uint16_t)d); \ - msgpack_pack_append_buffer(x, buf, 3); \ - } else if(d < (1ULL<<32)) { \ - /* unsigned 32 */ \ - unsigned char buf[5]; \ - buf[0] = 0xce; _msgpack_store32(&buf[1], (uint32_t)d); \ - msgpack_pack_append_buffer(x, buf, 5); \ - } else { \ - /* unsigned 64 */ \ - unsigned char buf[9]; \ - buf[0] = 0xcf; _msgpack_store64(&buf[1], d); \ - msgpack_pack_append_buffer(x, buf, 9); \ - } \ - } \ + if(d < (1ULL<<8)) { \ + if(d < (1ULL<<7)) { \ + /* fixnum */ \ + msgpack_pack_append_buffer(x, &TAKE8_64(d), 1); \ + } else { \ + /* unsigned 8 */ \ + unsigned char buf[2] = {0xcc, TAKE8_64(d)}; \ + msgpack_pack_append_buffer(x, buf, 2); \ + } \ + } else { \ + if(d < (1ULL<<16)) { \ + /* unsigned 16 */ \ + unsigned char buf[3]; \ + buf[0] = 0xcd; _msgpack_store16(&buf[1], (uint16_t)d); \ + msgpack_pack_append_buffer(x, buf, 3); \ + } else if(d < (1ULL<<32)) { \ + /* unsigned 32 */ \ + unsigned char buf[5]; \ + buf[0] = 0xce; _msgpack_store32(&buf[1], (uint32_t)d); \ + msgpack_pack_append_buffer(x, buf, 5); \ + } else { \ + /* unsigned 64 */ \ + unsigned char buf[9]; \ + buf[0] = 0xcf; _msgpack_store64(&buf[1], d); \ + msgpack_pack_append_buffer(x, buf, 9); \ + } \ + } \ } while(0) #define msgpack_pack_real_int8(x, d) \ do { \ - if(d < -(1<<5)) { \ - /* signed 8 */ \ - unsigned char buf[2] = {0xd0, TAKE8_8(d)}; \ - msgpack_pack_append_buffer(x, buf, 2); \ - } else { \ - /* fixnum */ \ - msgpack_pack_append_buffer(x, &TAKE8_8(d), 1); \ - } \ + if(d < -(1<<5)) { \ + /* signed 8 */ \ + unsigned char buf[2] = {0xd0, TAKE8_8(d)}; \ + msgpack_pack_append_buffer(x, buf, 2); \ + } else { \ + /* fixnum */ \ + msgpack_pack_append_buffer(x, &TAKE8_8(d), 1); \ + } \ } while(0) #define msgpack_pack_real_int16(x, d) \ do { \ - if(d < -(1<<5)) { \ - if(d < -(1<<7)) { \ - /* signed 16 */ \ - unsigned char buf[3]; \ - buf[0] = 0xd1; _msgpack_store16(&buf[1], (int16_t)d); \ - msgpack_pack_append_buffer(x, buf, 3); \ - } else { \ - /* signed 8 */ \ - unsigned char buf[2] = {0xd0, TAKE8_16(d)}; \ - msgpack_pack_append_buffer(x, buf, 2); \ - } \ - } else if(d < (1<<7)) { \ - /* fixnum */ \ - msgpack_pack_append_buffer(x, &TAKE8_16(d), 1); \ - } else { \ - if(d < (1<<8)) { \ - /* unsigned 8 */ \ - unsigned char buf[2] = {0xcc, TAKE8_16(d)}; \ - msgpack_pack_append_buffer(x, buf, 2); \ - } else { \ - /* unsigned 16 */ \ - unsigned char buf[3]; \ - buf[0] = 0xcd; _msgpack_store16(&buf[1], (uint16_t)d); \ - msgpack_pack_append_buffer(x, buf, 3); \ - } \ - } \ + if(d < -(1<<5)) { \ + if(d < -(1<<7)) { \ + /* signed 16 */ \ + unsigned char buf[3]; \ + buf[0] = 0xd1; _msgpack_store16(&buf[1], (int16_t)d); \ + msgpack_pack_append_buffer(x, buf, 3); \ + } else { \ + /* signed 8 */ \ + unsigned char buf[2] = {0xd0, TAKE8_16(d)}; \ + msgpack_pack_append_buffer(x, buf, 2); \ + } \ + } else if(d < (1<<7)) { \ + /* fixnum */ \ + msgpack_pack_append_buffer(x, &TAKE8_16(d), 1); \ + } else { \ + if(d < (1<<8)) { \ + /* unsigned 8 */ \ + unsigned char buf[2] = {0xcc, TAKE8_16(d)}; \ + msgpack_pack_append_buffer(x, buf, 2); \ + } else { \ + /* unsigned 16 */ \ + unsigned char buf[3]; \ + buf[0] = 0xcd; _msgpack_store16(&buf[1], (uint16_t)d); \ + msgpack_pack_append_buffer(x, buf, 3); \ + } \ + } \ } while(0) #define msgpack_pack_real_int32(x, d) \ do { \ - if(d < -(1<<5)) { \ - if(d < -(1<<15)) { \ - /* signed 32 */ \ - unsigned char buf[5]; \ - buf[0] = 0xd2; _msgpack_store32(&buf[1], (int32_t)d); \ - msgpack_pack_append_buffer(x, buf, 5); \ - } else if(d < -(1<<7)) { \ - /* signed 16 */ \ - unsigned char buf[3]; \ - buf[0] = 0xd1; _msgpack_store16(&buf[1], (int16_t)d); \ - msgpack_pack_append_buffer(x, buf, 3); \ - } else { \ - /* signed 8 */ \ - unsigned char buf[2] = {0xd0, TAKE8_32(d)}; \ - msgpack_pack_append_buffer(x, buf, 2); \ - } \ - } else if(d < (1<<7)) { \ - /* fixnum */ \ - msgpack_pack_append_buffer(x, &TAKE8_32(d), 1); \ - } else { \ - if(d < (1<<8)) { \ - /* unsigned 8 */ \ - unsigned char buf[2] = {0xcc, TAKE8_32(d)}; \ - msgpack_pack_append_buffer(x, buf, 2); \ - } else if(d < (1<<16)) { \ - /* unsigned 16 */ \ - unsigned char buf[3]; \ - buf[0] = 0xcd; _msgpack_store16(&buf[1], (uint16_t)d); \ - msgpack_pack_append_buffer(x, buf, 3); \ - } else { \ - /* unsigned 32 */ \ - unsigned char buf[5]; \ - buf[0] = 0xce; _msgpack_store32(&buf[1], (uint32_t)d); \ - msgpack_pack_append_buffer(x, buf, 5); \ - } \ - } \ + if(d < -(1<<5)) { \ + if(d < -(1<<15)) { \ + /* signed 32 */ \ + unsigned char buf[5]; \ + buf[0] = 0xd2; _msgpack_store32(&buf[1], (int32_t)d); \ + msgpack_pack_append_buffer(x, buf, 5); \ + } else if(d < -(1<<7)) { \ + /* signed 16 */ \ + unsigned char buf[3]; \ + buf[0] = 0xd1; _msgpack_store16(&buf[1], (int16_t)d); \ + msgpack_pack_append_buffer(x, buf, 3); \ + } else { \ + /* signed 8 */ \ + unsigned char buf[2] = {0xd0, TAKE8_32(d)}; \ + msgpack_pack_append_buffer(x, buf, 2); \ + } \ + } else if(d < (1<<7)) { \ + /* fixnum */ \ + msgpack_pack_append_buffer(x, &TAKE8_32(d), 1); \ + } else { \ + if(d < (1<<8)) { \ + /* unsigned 8 */ \ + unsigned char buf[2] = {0xcc, TAKE8_32(d)}; \ + msgpack_pack_append_buffer(x, buf, 2); \ + } else if(d < (1<<16)) { \ + /* unsigned 16 */ \ + unsigned char buf[3]; \ + buf[0] = 0xcd; _msgpack_store16(&buf[1], (uint16_t)d); \ + msgpack_pack_append_buffer(x, buf, 3); \ + } else { \ + /* unsigned 32 */ \ + unsigned char buf[5]; \ + buf[0] = 0xce; _msgpack_store32(&buf[1], (uint32_t)d); \ + msgpack_pack_append_buffer(x, buf, 5); \ + } \ + } \ } while(0) #define msgpack_pack_real_int64(x, d) \ do { \ - if(d < -(1LL<<5)) { \ - if(d < -(1LL<<15)) { \ - if(d < -(1LL<<31)) { \ - /* signed 64 */ \ - unsigned char buf[9]; \ - buf[0] = 0xd3; _msgpack_store64(&buf[1], d); \ - msgpack_pack_append_buffer(x, buf, 9); \ - } else { \ - /* signed 32 */ \ - unsigned char buf[5]; \ - buf[0] = 0xd2; _msgpack_store32(&buf[1], (int32_t)d); \ - msgpack_pack_append_buffer(x, buf, 5); \ - } \ - } else { \ - if(d < -(1<<7)) { \ - /* signed 16 */ \ - unsigned char buf[3]; \ - buf[0] = 0xd1; _msgpack_store16(&buf[1], (int16_t)d); \ - msgpack_pack_append_buffer(x, buf, 3); \ - } else { \ - /* signed 8 */ \ - unsigned char buf[2] = {0xd0, TAKE8_64(d)}; \ - msgpack_pack_append_buffer(x, buf, 2); \ - } \ - } \ - } else if(d < (1<<7)) { \ - /* fixnum */ \ - msgpack_pack_append_buffer(x, &TAKE8_64(d), 1); \ - } else { \ - if(d < (1LL<<16)) { \ - if(d < (1<<8)) { \ - /* unsigned 8 */ \ - unsigned char buf[2] = {0xcc, TAKE8_64(d)}; \ - msgpack_pack_append_buffer(x, buf, 2); \ - } else { \ - /* unsigned 16 */ \ - unsigned char buf[3]; \ - buf[0] = 0xcd; _msgpack_store16(&buf[1], (uint16_t)d); \ - msgpack_pack_append_buffer(x, buf, 3); \ - } \ - } else { \ - if(d < (1LL<<32)) { \ - /* unsigned 32 */ \ - unsigned char buf[5]; \ - buf[0] = 0xce; _msgpack_store32(&buf[1], (uint32_t)d); \ - msgpack_pack_append_buffer(x, buf, 5); \ - } else { \ - /* unsigned 64 */ \ - unsigned char buf[9]; \ - buf[0] = 0xcf; _msgpack_store64(&buf[1], d); \ - msgpack_pack_append_buffer(x, buf, 9); \ - } \ - } \ - } \ + if(d < -(1LL<<5)) { \ + if(d < -(1LL<<15)) { \ + if(d < -(1LL<<31)) { \ + /* signed 64 */ \ + unsigned char buf[9]; \ + buf[0] = 0xd3; _msgpack_store64(&buf[1], d); \ + msgpack_pack_append_buffer(x, buf, 9); \ + } else { \ + /* signed 32 */ \ + unsigned char buf[5]; \ + buf[0] = 0xd2; _msgpack_store32(&buf[1], (int32_t)d); \ + msgpack_pack_append_buffer(x, buf, 5); \ + } \ + } else { \ + if(d < -(1<<7)) { \ + /* signed 16 */ \ + unsigned char buf[3]; \ + buf[0] = 0xd1; _msgpack_store16(&buf[1], (int16_t)d); \ + msgpack_pack_append_buffer(x, buf, 3); \ + } else { \ + /* signed 8 */ \ + unsigned char buf[2] = {0xd0, TAKE8_64(d)}; \ + msgpack_pack_append_buffer(x, buf, 2); \ + } \ + } \ + } else if(d < (1<<7)) { \ + /* fixnum */ \ + msgpack_pack_append_buffer(x, &TAKE8_64(d), 1); \ + } else { \ + if(d < (1LL<<16)) { \ + if(d < (1<<8)) { \ + /* unsigned 8 */ \ + unsigned char buf[2] = {0xcc, TAKE8_64(d)}; \ + msgpack_pack_append_buffer(x, buf, 2); \ + } else { \ + /* unsigned 16 */ \ + unsigned char buf[3]; \ + buf[0] = 0xcd; _msgpack_store16(&buf[1], (uint16_t)d); \ + msgpack_pack_append_buffer(x, buf, 3); \ + } \ + } else { \ + if(d < (1LL<<32)) { \ + /* unsigned 32 */ \ + unsigned char buf[5]; \ + buf[0] = 0xce; _msgpack_store32(&buf[1], (uint32_t)d); \ + msgpack_pack_append_buffer(x, buf, 5); \ + } else { \ + /* unsigned 64 */ \ + unsigned char buf[9]; \ + buf[0] = 0xcf; _msgpack_store64(&buf[1], d); \ + msgpack_pack_append_buffer(x, buf, 9); \ + } \ + } \ + } \ } while(0) -#ifdef msgpack_pack_inline_func_fixint - -msgpack_pack_inline_func_fixint(_uint8)(msgpack_pack_user x, uint8_t d) -{ - unsigned char buf[2] = {0xcc, TAKE8_8(d)}; - msgpack_pack_append_buffer(x, buf, 2); -} - -msgpack_pack_inline_func_fixint(_uint16)(msgpack_pack_user x, uint16_t d) -{ - unsigned char buf[3]; - buf[0] = 0xcd; _msgpack_store16(&buf[1], d); - msgpack_pack_append_buffer(x, buf, 3); -} - -msgpack_pack_inline_func_fixint(_uint32)(msgpack_pack_user x, uint32_t d) -{ - unsigned char buf[5]; - buf[0] = 0xce; _msgpack_store32(&buf[1], d); - msgpack_pack_append_buffer(x, buf, 5); -} - -msgpack_pack_inline_func_fixint(_uint64)(msgpack_pack_user x, uint64_t d) -{ - unsigned char buf[9]; - buf[0] = 0xcf; _msgpack_store64(&buf[1], d); - msgpack_pack_append_buffer(x, buf, 9); -} - -msgpack_pack_inline_func_fixint(_int8)(msgpack_pack_user x, int8_t d) +static inline int msgpack_pack_uint8(msgpack_packer* x, uint8_t d) { - unsigned char buf[2] = {0xd0, TAKE8_8(d)}; - msgpack_pack_append_buffer(x, buf, 2); + msgpack_pack_real_uint8(x, d); } -msgpack_pack_inline_func_fixint(_int16)(msgpack_pack_user x, int16_t d) +static inline int msgpack_pack_uint16(msgpack_packer* x, uint16_t d) { - unsigned char buf[3]; - buf[0] = 0xd1; _msgpack_store16(&buf[1], d); - msgpack_pack_append_buffer(x, buf, 3); + msgpack_pack_real_uint16(x, d); } -msgpack_pack_inline_func_fixint(_int32)(msgpack_pack_user x, int32_t d) +static inline int msgpack_pack_uint32(msgpack_packer* x, uint32_t d) { - unsigned char buf[5]; - buf[0] = 0xd2; _msgpack_store32(&buf[1], d); - msgpack_pack_append_buffer(x, buf, 5); + msgpack_pack_real_uint32(x, d); } -msgpack_pack_inline_func_fixint(_int64)(msgpack_pack_user x, int64_t d) +static inline int msgpack_pack_uint64(msgpack_packer* x, uint64_t d) { - unsigned char buf[9]; - buf[0] = 0xd3; _msgpack_store64(&buf[1], d); - msgpack_pack_append_buffer(x, buf, 9); + msgpack_pack_real_uint64(x, d); } -#undef msgpack_pack_inline_func_fixint -#endif - - -msgpack_pack_inline_func(_uint8)(msgpack_pack_user x, uint8_t d) +static inline int msgpack_pack_int8(msgpack_packer* x, int8_t d) { - msgpack_pack_real_uint8(x, d); + msgpack_pack_real_int8(x, d); } -msgpack_pack_inline_func(_uint16)(msgpack_pack_user x, uint16_t d) +static inline int msgpack_pack_int16(msgpack_packer* x, int16_t d) { - msgpack_pack_real_uint16(x, d); + msgpack_pack_real_int16(x, d); } -msgpack_pack_inline_func(_uint32)(msgpack_pack_user x, uint32_t d) +static inline int msgpack_pack_int32(msgpack_packer* x, int32_t d) { - msgpack_pack_real_uint32(x, d); + msgpack_pack_real_int32(x, d); } -msgpack_pack_inline_func(_uint64)(msgpack_pack_user x, uint64_t d) +static inline int msgpack_pack_int64(msgpack_packer* x, int64_t d) { - msgpack_pack_real_uint64(x, d); + msgpack_pack_real_int64(x, d); } -msgpack_pack_inline_func(_int8)(msgpack_pack_user x, int8_t d) -{ - msgpack_pack_real_int8(x, d); -} -msgpack_pack_inline_func(_int16)(msgpack_pack_user x, int16_t d) -{ - msgpack_pack_real_int16(x, d); -} +//#ifdef msgpack_pack_inline_func_cint -msgpack_pack_inline_func(_int32)(msgpack_pack_user x, int32_t d) -{ - msgpack_pack_real_int32(x, d); -} - -msgpack_pack_inline_func(_int64)(msgpack_pack_user x, int64_t d) -{ - msgpack_pack_real_int64(x, d); -} - - -#ifdef msgpack_pack_inline_func_cint - -msgpack_pack_inline_func_cint(_short)(msgpack_pack_user x, short d) +static inline int msgpack_pack_short(msgpack_packer* x, short d) { #if defined(SIZEOF_SHORT) #if SIZEOF_SHORT == 2 - msgpack_pack_real_int16(x, d); + msgpack_pack_real_int16(x, d); #elif SIZEOF_SHORT == 4 - msgpack_pack_real_int32(x, d); + msgpack_pack_real_int32(x, d); #else - msgpack_pack_real_int64(x, d); + msgpack_pack_real_int64(x, d); #endif #elif defined(SHRT_MAX) #if SHRT_MAX == 0x7fff - msgpack_pack_real_int16(x, d); + msgpack_pack_real_int16(x, d); #elif SHRT_MAX == 0x7fffffff - msgpack_pack_real_int32(x, d); + msgpack_pack_real_int32(x, d); #else - msgpack_pack_real_int64(x, d); + msgpack_pack_real_int64(x, d); #endif #else if(sizeof(short) == 2) { - msgpack_pack_real_int16(x, d); + msgpack_pack_real_int16(x, d); } else if(sizeof(short) == 4) { - msgpack_pack_real_int32(x, d); + msgpack_pack_real_int32(x, d); } else { - msgpack_pack_real_int64(x, d); + msgpack_pack_real_int64(x, d); } #endif } -msgpack_pack_inline_func_cint(_int)(msgpack_pack_user x, int d) +static inline int msgpack_pack_int(msgpack_packer* x, int d) { #if defined(SIZEOF_INT) #if SIZEOF_INT == 2 - msgpack_pack_real_int16(x, d); + msgpack_pack_real_int16(x, d); #elif SIZEOF_INT == 4 - msgpack_pack_real_int32(x, d); + msgpack_pack_real_int32(x, d); #else - msgpack_pack_real_int64(x, d); + msgpack_pack_real_int64(x, d); #endif #elif defined(INT_MAX) #if INT_MAX == 0x7fff - msgpack_pack_real_int16(x, d); + msgpack_pack_real_int16(x, d); #elif INT_MAX == 0x7fffffff - msgpack_pack_real_int32(x, d); + msgpack_pack_real_int32(x, d); #else - msgpack_pack_real_int64(x, d); + msgpack_pack_real_int64(x, d); #endif #else if(sizeof(int) == 2) { - msgpack_pack_real_int16(x, d); + msgpack_pack_real_int16(x, d); } else if(sizeof(int) == 4) { - msgpack_pack_real_int32(x, d); + msgpack_pack_real_int32(x, d); } else { - msgpack_pack_real_int64(x, d); + msgpack_pack_real_int64(x, d); } #endif } -msgpack_pack_inline_func_cint(_long)(msgpack_pack_user x, long d) +static inline int msgpack_pack_long(msgpack_packer* x, long d) { #if defined(SIZEOF_LONG) #if SIZEOF_LONG == 2 - msgpack_pack_real_int16(x, d); + msgpack_pack_real_int16(x, d); #elif SIZEOF_LONG == 4 - msgpack_pack_real_int32(x, d); + msgpack_pack_real_int32(x, d); #else - msgpack_pack_real_int64(x, d); + msgpack_pack_real_int64(x, d); #endif #elif defined(LONG_MAX) #if LONG_MAX == 0x7fffL - msgpack_pack_real_int16(x, d); + msgpack_pack_real_int16(x, d); #elif LONG_MAX == 0x7fffffffL - msgpack_pack_real_int32(x, d); + msgpack_pack_real_int32(x, d); #else - msgpack_pack_real_int64(x, d); + msgpack_pack_real_int64(x, d); #endif #else if(sizeof(long) == 2) { - msgpack_pack_real_int16(x, d); + msgpack_pack_real_int16(x, d); } else if(sizeof(long) == 4) { - msgpack_pack_real_int32(x, d); + msgpack_pack_real_int32(x, d); } else { - msgpack_pack_real_int64(x, d); + msgpack_pack_real_int64(x, d); } #endif } -msgpack_pack_inline_func_cint(_long_long)(msgpack_pack_user x, long long d) +static inline int msgpack_pack_long_long(msgpack_packer* x, long long d) { #if defined(SIZEOF_LONG_LONG) #if SIZEOF_LONG_LONG == 2 - msgpack_pack_real_int16(x, d); + msgpack_pack_real_int16(x, d); #elif SIZEOF_LONG_LONG == 4 - msgpack_pack_real_int32(x, d); + msgpack_pack_real_int32(x, d); #else - msgpack_pack_real_int64(x, d); + msgpack_pack_real_int64(x, d); #endif #elif defined(LLONG_MAX) #if LLONG_MAX == 0x7fffL - msgpack_pack_real_int16(x, d); + msgpack_pack_real_int16(x, d); #elif LLONG_MAX == 0x7fffffffL - msgpack_pack_real_int32(x, d); + msgpack_pack_real_int32(x, d); #else - msgpack_pack_real_int64(x, d); + msgpack_pack_real_int64(x, d); #endif #else if(sizeof(long long) == 2) { - msgpack_pack_real_int16(x, d); + msgpack_pack_real_int16(x, d); } else if(sizeof(long long) == 4) { - msgpack_pack_real_int32(x, d); + msgpack_pack_real_int32(x, d); } else { - msgpack_pack_real_int64(x, d); + msgpack_pack_real_int64(x, d); } #endif } -msgpack_pack_inline_func_cint(_unsigned_short)(msgpack_pack_user x, unsigned short d) +static inline int msgpack_pack_unsigned_short(msgpack_packer* x, unsigned short d) { #if defined(SIZEOF_SHORT) #if SIZEOF_SHORT == 2 - msgpack_pack_real_uint16(x, d); + msgpack_pack_real_uint16(x, d); #elif SIZEOF_SHORT == 4 - msgpack_pack_real_uint32(x, d); + msgpack_pack_real_uint32(x, d); #else - msgpack_pack_real_uint64(x, d); + msgpack_pack_real_uint64(x, d); #endif #elif defined(USHRT_MAX) #if USHRT_MAX == 0xffffU - msgpack_pack_real_uint16(x, d); + msgpack_pack_real_uint16(x, d); #elif USHRT_MAX == 0xffffffffU - msgpack_pack_real_uint32(x, d); + msgpack_pack_real_uint32(x, d); #else - msgpack_pack_real_uint64(x, d); + msgpack_pack_real_uint64(x, d); #endif #else if(sizeof(unsigned short) == 2) { - msgpack_pack_real_uint16(x, d); + msgpack_pack_real_uint16(x, d); } else if(sizeof(unsigned short) == 4) { - msgpack_pack_real_uint32(x, d); + msgpack_pack_real_uint32(x, d); } else { - msgpack_pack_real_uint64(x, d); + msgpack_pack_real_uint64(x, d); } #endif } -msgpack_pack_inline_func_cint(_unsigned_int)(msgpack_pack_user x, unsigned int d) +static inline int msgpack_pack_unsigned_int(msgpack_packer* x, unsigned int d) { #if defined(SIZEOF_INT) #if SIZEOF_INT == 2 - msgpack_pack_real_uint16(x, d); + msgpack_pack_real_uint16(x, d); #elif SIZEOF_INT == 4 - msgpack_pack_real_uint32(x, d); + msgpack_pack_real_uint32(x, d); #else - msgpack_pack_real_uint64(x, d); + msgpack_pack_real_uint64(x, d); #endif #elif defined(UINT_MAX) #if UINT_MAX == 0xffffU - msgpack_pack_real_uint16(x, d); + msgpack_pack_real_uint16(x, d); #elif UINT_MAX == 0xffffffffU - msgpack_pack_real_uint32(x, d); + msgpack_pack_real_uint32(x, d); #else - msgpack_pack_real_uint64(x, d); + msgpack_pack_real_uint64(x, d); #endif #else if(sizeof(unsigned int) == 2) { - msgpack_pack_real_uint16(x, d); + msgpack_pack_real_uint16(x, d); } else if(sizeof(unsigned int) == 4) { - msgpack_pack_real_uint32(x, d); + msgpack_pack_real_uint32(x, d); } else { - msgpack_pack_real_uint64(x, d); + msgpack_pack_real_uint64(x, d); } #endif } -msgpack_pack_inline_func_cint(_unsigned_long)(msgpack_pack_user x, unsigned long d) +static inline int msgpack_pack_unsigned_long(msgpack_packer* x, unsigned long d) { #if defined(SIZEOF_LONG) #if SIZEOF_LONG == 2 - msgpack_pack_real_uint16(x, d); + msgpack_pack_real_uint16(x, d); #elif SIZEOF_LONG == 4 - msgpack_pack_real_uint32(x, d); + msgpack_pack_real_uint32(x, d); #else - msgpack_pack_real_uint64(x, d); + msgpack_pack_real_uint64(x, d); #endif #elif defined(ULONG_MAX) #if ULONG_MAX == 0xffffUL - msgpack_pack_real_uint16(x, d); + msgpack_pack_real_uint16(x, d); #elif ULONG_MAX == 0xffffffffUL - msgpack_pack_real_uint32(x, d); + msgpack_pack_real_uint32(x, d); #else - msgpack_pack_real_uint64(x, d); + msgpack_pack_real_uint64(x, d); #endif #else if(sizeof(unsigned long) == 2) { - msgpack_pack_real_uint16(x, d); + msgpack_pack_real_uint16(x, d); } else if(sizeof(unsigned long) == 4) { - msgpack_pack_real_uint32(x, d); + msgpack_pack_real_uint32(x, d); } else { - msgpack_pack_real_uint64(x, d); + msgpack_pack_real_uint64(x, d); } #endif } -msgpack_pack_inline_func_cint(_unsigned_long_long)(msgpack_pack_user x, unsigned long long d) +static inline int msgpack_pack_unsigned_long_long(msgpack_packer* x, unsigned long long d) { #if defined(SIZEOF_LONG_LONG) #if SIZEOF_LONG_LONG == 2 - msgpack_pack_real_uint16(x, d); + msgpack_pack_real_uint16(x, d); #elif SIZEOF_LONG_LONG == 4 - msgpack_pack_real_uint32(x, d); + msgpack_pack_real_uint32(x, d); #else - msgpack_pack_real_uint64(x, d); + msgpack_pack_real_uint64(x, d); #endif #elif defined(ULLONG_MAX) #if ULLONG_MAX == 0xffffUL - msgpack_pack_real_uint16(x, d); + msgpack_pack_real_uint16(x, d); #elif ULLONG_MAX == 0xffffffffUL - msgpack_pack_real_uint32(x, d); + msgpack_pack_real_uint32(x, d); #else - msgpack_pack_real_uint64(x, d); + msgpack_pack_real_uint64(x, d); #endif #else if(sizeof(unsigned long long) == 2) { - msgpack_pack_real_uint16(x, d); + msgpack_pack_real_uint16(x, d); } else if(sizeof(unsigned long long) == 4) { - msgpack_pack_real_uint32(x, d); + msgpack_pack_real_uint32(x, d); } else { - msgpack_pack_real_uint64(x, d); + msgpack_pack_real_uint64(x, d); } #endif } -#undef msgpack_pack_inline_func_cint -#endif +//#undef msgpack_pack_inline_func_cint +//#endif @@ -632,27 +564,27 @@ if(sizeof(unsigned long long) == 2) { * Float */ -msgpack_pack_inline_func(_float)(msgpack_pack_user x, float d) +static inline int msgpack_pack_float(msgpack_packer* x, float d) { - union { float f; uint32_t i; } mem; - mem.f = d; - unsigned char buf[5]; - buf[0] = 0xca; _msgpack_store32(&buf[1], mem.i); - msgpack_pack_append_buffer(x, buf, 5); + union { float f; uint32_t i; } mem; + mem.f = d; + unsigned char buf[5]; + buf[0] = 0xca; _msgpack_store32(&buf[1], mem.i); + msgpack_pack_append_buffer(x, buf, 5); } -msgpack_pack_inline_func(_double)(msgpack_pack_user x, double d) +static inline int msgpack_pack_double(msgpack_packer* x, double d) { - union { double f; uint64_t i; } mem; - mem.f = d; - unsigned char buf[9]; - buf[0] = 0xcb; + union { double f; uint64_t i; } mem; + mem.f = d; + unsigned char buf[9]; + buf[0] = 0xcb; #if defined(__arm__) && !(__ARM_EABI__) // arm-oabi // https://github.com/msgpack/msgpack-perl/pull/1 mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL); #endif _msgpack_store64(&buf[1], mem.i); - msgpack_pack_append_buffer(x, buf, 9); + msgpack_pack_append_buffer(x, buf, 9); } @@ -660,10 +592,10 @@ msgpack_pack_inline_func(_double)(msgpack_pack_user x, double d) * Nil */ -msgpack_pack_inline_func(_nil)(msgpack_pack_user x) +static inline int msgpack_pack_nil(msgpack_packer* x) { - static const unsigned char d = 0xc0; - msgpack_pack_append_buffer(x, &d, 1); + static const unsigned char d = 0xc0; + msgpack_pack_append_buffer(x, &d, 1); } @@ -671,16 +603,16 @@ msgpack_pack_inline_func(_nil)(msgpack_pack_user x) * Boolean */ -msgpack_pack_inline_func(_true)(msgpack_pack_user x) +static inline int msgpack_pack_true(msgpack_packer* x) { - static const unsigned char d = 0xc3; - msgpack_pack_append_buffer(x, &d, 1); + static const unsigned char d = 0xc3; + msgpack_pack_append_buffer(x, &d, 1); } -msgpack_pack_inline_func(_false)(msgpack_pack_user x) +static inline int msgpack_pack_false(msgpack_packer* x) { - static const unsigned char d = 0xc2; - msgpack_pack_append_buffer(x, &d, 1); + static const unsigned char d = 0xc2; + msgpack_pack_append_buffer(x, &d, 1); } @@ -688,20 +620,20 @@ msgpack_pack_inline_func(_false)(msgpack_pack_user x) * Array */ -msgpack_pack_inline_func(_array)(msgpack_pack_user x, unsigned int n) +static inline int msgpack_pack_array(msgpack_packer* x, unsigned int n) { - if(n < 16) { - unsigned char d = 0x90 | n; - msgpack_pack_append_buffer(x, &d, 1); - } else if(n < 65536) { - unsigned char buf[3]; - buf[0] = 0xdc; _msgpack_store16(&buf[1], (uint16_t)n); - msgpack_pack_append_buffer(x, buf, 3); - } else { - unsigned char buf[5]; - buf[0] = 0xdd; _msgpack_store32(&buf[1], (uint32_t)n); - msgpack_pack_append_buffer(x, buf, 5); - } + if(n < 16) { + unsigned char d = 0x90 | n; + msgpack_pack_append_buffer(x, &d, 1); + } else if(n < 65536) { + unsigned char buf[3]; + buf[0] = 0xdc; _msgpack_store16(&buf[1], (uint16_t)n); + msgpack_pack_append_buffer(x, buf, 3); + } else { + unsigned char buf[5]; + buf[0] = 0xdd; _msgpack_store32(&buf[1], (uint32_t)n); + msgpack_pack_append_buffer(x, buf, 5); + } } @@ -709,20 +641,20 @@ msgpack_pack_inline_func(_array)(msgpack_pack_user x, unsigned int n) * Map */ -msgpack_pack_inline_func(_map)(msgpack_pack_user x, unsigned int n) +static inline int msgpack_pack_map(msgpack_packer* x, unsigned int n) { - if(n < 16) { - unsigned char d = 0x80 | n; - msgpack_pack_append_buffer(x, &TAKE8_8(d), 1); - } else if(n < 65536) { - unsigned char buf[3]; - buf[0] = 0xde; _msgpack_store16(&buf[1], (uint16_t)n); - msgpack_pack_append_buffer(x, buf, 3); - } else { - unsigned char buf[5]; - buf[0] = 0xdf; _msgpack_store32(&buf[1], (uint32_t)n); - msgpack_pack_append_buffer(x, buf, 5); - } + if(n < 16) { + unsigned char d = 0x80 | n; + msgpack_pack_append_buffer(x, &TAKE8_8(d), 1); + } else if(n < 65536) { + unsigned char buf[3]; + buf[0] = 0xde; _msgpack_store16(&buf[1], (uint16_t)n); + msgpack_pack_append_buffer(x, buf, 3); + } else { + unsigned char buf[5]; + buf[0] = 0xdf; _msgpack_store32(&buf[1], (uint32_t)n); + msgpack_pack_append_buffer(x, buf, 5); + } } @@ -730,29 +662,112 @@ msgpack_pack_inline_func(_map)(msgpack_pack_user x, unsigned int n) * Raw */ -msgpack_pack_inline_func(_raw)(msgpack_pack_user x, size_t l) +static inline int msgpack_pack_raw(msgpack_packer* x, size_t l) +{ + if (l < 32) { + unsigned char d = 0xa0 | (uint8_t)l; + msgpack_pack_append_buffer(x, &TAKE8_8(d), 1); + } else if (x->use_bin_type && l < 256) { // str8 is new format introduced with bin. + unsigned char buf[2] = {0xd9, (uint8_t)l}; + msgpack_pack_append_buffer(x, buf, 2); + } else if (l < 65536) { + unsigned char buf[3]; + buf[0] = 0xda; _msgpack_store16(&buf[1], (uint16_t)l); + msgpack_pack_append_buffer(x, buf, 3); + } else { + unsigned char buf[5]; + buf[0] = 0xdb; _msgpack_store32(&buf[1], (uint32_t)l); + msgpack_pack_append_buffer(x, buf, 5); + } +} + +/* + * bin + */ +static inline int msgpack_pack_bin(msgpack_packer *x, size_t l) { - if(l < 32) { - unsigned char d = 0xa0 | (uint8_t)l; - msgpack_pack_append_buffer(x, &TAKE8_8(d), 1); - } else if(l < 65536) { - unsigned char buf[3]; - buf[0] = 0xda; _msgpack_store16(&buf[1], (uint16_t)l); - msgpack_pack_append_buffer(x, buf, 3); - } else { - unsigned char buf[5]; - buf[0] = 0xdb; _msgpack_store32(&buf[1], (uint32_t)l); - msgpack_pack_append_buffer(x, buf, 5); - } -} - -msgpack_pack_inline_func(_raw_body)(msgpack_pack_user x, const void* b, size_t l) + if (!x->use_bin_type) { + return msgpack_pack_raw(x, l); + } + if (l < 256) { + unsigned char buf[2] = {0xc4, (unsigned char)l}; + msgpack_pack_append_buffer(x, buf, 2); + } else if (l < 65536) { + unsigned char buf[3] = {0xc5}; + _msgpack_store16(&buf[1], (uint16_t)l); + msgpack_pack_append_buffer(x, buf, 3); + } else { + unsigned char buf[5] = {0xc6}; + _msgpack_store32(&buf[1], (uint32_t)l); + msgpack_pack_append_buffer(x, buf, 5); + } +} + +static inline int msgpack_pack_raw_body(msgpack_packer* x, const void* b, size_t l) { - msgpack_pack_append_buffer(x, (const unsigned char*)b, l); + if (l > 0) msgpack_pack_append_buffer(x, (const unsigned char*)b, l); + return 0; } -#undef msgpack_pack_inline_func -#undef msgpack_pack_user +/* + * Ext + */ +static inline int msgpack_pack_ext(msgpack_packer* x, char typecode, size_t l) +{ + if (l == 1) { + unsigned char buf[2]; + buf[0] = 0xd4; + buf[1] = (unsigned char)typecode; + msgpack_pack_append_buffer(x, buf, 2); + } + else if(l == 2) { + unsigned char buf[2]; + buf[0] = 0xd5; + buf[1] = (unsigned char)typecode; + msgpack_pack_append_buffer(x, buf, 2); + } + else if(l == 4) { + unsigned char buf[2]; + buf[0] = 0xd6; + buf[1] = (unsigned char)typecode; + msgpack_pack_append_buffer(x, buf, 2); + } + else if(l == 8) { + unsigned char buf[2]; + buf[0] = 0xd7; + buf[1] = (unsigned char)typecode; + msgpack_pack_append_buffer(x, buf, 2); + } + else if(l == 16) { + unsigned char buf[2]; + buf[0] = 0xd8; + buf[1] = (unsigned char)typecode; + msgpack_pack_append_buffer(x, buf, 2); + } + else if(l < 256) { + unsigned char buf[3]; + buf[0] = 0xc7; + buf[1] = l; + buf[2] = (unsigned char)typecode; + msgpack_pack_append_buffer(x, buf, 3); + } else if(l < 65536) { + unsigned char buf[4]; + buf[0] = 0xc8; + _msgpack_store16(&buf[1], (uint16_t)l); + buf[3] = (unsigned char)typecode; + msgpack_pack_append_buffer(x, buf, 4); + } else { + unsigned char buf[6]; + buf[0] = 0xc9; + _msgpack_store32(&buf[1], (uint32_t)l); + buf[5] = (unsigned char)typecode; + msgpack_pack_append_buffer(x, buf, 6); + } + +} + + + #undef msgpack_pack_append_buffer #undef TAKE8_8 @@ -768,4 +783,3 @@ msgpack_pack_inline_func(_raw_body)(msgpack_pack_user x, const void* b, size_t l #undef msgpack_pack_real_int16 #undef msgpack_pack_real_int32 #undef msgpack_pack_real_int64 - diff --git a/pandas/src/msgpack/sysdep.h b/pandas/src/msgpack/sysdep.h index 4fedbd8ba472f..ed9c1bc0b8031 100644 --- a/pandas/src/msgpack/sysdep.h +++ b/pandas/src/msgpack/sysdep.h @@ -192,4 +192,3 @@ typedef unsigned int _msgpack_atomic_counter_t; #endif /* msgpack/sysdep.h */ - diff --git a/pandas/src/msgpack/unpack.h b/pandas/src/msgpack/unpack.h index 3dc88e5fbded0..5deb7cde0b929 100644 --- a/pandas/src/msgpack/unpack.h +++ b/pandas/src/msgpack/unpack.h @@ -24,35 +24,23 @@ typedef struct unpack_user { PyObject *object_hook; bool has_pairs_hook; PyObject *list_hook; + PyObject *ext_hook; const char *encoding; const char *unicode_errors; + Py_ssize_t max_str_len, max_bin_len, max_array_len, max_map_len, max_ext_len; } unpack_user; +typedef PyObject* msgpack_unpack_object; +struct unpack_context; +typedef struct unpack_context unpack_context; +typedef int (*execute_fn)(unpack_context *ctx, const char* data, size_t len, size_t* off); -#define msgpack_unpack_struct(name) \ - struct template ## name - -#define msgpack_unpack_func(ret, name) \ - static inline ret template ## name - -#define msgpack_unpack_callback(name) \ - template_callback ## name - -#define msgpack_unpack_object PyObject* - -#define msgpack_unpack_user unpack_user - -typedef int (*execute_fn)(msgpack_unpack_struct(_context)* ctx, const char* data, size_t len, size_t* off); - -struct template_context; -typedef struct template_context template_context; - -static inline msgpack_unpack_object template_callback_root(unpack_user* u) +static inline msgpack_unpack_object unpack_callback_root(unpack_user* u) { return NULL; } -static inline int template_callback_uint16(unpack_user* u, uint16_t d, msgpack_unpack_object* o) +static inline int unpack_callback_uint16(unpack_user* u, uint16_t d, msgpack_unpack_object* o) { PyObject *p = PyInt_FromLong((long)d); if (!p) @@ -60,36 +48,36 @@ static inline int template_callback_uint16(unpack_user* u, uint16_t d, msgpack_u *o = p; return 0; } -static inline int template_callback_uint8(unpack_user* u, uint8_t d, msgpack_unpack_object* o) +static inline int unpack_callback_uint8(unpack_user* u, uint8_t d, msgpack_unpack_object* o) { - return template_callback_uint16(u, d, o); + return unpack_callback_uint16(u, d, o); } -static inline int template_callback_uint32(unpack_user* u, uint32_t d, msgpack_unpack_object* o) +static inline int unpack_callback_uint32(unpack_user* u, uint32_t d, msgpack_unpack_object* o) { - PyObject *p; - if (d > LONG_MAX) { - p = PyLong_FromUnsignedLong((unsigned long)d); - } else { - p = PyInt_FromLong((long)d); - } + PyObject *p = PyInt_FromSize_t((size_t)d); if (!p) return -1; *o = p; return 0; } -static inline int template_callback_uint64(unpack_user* u, uint64_t d, msgpack_unpack_object* o) +static inline int unpack_callback_uint64(unpack_user* u, uint64_t d, msgpack_unpack_object* o) { - PyObject *p = PyLong_FromUnsignedLongLong(d); + PyObject *p; + if (d > LONG_MAX) { + p = PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)d); + } else { + p = PyInt_FromSize_t((size_t)d); + } if (!p) return -1; *o = p; return 0; } -static inline int template_callback_int32(unpack_user* u, int32_t d, msgpack_unpack_object* o) +static inline int unpack_callback_int32(unpack_user* u, int32_t d, msgpack_unpack_object* o) { PyObject *p = PyInt_FromLong(d); if (!p) @@ -98,26 +86,29 @@ static inline int template_callback_int32(unpack_user* u, int32_t d, msgpack_unp return 0; } -static inline int template_callback_int16(unpack_user* u, int16_t d, msgpack_unpack_object* o) +static inline int unpack_callback_int16(unpack_user* u, int16_t d, msgpack_unpack_object* o) { - return template_callback_int32(u, d, o); + return unpack_callback_int32(u, d, o); } -static inline int template_callback_int8(unpack_user* u, int8_t d, msgpack_unpack_object* o) +static inline int unpack_callback_int8(unpack_user* u, int8_t d, msgpack_unpack_object* o) { - return template_callback_int32(u, d, o); + return unpack_callback_int32(u, d, o); } -static inline int template_callback_int64(unpack_user* u, int64_t d, msgpack_unpack_object* o) +static inline int unpack_callback_int64(unpack_user* u, int64_t d, msgpack_unpack_object* o) { - PyObject *p = PyLong_FromLongLong(d); - if (!p) - return -1; + PyObject *p; + if (d > LONG_MAX || d < LONG_MIN) { + p = PyLong_FromLongLong((unsigned PY_LONG_LONG)d); + } else { + p = PyInt_FromLong((long)d); + } *o = p; return 0; } -static inline int template_callback_double(unpack_user* u, double d, msgpack_unpack_object* o) +static inline int unpack_callback_double(unpack_user* u, double d, msgpack_unpack_object* o) { PyObject *p = PyFloat_FromDouble(d); if (!p) @@ -126,22 +117,26 @@ static inline int template_callback_double(unpack_user* u, double d, msgpack_unp return 0; } -static inline int template_callback_float(unpack_user* u, float d, msgpack_unpack_object* o) +static inline int unpack_callback_float(unpack_user* u, float d, msgpack_unpack_object* o) { - return template_callback_double(u, d, o); + return unpack_callback_double(u, d, o); } -static inline int template_callback_nil(unpack_user* u, msgpack_unpack_object* o) +static inline int unpack_callback_nil(unpack_user* u, msgpack_unpack_object* o) { Py_INCREF(Py_None); *o = Py_None; return 0; } -static inline int template_callback_true(unpack_user* u, msgpack_unpack_object* o) +static inline int unpack_callback_true(unpack_user* u, msgpack_unpack_object* o) { Py_INCREF(Py_True); *o = Py_True; return 0; } -static inline int template_callback_false(unpack_user* u, msgpack_unpack_object* o) +static inline int unpack_callback_false(unpack_user* u, msgpack_unpack_object* o) { Py_INCREF(Py_False); *o = Py_False; return 0; } -static inline int template_callback_array(unpack_user* u, unsigned int n, msgpack_unpack_object* o) +static inline int unpack_callback_array(unpack_user* u, unsigned int n, msgpack_unpack_object* o) { + if (n > u->max_array_len) { + PyErr_Format(PyExc_ValueError, "%u exceeds max_array_len(%zd)", n, u->max_array_len); + return -1; + } PyObject *p = u->use_list ? PyList_New(n) : PyTuple_New(n); if (!p) @@ -150,7 +145,7 @@ static inline int template_callback_array(unpack_user* u, unsigned int n, msgpac return 0; } -static inline int template_callback_array_item(unpack_user* u, unsigned int current, msgpack_unpack_object* c, msgpack_unpack_object o) +static inline int unpack_callback_array_item(unpack_user* u, unsigned int current, msgpack_unpack_object* c, msgpack_unpack_object o) { if (u->use_list) PyList_SET_ITEM(*c, current, o); @@ -159,10 +154,10 @@ static inline int template_callback_array_item(unpack_user* u, unsigned int curr return 0; } -static inline int template_callback_array_end(unpack_user* u, msgpack_unpack_object* c) +static inline int unpack_callback_array_end(unpack_user* u, msgpack_unpack_object* c) { if (u->list_hook) { - PyObject *new_c = PyEval_CallFunction(u->list_hook, "(O)", *c); + PyObject *new_c = PyObject_CallFunctionObjArgs(u->list_hook, *c, NULL); if (!new_c) return -1; Py_DECREF(*c); @@ -171,8 +166,12 @@ static inline int template_callback_array_end(unpack_user* u, msgpack_unpack_obj return 0; } -static inline int template_callback_map(unpack_user* u, unsigned int n, msgpack_unpack_object* o) +static inline int unpack_callback_map(unpack_user* u, unsigned int n, msgpack_unpack_object* o) { + if (n > u->max_map_len) { + PyErr_Format(PyExc_ValueError, "%u exceeds max_map_len(%zd)", n, u->max_map_len); + return -1; + } PyObject *p; if (u->has_pairs_hook) { p = PyList_New(n); // Or use tuple? @@ -186,7 +185,7 @@ static inline int template_callback_map(unpack_user* u, unsigned int n, msgpack_ return 0; } -static inline int template_callback_map_item(unpack_user* u, unsigned int current, msgpack_unpack_object* c, msgpack_unpack_object k, msgpack_unpack_object v) +static inline int unpack_callback_map_item(unpack_user* u, unsigned int current, msgpack_unpack_object* c, msgpack_unpack_object k, msgpack_unpack_object v) { if (u->has_pairs_hook) { msgpack_unpack_object item = PyTuple_Pack(2, k, v); @@ -205,10 +204,10 @@ static inline int template_callback_map_item(unpack_user* u, unsigned int curren return -1; } -static inline int template_callback_map_end(unpack_user* u, msgpack_unpack_object* c) +static inline int unpack_callback_map_end(unpack_user* u, msgpack_unpack_object* c) { if (u->object_hook) { - PyObject *new_c = PyEval_CallFunction(u->object_hook, "(O)", *c); + PyObject *new_c = PyObject_CallFunctionObjArgs(u->object_hook, *c, NULL); if (!new_c) return -1; @@ -218,8 +217,13 @@ static inline int template_callback_map_end(unpack_user* u, msgpack_unpack_objec return 0; } -static inline int template_callback_raw(unpack_user* u, const char* b, const char* p, unsigned int l, msgpack_unpack_object* o) +static inline int unpack_callback_raw(unpack_user* u, const char* b, const char* p, unsigned int l, msgpack_unpack_object* o) { + if (l > u->max_str_len) { + PyErr_Format(PyExc_ValueError, "%u exceeds max_str_len(%zd)", l, u->max_str_len); + return -1; + } + PyObject *py; if(u->encoding) { py = PyUnicode_Decode(p, l, u->encoding, u->unicode_errors); @@ -232,4 +236,43 @@ static inline int template_callback_raw(unpack_user* u, const char* b, const cha return 0; } +static inline int unpack_callback_bin(unpack_user* u, const char* b, const char* p, unsigned int l, msgpack_unpack_object* o) +{ + if (l > u->max_bin_len) { + PyErr_Format(PyExc_ValueError, "%u exceeds max_bin_len(%zd)", l, u->max_bin_len); + return -1; + } + + PyObject *py = PyBytes_FromStringAndSize(p, l); + if (!py) + return -1; + *o = py; + return 0; +} + +static inline int unpack_callback_ext(unpack_user* u, const char* base, const char* pos, + unsigned int length, msgpack_unpack_object* o) +{ + PyObject *py; + int8_t typecode = (int8_t)*pos++; + if (!u->ext_hook) { + PyErr_SetString(PyExc_AssertionError, "u->ext_hook cannot be NULL"); + return -1; + } + if (length-1 > u->max_ext_len) { + PyErr_Format(PyExc_ValueError, "%u exceeds max_ext_len(%zd)", length, u->max_ext_len); + return -1; + } + // length also includes the typecode, so the actual data is length-1 +#if PY_MAJOR_VERSION == 2 + py = PyObject_CallFunction(u->ext_hook, "(is#)", typecode, pos, length-1); +#else + py = PyObject_CallFunction(u->ext_hook, "(iy#)", typecode, pos, length-1); +#endif + if (!py) + return -1; + *o = py; + return 0; +} + #include "unpack_template.h" diff --git a/pandas/src/msgpack/unpack_define.h b/pandas/src/msgpack/unpack_define.h index 959d3519e7b5c..0dd708d17c3d4 100644 --- a/pandas/src/msgpack/unpack_define.h +++ b/pandas/src/msgpack/unpack_define.h @@ -34,54 +34,57 @@ extern "C" { #endif +// CS is first byte & 0x1f typedef enum { - CS_HEADER = 0x00, // nil - - //CS_ = 0x01, - //CS_ = 0x02, // false - //CS_ = 0x03, // true - - //CS_ = 0x04, - //CS_ = 0x05, - //CS_ = 0x06, - //CS_ = 0x07, - - //CS_ = 0x08, - //CS_ = 0x09, - CS_FLOAT = 0x0a, - CS_DOUBLE = 0x0b, - CS_UINT_8 = 0x0c, - CS_UINT_16 = 0x0d, - CS_UINT_32 = 0x0e, - CS_UINT_64 = 0x0f, - CS_INT_8 = 0x10, - CS_INT_16 = 0x11, - CS_INT_32 = 0x12, - CS_INT_64 = 0x13, - - //CS_ = 0x14, - //CS_ = 0x15, - //CS_BIG_INT_16 = 0x16, - //CS_BIG_INT_32 = 0x17, - //CS_BIG_FLOAT_16 = 0x18, - //CS_BIG_FLOAT_32 = 0x19, - CS_RAW_16 = 0x1a, - CS_RAW_32 = 0x1b, - CS_ARRAY_16 = 0x1c, - CS_ARRAY_32 = 0x1d, - CS_MAP_16 = 0x1e, - CS_MAP_32 = 0x1f, - - //ACS_BIG_INT_VALUE, - //ACS_BIG_FLOAT_VALUE, - ACS_RAW_VALUE, + CS_HEADER = 0x00, // nil + + //CS_ = 0x01, + //CS_ = 0x02, // false + //CS_ = 0x03, // true + + CS_BIN_8 = 0x04, + CS_BIN_16 = 0x05, + CS_BIN_32 = 0x06, + + CS_EXT_8 = 0x07, + CS_EXT_16 = 0x08, + CS_EXT_32 = 0x09, + + CS_FLOAT = 0x0a, + CS_DOUBLE = 0x0b, + CS_UINT_8 = 0x0c, + CS_UINT_16 = 0x0d, + CS_UINT_32 = 0x0e, + CS_UINT_64 = 0x0f, + CS_INT_8 = 0x10, + CS_INT_16 = 0x11, + CS_INT_32 = 0x12, + CS_INT_64 = 0x13, + + //CS_FIXEXT1 = 0x14, + //CS_FIXEXT2 = 0x15, + //CS_FIXEXT4 = 0x16, + //CS_FIXEXT8 = 0x17, + //CS_FIXEXT16 = 0x18, + + CS_RAW_8 = 0x19, + CS_RAW_16 = 0x1a, + CS_RAW_32 = 0x1b, + CS_ARRAY_16 = 0x1c, + CS_ARRAY_32 = 0x1d, + CS_MAP_16 = 0x1e, + CS_MAP_32 = 0x1f, + + ACS_RAW_VALUE, + ACS_BIN_VALUE, + ACS_EXT_VALUE, } msgpack_unpack_state; typedef enum { - CT_ARRAY_ITEM, - CT_MAP_KEY, - CT_MAP_VALUE, + CT_ARRAY_ITEM, + CT_MAP_KEY, + CT_MAP_VALUE, } msgpack_container_type; @@ -90,4 +93,3 @@ typedef enum { #endif #endif /* msgpack/unpack_define.h */ - diff --git a/pandas/src/msgpack/unpack_template.h b/pandas/src/msgpack/unpack_template.h index 83b6918dc6686..d34eceda6ab69 100644 --- a/pandas/src/msgpack/unpack_template.h +++ b/pandas/src/msgpack/unpack_template.h @@ -16,167 +16,142 @@ * limitations under the License. */ -#ifndef msgpack_unpack_func -#error msgpack_unpack_func template is not defined -#endif - -#ifndef msgpack_unpack_callback -#error msgpack_unpack_callback template is not defined -#endif - -#ifndef msgpack_unpack_struct -#error msgpack_unpack_struct template is not defined -#endif - -#ifndef msgpack_unpack_struct_decl -#define msgpack_unpack_struct_decl(name) msgpack_unpack_struct(name) -#endif - -#ifndef msgpack_unpack_object -#error msgpack_unpack_object type is not defined -#endif - -#ifndef msgpack_unpack_user -#error msgpack_unpack_user type is not defined -#endif - #ifndef USE_CASE_RANGE #if !defined(_MSC_VER) #define USE_CASE_RANGE #endif #endif -msgpack_unpack_struct_decl(_stack) { - msgpack_unpack_object obj; - size_t size; - size_t count; - unsigned int ct; - msgpack_unpack_object map_key; -}; - -msgpack_unpack_struct_decl(_context) { - msgpack_unpack_user user; - unsigned int cs; - unsigned int trail; - unsigned int top; - /* - msgpack_unpack_struct(_stack)* stack; - unsigned int stack_size; - msgpack_unpack_struct(_stack) embed_stack[MSGPACK_EMBED_STACK_SIZE]; - */ - msgpack_unpack_struct(_stack) stack[MSGPACK_EMBED_STACK_SIZE]; +typedef struct unpack_stack { + PyObject* obj; + size_t size; + size_t count; + unsigned int ct; + PyObject* map_key; +} unpack_stack; + +struct unpack_context { + unpack_user user; + unsigned int cs; + unsigned int trail; + unsigned int top; + /* + unpack_stack* stack; + unsigned int stack_size; + unpack_stack embed_stack[MSGPACK_EMBED_STACK_SIZE]; + */ + unpack_stack stack[MSGPACK_EMBED_STACK_SIZE]; }; -msgpack_unpack_func(void, _init)(msgpack_unpack_struct(_context)* ctx) +static inline void unpack_init(unpack_context* ctx) { - ctx->cs = CS_HEADER; - ctx->trail = 0; - ctx->top = 0; - /* - ctx->stack = ctx->embed_stack; - ctx->stack_size = MSGPACK_EMBED_STACK_SIZE; - */ - ctx->stack[0].obj = msgpack_unpack_callback(_root)(&ctx->user); + ctx->cs = CS_HEADER; + ctx->trail = 0; + ctx->top = 0; + /* + ctx->stack = ctx->embed_stack; + ctx->stack_size = MSGPACK_EMBED_STACK_SIZE; + */ + ctx->stack[0].obj = unpack_callback_root(&ctx->user); } /* -msgpack_unpack_func(void, _destroy)(msgpack_unpack_struct(_context)* ctx) +static inline void unpack_destroy(unpack_context* ctx) { - if(ctx->stack_size != MSGPACK_EMBED_STACK_SIZE) { - free(ctx->stack); - } + if(ctx->stack_size != MSGPACK_EMBED_STACK_SIZE) { + free(ctx->stack); + } } */ -msgpack_unpack_func(msgpack_unpack_object, _data)(msgpack_unpack_struct(_context)* ctx) +static inline PyObject* unpack_data(unpack_context* ctx) { - return (ctx)->stack[0].obj; + return (ctx)->stack[0].obj; } template -msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const char* data, size_t len, size_t* off) +static inline int unpack_execute(unpack_context* ctx, const char* data, size_t len, size_t* off) { - assert(len >= *off); + assert(len >= *off); - const unsigned char* p = (unsigned char*)data + *off; - const unsigned char* const pe = (unsigned char*)data + len; - const void* n = NULL; + const unsigned char* p = (unsigned char*)data + *off; + const unsigned char* const pe = (unsigned char*)data + len; + const void* n = NULL; - unsigned int trail = ctx->trail; - unsigned int cs = ctx->cs; - unsigned int top = ctx->top; - msgpack_unpack_struct(_stack)* stack = ctx->stack; - /* - unsigned int stack_size = ctx->stack_size; - */ - msgpack_unpack_user* user = &ctx->user; + unsigned int trail = ctx->trail; + unsigned int cs = ctx->cs; + unsigned int top = ctx->top; + unpack_stack* stack = ctx->stack; + /* + unsigned int stack_size = ctx->stack_size; + */ + unpack_user* user = &ctx->user; - msgpack_unpack_object obj; - msgpack_unpack_struct(_stack)* c = NULL; + PyObject* obj; + unpack_stack* c = NULL; - int ret; + int ret; #define construct_cb(name) \ - construct && msgpack_unpack_callback(name) + construct && unpack_callback ## name #define push_simple_value(func) \ - if(construct_cb(func)(user, &obj) < 0) { goto _failed; } \ - goto _push + if(construct_cb(func)(user, &obj) < 0) { goto _failed; } \ + goto _push #define push_fixed_value(func, arg) \ - if(construct_cb(func)(user, arg, &obj) < 0) { goto _failed; } \ - goto _push + if(construct_cb(func)(user, arg, &obj) < 0) { goto _failed; } \ + goto _push #define push_variable_value(func, base, pos, len) \ - if(construct_cb(func)(user, \ - (const char*)base, (const char*)pos, len, &obj) < 0) { goto _failed; } \ - goto _push + if(construct_cb(func)(user, \ + (const char*)base, (const char*)pos, len, &obj) < 0) { goto _failed; } \ + goto _push #define again_fixed_trail(_cs, trail_len) \ - trail = trail_len; \ - cs = _cs; \ - goto _fixed_trail_again + trail = trail_len; \ + cs = _cs; \ + goto _fixed_trail_again #define again_fixed_trail_if_zero(_cs, trail_len, ifzero) \ - trail = trail_len; \ - if(trail == 0) { goto ifzero; } \ - cs = _cs; \ - goto _fixed_trail_again + trail = trail_len; \ + if(trail == 0) { goto ifzero; } \ + cs = _cs; \ + goto _fixed_trail_again #define start_container(func, count_, ct_) \ - if(top >= MSGPACK_EMBED_STACK_SIZE) { goto _failed; } /* FIXME */ \ - if(construct_cb(func)(user, count_, &stack[top].obj) < 0) { goto _failed; } \ - if((count_) == 0) { obj = stack[top].obj; \ - if (construct_cb(func##_end)(user, &obj) < 0) { goto _failed; } \ - goto _push; } \ - stack[top].ct = ct_; \ - stack[top].size = count_; \ - stack[top].count = 0; \ - ++top; \ - /*printf("container %d count %d stack %d\n",stack[top].obj,count_,top);*/ \ - /*printf("stack push %d\n", top);*/ \ - /* FIXME \ - if(top >= stack_size) { \ - if(stack_size == MSGPACK_EMBED_STACK_SIZE) { \ - size_t csize = sizeof(msgpack_unpack_struct(_stack)) * MSGPACK_EMBED_STACK_SIZE; \ - size_t nsize = csize * 2; \ - msgpack_unpack_struct(_stack)* tmp = (msgpack_unpack_struct(_stack)*)malloc(nsize); \ - if(tmp == NULL) { goto _failed; } \ - memcpy(tmp, ctx->stack, csize); \ - ctx->stack = stack = tmp; \ - ctx->stack_size = stack_size = MSGPACK_EMBED_STACK_SIZE * 2; \ - } else { \ - size_t nsize = sizeof(msgpack_unpack_struct(_stack)) * ctx->stack_size * 2; \ - msgpack_unpack_struct(_stack)* tmp = (msgpack_unpack_struct(_stack)*)realloc(ctx->stack, nsize); \ - if(tmp == NULL) { goto _failed; } \ - ctx->stack = stack = tmp; \ - ctx->stack_size = stack_size = stack_size * 2; \ - } \ - } \ - */ \ - goto _header_again - -#define NEXT_CS(p) \ - ((unsigned int)*p & 0x1f) + if(top >= MSGPACK_EMBED_STACK_SIZE) { goto _failed; } /* FIXME */ \ + if(construct_cb(func)(user, count_, &stack[top].obj) < 0) { goto _failed; } \ + if((count_) == 0) { obj = stack[top].obj; \ + if (construct_cb(func##_end)(user, &obj) < 0) { goto _failed; } \ + goto _push; } \ + stack[top].ct = ct_; \ + stack[top].size = count_; \ + stack[top].count = 0; \ + ++top; \ + /*printf("container %d count %d stack %d\n",stack[top].obj,count_,top);*/ \ + /*printf("stack push %d\n", top);*/ \ + /* FIXME \ + if(top >= stack_size) { \ + if(stack_size == MSGPACK_EMBED_STACK_SIZE) { \ + size_t csize = sizeof(unpack_stack) * MSGPACK_EMBED_STACK_SIZE; \ + size_t nsize = csize * 2; \ + unpack_stack* tmp = (unpack_stack*)malloc(nsize); \ + if(tmp == NULL) { goto _failed; } \ + memcpy(tmp, ctx->stack, csize); \ + ctx->stack = stack = tmp; \ + ctx->stack_size = stack_size = MSGPACK_EMBED_STACK_SIZE * 2; \ + } else { \ + size_t nsize = sizeof(unpack_stack) * ctx->stack_size * 2; \ + unpack_stack* tmp = (unpack_stack*)realloc(ctx->stack, nsize); \ + if(tmp == NULL) { goto _failed; } \ + ctx->stack = stack = tmp; \ + ctx->stack_size = stack_size = stack_size * 2; \ + } \ + } \ + */ \ + goto _header_again + +#define NEXT_CS(p) ((unsigned int)*p & 0x1f) #ifdef USE_CASE_RANGE #define SWITCH_RANGE_BEGIN switch(*p) { @@ -190,221 +165,235 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c #define SWITCH_RANGE_END } } #endif - if(p == pe) { goto _out; } - do { - switch(cs) { - case CS_HEADER: - SWITCH_RANGE_BEGIN - SWITCH_RANGE(0x00, 0x7f) // Positive Fixnum - push_fixed_value(_uint8, *(uint8_t*)p); - SWITCH_RANGE(0xe0, 0xff) // Negative Fixnum - push_fixed_value(_int8, *(int8_t*)p); - SWITCH_RANGE(0xc0, 0xdf) // Variable - switch(*p) { - case 0xc0: // nil - push_simple_value(_nil); - //case 0xc1: // string - // again_terminal_trail(NEXT_CS(p), p+1); - case 0xc2: // false - push_simple_value(_false); - case 0xc3: // true - push_simple_value(_true); - //case 0xc4: - //case 0xc5: - //case 0xc6: - //case 0xc7: - //case 0xc8: - //case 0xc9: - case 0xca: // float - case 0xcb: // double - case 0xcc: // unsigned int 8 - case 0xcd: // unsigned int 16 - case 0xce: // unsigned int 32 - case 0xcf: // unsigned int 64 - case 0xd0: // signed int 8 - case 0xd1: // signed int 16 - case 0xd2: // signed int 32 - case 0xd3: // signed int 64 - again_fixed_trail(NEXT_CS(p), 1 << (((unsigned int)*p) & 0x03)); - //case 0xd4: - //case 0xd5: - //case 0xd6: // big integer 16 - //case 0xd7: // big integer 32 - //case 0xd8: // big float 16 - //case 0xd9: // big float 32 - case 0xda: // raw 16 - case 0xdb: // raw 32 - case 0xdc: // array 16 - case 0xdd: // array 32 - case 0xde: // map 16 - case 0xdf: // map 32 - again_fixed_trail(NEXT_CS(p), 2 << (((unsigned int)*p) & 0x01)); - default: - goto _failed; - } - SWITCH_RANGE(0xa0, 0xbf) // FixRaw - again_fixed_trail_if_zero(ACS_RAW_VALUE, ((unsigned int)*p & 0x1f), _raw_zero); - SWITCH_RANGE(0x90, 0x9f) // FixArray - start_container(_array, ((unsigned int)*p) & 0x0f, CT_ARRAY_ITEM); - SWITCH_RANGE(0x80, 0x8f) // FixMap - start_container(_map, ((unsigned int)*p) & 0x0f, CT_MAP_KEY); - - SWITCH_RANGE_DEFAULT - goto _failed; - SWITCH_RANGE_END - // end CS_HEADER - - - _fixed_trail_again: - ++p; - - default: - if((size_t)(pe - p) < trail) { goto _out; } - n = p; p += trail - 1; - switch(cs) { - //case CS_ - //case CS_ - case CS_FLOAT: { - union { uint32_t i; float f; } mem; - mem.i = _msgpack_load32(uint32_t,n); - push_fixed_value(_float, mem.f); } - case CS_DOUBLE: { - union { uint64_t i; double f; } mem; - mem.i = _msgpack_load64(uint64_t,n); + if(p == pe) { goto _out; } + do { + switch(cs) { + case CS_HEADER: + SWITCH_RANGE_BEGIN + SWITCH_RANGE(0x00, 0x7f) // Positive Fixnum + push_fixed_value(_uint8, *(uint8_t*)p); + SWITCH_RANGE(0xe0, 0xff) // Negative Fixnum + push_fixed_value(_int8, *(int8_t*)p); + SWITCH_RANGE(0xc0, 0xdf) // Variable + switch(*p) { + case 0xc0: // nil + push_simple_value(_nil); + //case 0xc1: // never used + case 0xc2: // false + push_simple_value(_false); + case 0xc3: // true + push_simple_value(_true); + case 0xc4: // bin 8 + again_fixed_trail(NEXT_CS(p), 1); + case 0xc5: // bin 16 + again_fixed_trail(NEXT_CS(p), 2); + case 0xc6: // bin 32 + again_fixed_trail(NEXT_CS(p), 4); + case 0xc7: // ext 8 + again_fixed_trail(NEXT_CS(p), 1); + case 0xc8: // ext 16 + again_fixed_trail(NEXT_CS(p), 2); + case 0xc9: // ext 32 + again_fixed_trail(NEXT_CS(p), 4); + case 0xca: // float + case 0xcb: // double + case 0xcc: // unsigned int 8 + case 0xcd: // unsigned int 16 + case 0xce: // unsigned int 32 + case 0xcf: // unsigned int 64 + case 0xd0: // signed int 8 + case 0xd1: // signed int 16 + case 0xd2: // signed int 32 + case 0xd3: // signed int 64 + again_fixed_trail(NEXT_CS(p), 1 << (((unsigned int)*p) & 0x03)); + case 0xd4: // fixext 1 + case 0xd5: // fixext 2 + case 0xd6: // fixext 4 + case 0xd7: // fixext 8 + again_fixed_trail_if_zero(ACS_EXT_VALUE, + (1 << (((unsigned int)*p) & 0x03))+1, + _ext_zero); + case 0xd8: // fixext 16 + again_fixed_trail_if_zero(ACS_EXT_VALUE, 16+1, _ext_zero); + case 0xd9: // str 8 + again_fixed_trail(NEXT_CS(p), 1); + case 0xda: // raw 16 + case 0xdb: // raw 32 + case 0xdc: // array 16 + case 0xdd: // array 32 + case 0xde: // map 16 + case 0xdf: // map 32 + again_fixed_trail(NEXT_CS(p), 2 << (((unsigned int)*p) & 0x01)); + default: + goto _failed; + } + SWITCH_RANGE(0xa0, 0xbf) // FixRaw + again_fixed_trail_if_zero(ACS_RAW_VALUE, ((unsigned int)*p & 0x1f), _raw_zero); + SWITCH_RANGE(0x90, 0x9f) // FixArray + start_container(_array, ((unsigned int)*p) & 0x0f, CT_ARRAY_ITEM); + SWITCH_RANGE(0x80, 0x8f) // FixMap + start_container(_map, ((unsigned int)*p) & 0x0f, CT_MAP_KEY); + + SWITCH_RANGE_DEFAULT + goto _failed; + SWITCH_RANGE_END + // end CS_HEADER + + + _fixed_trail_again: + ++p; + + default: + if((size_t)(pe - p) < trail) { goto _out; } + n = p; p += trail - 1; + switch(cs) { + case CS_EXT_8: + again_fixed_trail_if_zero(ACS_EXT_VALUE, *(uint8_t*)n+1, _ext_zero); + case CS_EXT_16: + again_fixed_trail_if_zero(ACS_EXT_VALUE, + _msgpack_load16(uint16_t,n)+1, + _ext_zero); + case CS_EXT_32: + again_fixed_trail_if_zero(ACS_EXT_VALUE, + _msgpack_load32(uint32_t,n)+1, + _ext_zero); + case CS_FLOAT: { + union { uint32_t i; float f; } mem; + mem.i = _msgpack_load32(uint32_t,n); + push_fixed_value(_float, mem.f); } + case CS_DOUBLE: { + union { uint64_t i; double f; } mem; + mem.i = _msgpack_load64(uint64_t,n); #if defined(__arm__) && !(__ARM_EABI__) // arm-oabi // https://github.com/msgpack/msgpack-perl/pull/1 mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL); #endif - push_fixed_value(_double, mem.f); } - case CS_UINT_8: - push_fixed_value(_uint8, *(uint8_t*)n); - case CS_UINT_16: - push_fixed_value(_uint16, _msgpack_load16(uint16_t,n)); - case CS_UINT_32: - push_fixed_value(_uint32, _msgpack_load32(uint32_t,n)); - case CS_UINT_64: - push_fixed_value(_uint64, _msgpack_load64(uint64_t,n)); - - case CS_INT_8: - push_fixed_value(_int8, *(int8_t*)n); - case CS_INT_16: - push_fixed_value(_int16, _msgpack_load16(int16_t,n)); - case CS_INT_32: - push_fixed_value(_int32, _msgpack_load32(int32_t,n)); - case CS_INT_64: - push_fixed_value(_int64, _msgpack_load64(int64_t,n)); - - //case CS_ - //case CS_ - //case CS_BIG_INT_16: - // again_fixed_trail_if_zero(ACS_BIG_INT_VALUE, _msgpack_load16(uint16_t,n), _big_int_zero); - //case CS_BIG_INT_32: - // again_fixed_trail_if_zero(ACS_BIG_INT_VALUE, _msgpack_load32(uint32_t,n), _big_int_zero); - //case ACS_BIG_INT_VALUE: - //_big_int_zero: - // // FIXME - // push_variable_value(_big_int, data, n, trail); - - //case CS_BIG_FLOAT_16: - // again_fixed_trail_if_zero(ACS_BIG_FLOAT_VALUE, _msgpack_load16(uint16_t,n), _big_float_zero); - //case CS_BIG_FLOAT_32: - // again_fixed_trail_if_zero(ACS_BIG_FLOAT_VALUE, _msgpack_load32(uint32_t,n), _big_float_zero); - //case ACS_BIG_FLOAT_VALUE: - //_big_float_zero: - // // FIXME - // push_variable_value(_big_float, data, n, trail); - - case CS_RAW_16: - again_fixed_trail_if_zero(ACS_RAW_VALUE, _msgpack_load16(uint16_t,n), _raw_zero); - case CS_RAW_32: - again_fixed_trail_if_zero(ACS_RAW_VALUE, _msgpack_load32(uint32_t,n), _raw_zero); - case ACS_RAW_VALUE: - _raw_zero: - push_variable_value(_raw, data, n, trail); - - case CS_ARRAY_16: - start_container(_array, _msgpack_load16(uint16_t,n), CT_ARRAY_ITEM); - case CS_ARRAY_32: - /* FIXME security guard */ - start_container(_array, _msgpack_load32(uint32_t,n), CT_ARRAY_ITEM); - - case CS_MAP_16: - start_container(_map, _msgpack_load16(uint16_t,n), CT_MAP_KEY); - case CS_MAP_32: - /* FIXME security guard */ - start_container(_map, _msgpack_load32(uint32_t,n), CT_MAP_KEY); - - default: - goto _failed; - } - } + push_fixed_value(_double, mem.f); } + case CS_UINT_8: + push_fixed_value(_uint8, *(uint8_t*)n); + case CS_UINT_16: + push_fixed_value(_uint16, _msgpack_load16(uint16_t,n)); + case CS_UINT_32: + push_fixed_value(_uint32, _msgpack_load32(uint32_t,n)); + case CS_UINT_64: + push_fixed_value(_uint64, _msgpack_load64(uint64_t,n)); + + case CS_INT_8: + push_fixed_value(_int8, *(int8_t*)n); + case CS_INT_16: + push_fixed_value(_int16, _msgpack_load16(int16_t,n)); + case CS_INT_32: + push_fixed_value(_int32, _msgpack_load32(int32_t,n)); + case CS_INT_64: + push_fixed_value(_int64, _msgpack_load64(int64_t,n)); + + case CS_BIN_8: + again_fixed_trail_if_zero(ACS_BIN_VALUE, *(uint8_t*)n, _bin_zero); + case CS_BIN_16: + again_fixed_trail_if_zero(ACS_BIN_VALUE, _msgpack_load16(uint16_t,n), _bin_zero); + case CS_BIN_32: + again_fixed_trail_if_zero(ACS_BIN_VALUE, _msgpack_load32(uint32_t,n), _bin_zero); + case ACS_BIN_VALUE: + _bin_zero: + push_variable_value(_bin, data, n, trail); + + case CS_RAW_8: + again_fixed_trail_if_zero(ACS_RAW_VALUE, *(uint8_t*)n, _raw_zero); + case CS_RAW_16: + again_fixed_trail_if_zero(ACS_RAW_VALUE, _msgpack_load16(uint16_t,n), _raw_zero); + case CS_RAW_32: + again_fixed_trail_if_zero(ACS_RAW_VALUE, _msgpack_load32(uint32_t,n), _raw_zero); + case ACS_RAW_VALUE: + _raw_zero: + push_variable_value(_raw, data, n, trail); + + case ACS_EXT_VALUE: + _ext_zero: + push_variable_value(_ext, data, n, trail); + + case CS_ARRAY_16: + start_container(_array, _msgpack_load16(uint16_t,n), CT_ARRAY_ITEM); + case CS_ARRAY_32: + /* FIXME security guard */ + start_container(_array, _msgpack_load32(uint32_t,n), CT_ARRAY_ITEM); + + case CS_MAP_16: + start_container(_map, _msgpack_load16(uint16_t,n), CT_MAP_KEY); + case CS_MAP_32: + /* FIXME security guard */ + start_container(_map, _msgpack_load32(uint32_t,n), CT_MAP_KEY); + + default: + goto _failed; + } + } _push: - if(top == 0) { goto _finish; } - c = &stack[top-1]; - switch(c->ct) { - case CT_ARRAY_ITEM: - if(construct_cb(_array_item)(user, c->count, &c->obj, obj) < 0) { goto _failed; } - if(++c->count == c->size) { - obj = c->obj; - if (construct_cb(_array_end)(user, &obj) < 0) { goto _failed; } - --top; - /*printf("stack pop %d\n", top);*/ - goto _push; - } - goto _header_again; - case CT_MAP_KEY: - c->map_key = obj; - c->ct = CT_MAP_VALUE; - goto _header_again; - case CT_MAP_VALUE: - if(construct_cb(_map_item)(user, c->count, &c->obj, c->map_key, obj) < 0) { goto _failed; } - if(++c->count == c->size) { - obj = c->obj; - if (construct_cb(_map_end)(user, &obj) < 0) { goto _failed; } - --top; - /*printf("stack pop %d\n", top);*/ - goto _push; - } - c->ct = CT_MAP_KEY; - goto _header_again; - - default: - goto _failed; - } + if(top == 0) { goto _finish; } + c = &stack[top-1]; + switch(c->ct) { + case CT_ARRAY_ITEM: + if(construct_cb(_array_item)(user, c->count, &c->obj, obj) < 0) { goto _failed; } + if(++c->count == c->size) { + obj = c->obj; + if (construct_cb(_array_end)(user, &obj) < 0) { goto _failed; } + --top; + /*printf("stack pop %d\n", top);*/ + goto _push; + } + goto _header_again; + case CT_MAP_KEY: + c->map_key = obj; + c->ct = CT_MAP_VALUE; + goto _header_again; + case CT_MAP_VALUE: + if(construct_cb(_map_item)(user, c->count, &c->obj, c->map_key, obj) < 0) { goto _failed; } + if(++c->count == c->size) { + obj = c->obj; + if (construct_cb(_map_end)(user, &obj) < 0) { goto _failed; } + --top; + /*printf("stack pop %d\n", top);*/ + goto _push; + } + c->ct = CT_MAP_KEY; + goto _header_again; + + default: + goto _failed; + } _header_again: - cs = CS_HEADER; - ++p; - } while(p != pe); - goto _out; + cs = CS_HEADER; + ++p; + } while(p != pe); + goto _out; _finish: - if (!construct) - msgpack_unpack_callback(_nil)(user, &obj); - stack[0].obj = obj; - ++p; - ret = 1; - /*printf("-- finish --\n"); */ - goto _end; + if (!construct) + unpack_callback_nil(user, &obj); + stack[0].obj = obj; + ++p; + ret = 1; + /*printf("-- finish --\n"); */ + goto _end; _failed: - /*printf("** FAILED **\n"); */ - ret = -1; - goto _end; + /*printf("** FAILED **\n"); */ + ret = -1; + goto _end; _out: - ret = 0; - goto _end; + ret = 0; + goto _end; _end: - ctx->cs = cs; - ctx->trail = trail; - ctx->top = top; - *off = p - (const unsigned char*)data; + ctx->cs = cs; + ctx->trail = trail; + ctx->top = top; + *off = p - (const unsigned char*)data; - return ret; + return ret; #undef construct_cb } @@ -420,55 +409,55 @@ msgpack_unpack_func(int, _execute)(msgpack_unpack_struct(_context)* ctx, const c #undef start_container template -msgpack_unpack_func(int, _container_header)(msgpack_unpack_struct(_context)* ctx, const char* data, size_t len, size_t* off) +static inline int unpack_container_header(unpack_context* ctx, const char* data, size_t len, size_t* off) { - assert(len >= *off); - uint32_t size; - const unsigned char *const p = (unsigned char*)data + *off; + assert(len >= *off); + uint32_t size; + const unsigned char *const p = (unsigned char*)data + *off; #define inc_offset(inc) \ - if (len - *off < inc) \ - return 0; \ - *off += inc; - - switch (*p) { - case var_offset: - inc_offset(3); - size = _msgpack_load16(uint16_t, p + 1); - break; - case var_offset + 1: - inc_offset(5); - size = _msgpack_load32(uint32_t, p + 1); - break; + if (len - *off < inc) \ + return 0; \ + *off += inc; + + switch (*p) { + case var_offset: + inc_offset(3); + size = _msgpack_load16(uint16_t, p + 1); + break; + case var_offset + 1: + inc_offset(5); + size = _msgpack_load32(uint32_t, p + 1); + break; #ifdef USE_CASE_RANGE - case fixed_offset + 0x0 ... fixed_offset + 0xf: + case fixed_offset + 0x0 ... fixed_offset + 0xf: #else - case fixed_offset + 0x0: - case fixed_offset + 0x1: - case fixed_offset + 0x2: - case fixed_offset + 0x3: - case fixed_offset + 0x4: - case fixed_offset + 0x5: - case fixed_offset + 0x6: - case fixed_offset + 0x7: - case fixed_offset + 0x8: - case fixed_offset + 0x9: - case fixed_offset + 0xa: - case fixed_offset + 0xb: - case fixed_offset + 0xc: - case fixed_offset + 0xd: - case fixed_offset + 0xe: - case fixed_offset + 0xf: + case fixed_offset + 0x0: + case fixed_offset + 0x1: + case fixed_offset + 0x2: + case fixed_offset + 0x3: + case fixed_offset + 0x4: + case fixed_offset + 0x5: + case fixed_offset + 0x6: + case fixed_offset + 0x7: + case fixed_offset + 0x8: + case fixed_offset + 0x9: + case fixed_offset + 0xa: + case fixed_offset + 0xb: + case fixed_offset + 0xc: + case fixed_offset + 0xd: + case fixed_offset + 0xe: + case fixed_offset + 0xf: #endif - ++*off; - size = ((unsigned int)*p) & 0x0f; - break; - default: - PyErr_SetString(PyExc_ValueError, "Unexpected type header on stream"); - return -1; + ++*off; + size = ((unsigned int)*p) & 0x0f; + break; + default: + PyErr_SetString(PyExc_ValueError, "Unexpected type header on stream"); + return -1; } - msgpack_unpack_callback(_uint32)(&ctx->user, size, &ctx->stack[0].obj); - return 1; + unpack_callback_uint32(&ctx->user, size, &ctx->stack[0].obj); + return 1; } #undef SWITCH_RANGE_BEGIN @@ -476,17 +465,11 @@ msgpack_unpack_func(int, _container_header)(msgpack_unpack_struct(_context)* ctx #undef SWITCH_RANGE_DEFAULT #undef SWITCH_RANGE_END -static const execute_fn template_construct = &template_execute; -static const execute_fn template_skip = &template_execute; -static const execute_fn read_array_header = &template_container_header<0x90, 0xdc>; -static const execute_fn read_map_header = &template_container_header<0x80, 0xde>; - -#undef msgpack_unpack_func -#undef msgpack_unpack_callback -#undef msgpack_unpack_struct -#undef msgpack_unpack_object -#undef msgpack_unpack_user +static const execute_fn unpack_construct = &unpack_execute; +static const execute_fn unpack_skip = &unpack_execute; +static const execute_fn read_array_header = &unpack_container_header<0x90, 0xdc>; +static const execute_fn read_map_header = &unpack_container_header<0x80, 0xde>; #undef NEXT_CS -/* vim: set ts=4 sw=4 noexpandtab */ +/* vim: set ts=4 sw=4 sts=4 expandtab */ diff --git a/pandas/src/parse_helper.h b/pandas/src/parse_helper.h index 2769f67fcf521..2cb1a7f017c62 100644 --- a/pandas/src/parse_helper.h +++ b/pandas/src/parse_helper.h @@ -6,7 +6,7 @@ static double xstrtod(const char *p, char **q, char decimal, char sci, int to_double(char *item, double *p_value, char sci, char decimal, int *maybe_int) { - char *p_end; + char *p_end = NULL; *p_value = xstrtod(item, &p_end, decimal, sci, 1, maybe_int); diff --git a/pandas/src/parser/tokenizer.c b/pandas/src/parser/tokenizer.c index 3be17f17d6afa..9d81bc9c37b8d 100644 --- a/pandas/src/parser/tokenizer.c +++ b/pandas/src/parser/tokenizer.c @@ -1413,9 +1413,9 @@ int tokenize_whitespace(parser_t *self, size_t line_limit) self->state = EAT_CRNL; break; } else if (IS_WHITESPACE(c)) { - /*if (self->skip_empty_lines) + if (self->skip_empty_lines) self->state = WHITESPACE_LINE; - else*/ + else self->state = EAT_WHITESPACE; break; } else if (c == self->commentchar) { @@ -1643,34 +1643,44 @@ int tokenize_whitespace(parser_t *self, size_t line_limit) static int parser_handle_eof(parser_t *self) { TRACE(("handling eof, datalen: %d, pstate: %d\n", self->datalen, self->state)) - if (self->datalen == 0 && (self->state != START_RECORD)) { - // test cases needed here - // TODO: empty field at end of line - TRACE(("handling eof\n")); - if (self->state == IN_FIELD || self->state == START_FIELD) { - if (end_field(self) < 0) - return -1; - } else if (self->state == QUOTE_IN_QUOTED_FIELD) { - if (end_field(self) < 0) - return -1; - } else if (self->state == IN_QUOTED_FIELD) { - self->error_msg = (char*) malloc(100); - sprintf(self->error_msg, "EOF inside string starting at line %d", - self->file_lines); - return -1; - } + if (self->datalen != 0) + return -1; - if (end_line(self) < 0) + switch (self->state) { + case START_RECORD: + case WHITESPACE_LINE: + case EAT_CRNL_NOP: + case EAT_LINE_COMMENT: + return 0; + + case ESCAPE_IN_QUOTED_FIELD: + case IN_QUOTED_FIELD: + self->error_msg = (char*)malloc(100); + sprintf(self->error_msg, "EOF inside string starting at line %d", + self->file_lines); + return -1; + + case ESCAPED_CHAR: + self->error_msg = (char*)malloc(100); + sprintf(self->error_msg, "EOF following escape character"); + return -1; + + case IN_FIELD: + case START_FIELD: + case QUOTE_IN_QUOTED_FIELD: + if (end_field(self) < 0) return -1; + break; - return 0; - } - else if (self->datalen == 0 && (self->state == START_RECORD)) { - return 0; + default: + break; } - return -1; + if (end_line(self) < 0) + return -1; + else + return 0; } int parser_consume_rows(parser_t *self, size_t nrows) { diff --git a/pandas/src/parser/tokenizer.h b/pandas/src/parser/tokenizer.h index d3777e858b6ca..eef94e0616769 100644 --- a/pandas/src/parser/tokenizer.h +++ b/pandas/src/parser/tokenizer.h @@ -27,11 +27,7 @@ See LICENSE for the license #define ERROR_INVALID_CHARS 3 #define ERROR_MINUS_SIGN 4 -#if defined(_MSC_VER) -#include "../headers/ms_stdint.h" -#else -#include -#endif +#include "../headers/stdint.h" #include "khash.h" diff --git a/pandas/src/period.pyx b/pandas/src/period.pyx index b4a4930e09d68..619d1a87a71e0 100644 --- a/pandas/src/period.pyx +++ b/pandas/src/period.pyx @@ -969,6 +969,14 @@ cdef class Period(object): value = ("%s" % formatted) return value + def __setstate__(self, state): + self.freq=state[1] + self.ordinal=state[2] + + def __reduce__(self): + object_state = None, self.freq, self.ordinal + return (Period, object_state) + def strftime(self, fmt): """ Returns the string representation of the :class:`Period`, depending diff --git a/pandas/src/period_helper.h b/pandas/src/period_helper.h index 19b186afb9fc8..0351321926fa2 100644 --- a/pandas/src/period_helper.h +++ b/pandas/src/period_helper.h @@ -166,5 +166,5 @@ double getAbsTime(int freq, npy_int64 dailyDate, npy_int64 originalDate); char *c_strftime(struct date_info *dinfo, char *fmt); int get_yq(npy_int64 ordinal, int freq, int *quarter, int *year); -void initialize_daytime_conversion_factor_matrix(); +void initialize_daytime_conversion_factor_matrix(void); #endif diff --git a/pandas/src/reduce.pyx b/pandas/src/reduce.pyx index add9a03642bed..09f8e0ab42924 100644 --- a/pandas/src/reduce.pyx +++ b/pandas/src/reduce.pyx @@ -6,6 +6,18 @@ from distutils.version import LooseVersion is_numpy_prior_1_6_2 = LooseVersion(np.__version__) < '1.6.2' +cdef _get_result_array(object obj, + Py_ssize_t size, + Py_ssize_t cnt): + + if isinstance(obj, np.ndarray) \ + or isinstance(obj, list) and len(obj) == cnt \ + or getattr(obj, 'shape', None) == (cnt,): + raise ValueError('function does not reduce') + + return np.empty(size, dtype='O') + + cdef class Reducer: ''' Performs generic reduction operation on a C or Fortran-contiguous ndarray @@ -124,7 +136,9 @@ cdef class Reducer: if hasattr(res,'values'): res = res.values if i == 0: - result = self._get_result_array(res) + result = _get_result_array(res, + self.nresults, + len(self.dummy)) it = PyArray_IterNew(result) PyArray_SETITEM(result, PyArray_ITER_DATA(it), res) @@ -143,17 +157,6 @@ cdef class Reducer: return result - def _get_result_array(self, object res): - try: - assert(not isinstance(res, np.ndarray)) - assert(not (isinstance(res, list) and len(res) == len(self.dummy))) - - result = np.empty(self.nresults, dtype='O') - result[0] = res - except Exception: - raise ValueError('function does not reduce') - return result - cdef class SeriesBinGrouper: ''' @@ -257,8 +260,10 @@ cdef class SeriesBinGrouper: res = self.f(cached_typ) res = _extract_result(res) if not initialized: - result = self._get_result_array(res) initialized = 1 + result = _get_result_array(res, + self.ngroups, + len(self.dummy_arr)) util.assign_value_1d(result, i, res) @@ -277,16 +282,6 @@ cdef class SeriesBinGrouper: return result, counts - def _get_result_array(self, object res): - try: - assert(not isinstance(res, np.ndarray)) - assert(not (isinstance(res, list) and len(res) == len(self.dummy_arr))) - - result = np.empty(self.ngroups, dtype='O') - except Exception: - raise ValueError('function does not reduce') - return result - cdef class SeriesGrouper: ''' @@ -388,8 +383,10 @@ cdef class SeriesGrouper: res = self.f(cached_typ) res = _extract_result(res) if not initialized: - result = self._get_result_array(res) initialized = 1 + result = _get_result_array(res, + self.ngroups, + len(self.dummy_arr)) util.assign_value_1d(result, lab, res) counts[lab] = group_size @@ -410,15 +407,6 @@ cdef class SeriesGrouper: return result, counts - def _get_result_array(self, object res): - try: - assert(not isinstance(res, np.ndarray)) - assert(not (isinstance(res, list) and len(res) == len(self.dummy_arr))) - - result = np.empty(self.ngroups, dtype='O') - except Exception: - raise ValueError('function does not reduce') - return result cdef inline _extract_result(object res): ''' extract the result object, it might be a 0-dim ndarray diff --git a/pandas/src/testing.pyx b/pandas/src/testing.pyx index 4977a80acc936..1abc758559e70 100644 --- a/pandas/src/testing.pyx +++ b/pandas/src/testing.pyx @@ -55,11 +55,39 @@ cpdef assert_dict_equal(a, b, bint compare_keys=True): return True -cpdef assert_almost_equal(a, b, bint check_less_precise=False): +cpdef assert_almost_equal(a, b, bint check_less_precise=False, + obj=None, lobj=None, robj=None): + """Check that left and right objects are almost equal. + + Parameters + ---------- + a : object + b : object + check_less_precise : bool, default False + Specify comparison precision. + 5 digits (False) or 3 digits (True) after decimal points are compared. + obj : str, default None + Specify object name being compared, internally used to show appropriate + assertion message + lobj : str, default None + Specify left object name being compared, internally used to show + appropriate assertion message + robj : str, default None + Specify right object name being compared, internally used to show + appropriate assertion message + """ + cdef: int decimal + double diff = 0.0 Py_ssize_t i, na, nb double fa, fb + bint is_unequal = False + + if lobj is None: + lobj = a + if robj is None: + robj = b if isinstance(a, dict) or isinstance(b, dict): return assert_dict_equal(a, b) @@ -70,33 +98,62 @@ cpdef assert_almost_equal(a, b, bint check_less_precise=False): return True if isiterable(a): - assert isiterable(b), ( - "First object is iterable, second isn't: %r != %r" % (a, b) - ) + + if not isiterable(b): + from pandas.util.testing import raise_assert_detail + if obj is None: + obj = 'Iterable' + msg = "First object is iterable, second isn't" + raise_assert_detail(obj, msg, a, b) + assert has_length(a) and has_length(b), ( "Can't compare objects without length, one or both is invalid: " "(%r, %r)" % (a, b) ) - na, nb = len(a), len(b) - assert na == nb, ( - "Length of two iterators not the same: %r != %r" % (na, nb) - ) if isinstance(a, np.ndarray) and isinstance(b, np.ndarray): + if obj is None: + obj = 'numpy array' + na, nb = a.size, b.size + if a.shape != b.shape: + from pandas.util.testing import raise_assert_detail + raise_assert_detail(obj, '{0} shapes are different'.format(obj), + a.shape, b.shape) try: if np.array_equal(a, b): return True except: pass + else: + if obj is None: + obj = 'Iterable' + na, nb = len(a), len(b) + + if na != nb: + from pandas.util.testing import raise_assert_detail + raise_assert_detail(obj, '{0} length are different'.format(obj), + na, nb) + + for i in xrange(len(a)): + try: + assert_almost_equal(a[i], b[i], check_less_precise) + except AssertionError: + is_unequal = True + diff += 1 - for i in xrange(na): - assert_almost_equal(a[i], b[i], check_less_precise) + if is_unequal: + from pandas.util.testing import raise_assert_detail + msg = '{0} values are different ({1} %)'.format(obj, np.round(diff * 100.0 / na, 5)) + raise_assert_detail(obj, msg, lobj, robj) return True + elif isiterable(b): - assert False, ( - "Second object is iterable, first isn't: %r != %r" % (a, b) - ) + from pandas.util.testing import raise_assert_detail + if obj is None: + obj = 'Iterable' + msg = "Second object is iterable, first isn't" + raise_assert_detail(obj, msg, a, b) if isnull(a): assert isnull(b), ( diff --git a/pandas/stats/moments.py b/pandas/stats/moments.py index 41a768783b1cb..586d507b27493 100644 --- a/pandas/stats/moments.py +++ b/pandas/stats/moments.py @@ -426,7 +426,7 @@ def _process_data_structure(arg, kill_inf=True): values = arg.values elif isinstance(arg, Series): values = arg.values - return_hook = lambda v: Series(v, arg.index) + return_hook = lambda v: Series(v, arg.index, name=arg.name) else: return_hook = lambda v: v values = arg diff --git a/pandas/stats/ols.py b/pandas/stats/ols.py index 9d22068c1612f..d1d74442d8961 100644 --- a/pandas/stats/ols.py +++ b/pandas/stats/ols.py @@ -614,7 +614,8 @@ class MovingOLS(OLS): size of window (for rolling/expanding OLS) min_periods : int Threshold of non-null data points to require. - If None, defaults to size of window. + If None, defaults to size of window for window_type='rolling' and 1 + otherwise intercept : bool True if you want an intercept. nw_lags : None or int @@ -818,7 +819,7 @@ def _calc_betas(self, x, y): betas[i] = math.solve(xx, xy) - mask = -np.isnan(betas).any(axis=1) + mask = ~np.isnan(betas).any(axis=1) have_betas = np.arange(N)[mask] return betas, have_betas, mask diff --git a/pandas/stats/tests/test_moments.py b/pandas/stats/tests/test_moments.py index 445530bc5b00c..bb6cb5a444dd9 100644 --- a/pandas/stats/tests/test_moments.py +++ b/pandas/stats/tests/test_moments.py @@ -539,7 +539,7 @@ def _check_ndarray(self, func, static_comp, window=50, result = func(arr, 20, center=True) expected = func(np.concatenate((arr, np.array([np.NaN] * 9))), 20)[9:] - self.assert_numpy_array_equivalent(result, expected) + self.assert_numpy_array_equal(result, expected) if test_stable: result = func(self.arr + 1e9, window) @@ -574,7 +574,7 @@ def _check_structures(self, func, static_comp, fill_value=None): series_result = func(self.series, 50) - tm.assert_isinstance(series_result, Series) + tm.assertIsInstance(series_result, Series) frame_result = func(self.frame, 50) self.assertEqual(type(frame_result), DataFrame) @@ -725,6 +725,14 @@ def test_ewma_halflife_arg(self): self.assertRaises(Exception, mom.ewma, self.arr, com=9.5, span=20, halflife=50) self.assertRaises(Exception, mom.ewma, self.arr) + def test_moment_preserve_series_name(self): + # GH 10565 + s = Series(np.arange(100), name='foo') + s2 = mom.rolling_mean(s, 30) + s3 = mom.rolling_sum(s, 20) + self.assertEqual(s2.name, 'foo') + self.assertEqual(s3.name, 'foo') + def test_ew_empty_arrays(self): arr = np.array([], dtype=np.float64) @@ -782,7 +790,7 @@ def _check_ew_ndarray(self, func, preserve_nan=False): def _check_ew_structures(self, func): series_result = func(self.series, com=10) - tm.assert_isinstance(series_result, Series) + tm.assertIsInstance(series_result, Series) frame_result = func(self.frame, com=10) self.assertEqual(type(frame_result), DataFrame) @@ -1676,7 +1684,7 @@ def test_pairwise_stats_column_names_order(self): assert_index_equal(result.columns, df.columns) for i, result in enumerate(results): if i > 0: - self.assert_numpy_array_equivalent(result, results[0]) + self.assert_numpy_array_equal(result, results[0]) # DataFrame with itself, pairwise=True for f in [lambda x: mom.expanding_cov(x, pairwise=True), @@ -1693,7 +1701,7 @@ def test_pairwise_stats_column_names_order(self): assert_index_equal(result.minor_axis, df.columns) for i, result in enumerate(results): if i > 0: - self.assert_numpy_array_equivalent(result, results[0]) + self.assert_numpy_array_equal(result, results[0]) # DataFrame with itself, pairwise=False for f in [lambda x: mom.expanding_cov(x, pairwise=False), @@ -1709,7 +1717,7 @@ def test_pairwise_stats_column_names_order(self): assert_index_equal(result.columns, df.columns) for i, result in enumerate(results): if i > 0: - self.assert_numpy_array_equivalent(result, results[0]) + self.assert_numpy_array_equal(result, results[0]) # DataFrame with another DataFrame, pairwise=True for f in [lambda x, y: mom.expanding_cov(x, y, pairwise=True), @@ -1726,7 +1734,7 @@ def test_pairwise_stats_column_names_order(self): assert_index_equal(result.minor_axis, df2.columns) for i, result in enumerate(results): if i > 0: - self.assert_numpy_array_equivalent(result, results[0]) + self.assert_numpy_array_equal(result, results[0]) # DataFrame with another DataFrame, pairwise=False for f in [lambda x, y: mom.expanding_cov(x, y, pairwise=False), @@ -1761,7 +1769,7 @@ def test_pairwise_stats_column_names_order(self): assert_index_equal(result.columns, df.columns) for i, result in enumerate(results): if i > 0: - self.assert_numpy_array_equivalent(result, results[0]) + self.assert_numpy_array_equal(result, results[0]) def test_rolling_skew_edge_cases(self): @@ -1844,7 +1852,7 @@ def _check_expanding_ndarray(self, func, static_comp, has_min_periods=True, def _check_expanding_structures(self, func): series_result = func(self.series) - tm.assert_isinstance(series_result, Series) + tm.assertIsInstance(series_result, Series) frame_result = func(self.frame) self.assertEqual(type(frame_result), DataFrame) diff --git a/pandas/stats/tests/test_ols.py b/pandas/stats/tests/test_ols.py index 5c8d47ec2a82a..60e976f09365b 100644 --- a/pandas/stats/tests/test_ols.py +++ b/pandas/stats/tests/test_ols.py @@ -41,7 +41,7 @@ def _check_repr(obj): def _compare_ols_results(model1, model2): - tm.assert_isinstance(model1, type(model2)) + tm.assertIsInstance(model1, type(model2)) if hasattr(model1, '_window_type'): _compare_moving_ols(model1, model2) @@ -370,7 +370,7 @@ def test_longpanel_series_combo(self): y = lp.pop('ItemA') model = ols(y=y, x=lp, entity_effects=True, window=20) self.assertTrue(notnull(model.beta.values).all()) - tm.assert_isinstance(model, PanelOLS) + tm.assertIsInstance(model, PanelOLS) model.summary def test_series_rhs(self): @@ -394,7 +394,7 @@ def test_various_attributes(self): for attr in series_attrs: value = getattr(model, attr) - tm.assert_isinstance(value, Series) + tm.assertIsInstance(value, Series) # works model._results diff --git a/pandas/tests/test_algos.py b/pandas/tests/test_algos.py index c80cea3ab7a7d..6164b1b4906de 100644 --- a/pandas/tests/test_algos.py +++ b/pandas/tests/test_algos.py @@ -2,14 +2,16 @@ from pandas.compat import range import numpy as np +from numpy.random import RandomState -from pandas.core.api import Series, Categorical +from pandas.core.api import Series, Categorical, CategoricalIndex import pandas as pd import pandas.core.algorithms as algos import pandas.util.testing as tm import pandas.hashtable as hashtable + class TestMatch(tm.TestCase): _multiprocess_can_split_ = True @@ -166,6 +168,38 @@ def _test_vector_resize(htable, uniques, dtype, nvals): _test_vector_resize(tbl(), vect(), dtype, 0) _test_vector_resize(tbl(), vect(), dtype, 10) +class TestIndexer(tm.TestCase): + _multiprocess_can_split_ = True + + def test_outer_join_indexer(self): + typemap = [('int32', algos.algos.outer_join_indexer_int32), + ('int64', algos.algos.outer_join_indexer_int64), + ('float32', algos.algos.outer_join_indexer_float32), + ('float64', algos.algos.outer_join_indexer_float64), + ('object', algos.algos.outer_join_indexer_object)] + + for dtype, indexer in typemap: + left = np.arange(3, dtype = dtype) + right = np.arange(2,5, dtype = dtype) + empty = np.array([], dtype = dtype) + + result, lindexer, rindexer = indexer(left, right) + tm.assertIsInstance(result, np.ndarray) + tm.assertIsInstance(lindexer, np.ndarray) + tm.assertIsInstance(rindexer, np.ndarray) + tm.assert_numpy_array_equal(result, np.arange(5, dtype = dtype)) + tm.assert_numpy_array_equal(lindexer, np.array([0, 1, 2, -1, -1])) + tm.assert_numpy_array_equal(rindexer, np.array([-1, -1, 0, 1, 2])) + + result, lindexer, rindexer = indexer(empty, right) + tm.assert_numpy_array_equal(result, right) + tm.assert_numpy_array_equal(lindexer, np.array([-1, -1, -1])) + tm.assert_numpy_array_equal(rindexer, np.array([0, 1, 2])) + + result, lindexer, rindexer = indexer(left, empty) + tm.assert_numpy_array_equal(result, left) + tm.assert_numpy_array_equal(lindexer, np.array([0, 1, 2])) + tm.assert_numpy_array_equal(rindexer, np.array([-1, -1, -1])) class TestUnique(tm.TestCase): _multiprocess_can_split_ = True @@ -174,13 +208,13 @@ def test_ints(self): arr = np.random.randint(0, 100, size=50) result = algos.unique(arr) - tm.assert_isinstance(result, np.ndarray) + tm.assertIsInstance(result, np.ndarray) def test_objects(self): arr = np.random.randint(0, 100, size=50).astype('O') result = algos.unique(arr) - tm.assert_isinstance(result, np.ndarray) + tm.assertIsInstance(result, np.ndarray) def test_object_refcount_bug(self): lst = ['A', 'B', 'C', 'D', 'E'] @@ -201,6 +235,50 @@ def test_on_index_object(self): tm.assert_almost_equal(result, expected) + def test_datetime64_dtype_array_returned(self): + # GH 9431 + expected = np.array(['2015-01-03T00:00:00.000000000+0000', + '2015-01-01T00:00:00.000000000+0000'], dtype='M8[ns]') + + dt_index = pd.to_datetime(['2015-01-03T00:00:00.000000000+0000', + '2015-01-01T00:00:00.000000000+0000', + '2015-01-01T00:00:00.000000000+0000']) + result = algos.unique(dt_index) + tm.assert_numpy_array_equal(result, expected) + self.assertEqual(result.dtype, expected.dtype) + + s = pd.Series(dt_index) + result = algos.unique(s) + tm.assert_numpy_array_equal(result, expected) + self.assertEqual(result.dtype, expected.dtype) + + arr = s.values + result = algos.unique(arr) + tm.assert_numpy_array_equal(result, expected) + self.assertEqual(result.dtype, expected.dtype) + + + def test_timedelta64_dtype_array_returned(self): + # GH 9431 + expected = np.array([31200, 45678, 10000], dtype='m8[ns]') + + td_index = pd.to_timedelta([31200, 45678, 31200, 10000, 45678]) + result = algos.unique(td_index) + tm.assert_numpy_array_equal(result, expected) + self.assertEqual(result.dtype, expected.dtype) + + s = pd.Series(td_index) + result = algos.unique(s) + tm.assert_numpy_array_equal(result, expected) + self.assertEqual(result.dtype, expected.dtype) + + arr = s.values + result = algos.unique(arr) + tm.assert_numpy_array_equal(result, expected) + self.assertEqual(result.dtype, expected.dtype) + + + class TestValueCounts(tm.TestCase): _multiprocess_can_split_ = True @@ -211,10 +289,16 @@ def test_value_counts(self): arr = np.random.randn(4) factor = cut(arr, 4) - tm.assert_isinstance(factor, Categorical) - + tm.assertIsInstance(factor, Categorical) result = algos.value_counts(factor) - expected = algos.value_counts(np.asarray(factor)) + cats = ['(-1.194, -0.535]', + '(-0.535, 0.121]', + '(0.121, 0.777]', + '(0.777, 1.433]' + ] + expected_index = CategoricalIndex(cats, cats, ordered=True) + expected = Series([1, 1, 1, 1], + index=expected_index) tm.assert_series_equal(result.sort_index(), expected.sort_index()) def test_value_counts_bins(self): @@ -254,6 +338,57 @@ def test_value_counts_nat(self): tm.assert_series_equal(algos.value_counts(dt), exp_dt) # TODO same for (timedelta) + def test_categorical(self): + s = Series(pd.Categorical(list('aaabbc'))) + result = s.value_counts() + expected = pd.Series([3, 2, 1], index=pd.CategoricalIndex(['a', 'b', 'c'])) + tm.assert_series_equal(result, expected, check_index_type=True) + + # preserve order? + s = s.cat.as_ordered() + result = s.value_counts() + expected.index = expected.index.as_ordered() + tm.assert_series_equal(result, expected, check_index_type=True) + + def test_categorical_nans(self): + s = Series(pd.Categorical(list('aaaaabbbcc'))) # 4,3,2,1 (nan) + s.iloc[1] = np.nan + result = s.value_counts() + expected = pd.Series([4, 3, 2], + index=pd.CategoricalIndex(['a', 'b', 'c'], + categories=['a', 'b', 'c'])) + tm.assert_series_equal(result, expected, check_index_type=True) + result = s.value_counts(dropna=False) + expected = pd.Series([4, 3, 2, 1], index=pd.CategoricalIndex( + ['a', 'b', 'c', np.nan])) + tm.assert_series_equal(result, expected, check_index_type=True) + + # out of order + s = Series(pd.Categorical(list('aaaaabbbcc'), + ordered=True, categories=['b', 'a', 'c'])) + s.iloc[1] = np.nan + result = s.value_counts() + expected = pd.Series([4, 3, 2], + index=pd.CategoricalIndex(['a', 'b', 'c'], + categories=['b', 'a', 'c'], + ordered=True)) + tm.assert_series_equal(result, expected, check_index_type=True) + + result = s.value_counts(dropna=False) + expected = pd.Series([4, 3, 2, 1], index=pd.CategoricalIndex( + ['a', 'b', 'c', np.nan], categories=['b', 'a', 'c'], ordered=True)) + tm.assert_series_equal(result, expected, check_index_type=True) + + def test_categorical_zeroes(self): + # keep the `d` category with 0 + s = Series(pd.Categorical(list('bbbaac'), categories=list('abcd'), + ordered=True)) + result = s.value_counts() + expected = Series([3, 2, 1, 0], index=pd.Categorical( + ['b', 'a', 'c', 'd'], categories=list('abcd'), ordered=True)) + tm.assert_series_equal(result, expected, check_index_type=True) + + def test_dropna(self): # https://github.com/pydata/pandas/issues/9443#issuecomment-73719328 @@ -285,6 +420,125 @@ def test_dropna(self): pd.Series([10.3, 5., 5., None]).value_counts(dropna=False), pd.Series([2, 1, 1], index=[5., 10.3, np.nan])) + +class GroupVarTestMixin(object): + + def test_group_var_generic_1d(self): + prng = RandomState(1234) + + out = (np.nan * np.ones((5, 1))).astype(self.dtype) + counts = np.zeros(5, dtype='int64') + values = 10 * prng.rand(15, 1).astype(self.dtype) + labels = np.tile(np.arange(5), (3, )).astype('int64') + + expected_out = (np.squeeze(values) + .reshape((5, 3), order='F') + .std(axis=1, ddof=1) ** 2)[:, np.newaxis] + expected_counts = counts + 3 + + self.algo(out, counts, values, labels) + np.testing.assert_allclose(out, expected_out, self.rtol) + tm.assert_numpy_array_equal(counts, expected_counts) + + def test_group_var_generic_1d_flat_labels(self): + prng = RandomState(1234) + + out = (np.nan * np.ones((1, 1))).astype(self.dtype) + counts = np.zeros(1, dtype='int64') + values = 10 * prng.rand(5, 1).astype(self.dtype) + labels = np.zeros(5, dtype='int64') + + expected_out = np.array([[values.std(ddof=1) ** 2]]) + expected_counts = counts + 5 + + self.algo(out, counts, values, labels) + + np.testing.assert_allclose(out, expected_out, self.rtol) + tm.assert_numpy_array_equal(counts, expected_counts) + + def test_group_var_generic_2d_all_finite(self): + prng = RandomState(1234) + + out = (np.nan * np.ones((5, 2))).astype(self.dtype) + counts = np.zeros(5, dtype='int64') + values = 10 * prng.rand(10, 2).astype(self.dtype) + labels = np.tile(np.arange(5), (2, )).astype('int64') + + expected_out = np.std( + values.reshape(2, 5, 2), ddof=1, axis=0) ** 2 + expected_counts = counts + 2 + + self.algo(out, counts, values, labels) + np.testing.assert_allclose(out, expected_out, self.rtol) + tm.assert_numpy_array_equal(counts, expected_counts) + + def test_group_var_generic_2d_some_nan(self): + prng = RandomState(1234) + + out = (np.nan * np.ones((5, 2))).astype(self.dtype) + counts = np.zeros(5, dtype='int64') + values = 10 * prng.rand(10, 2).astype(self.dtype) + values[:, 1] = np.nan + labels = np.tile(np.arange(5), (2, )).astype('int64') + + expected_out = np.vstack([ + values[:, 0].reshape(5, 2, order='F').std(ddof=1, axis=1) ** 2, + np.nan * np.ones(5) + ]).T + expected_counts = counts + 2 + + self.algo(out, counts, values, labels) + np.testing.assert_allclose(out, expected_out, self.rtol) + tm.assert_numpy_array_equal(counts, expected_counts) + + def test_group_var_constant(self): + # Regression test from GH 10448. + + out = np.array([[np.nan]], dtype=self.dtype) + counts = np.array([0],dtype='int64') + values = 0.832845131556193 * np.ones((3, 1), dtype=self.dtype) + labels = np.zeros(3, dtype='int64') + + self.algo(out, counts, values, labels) + + self.assertEqual(counts[0], 3) + self.assertTrue(out[0, 0] >= 0) # Python 2.6 has no assertGreaterEqual + tm.assert_almost_equal(out[0, 0], 0.0) + + +class TestGroupVarFloat64(tm.TestCase, GroupVarTestMixin): + __test__ = True + _multiprocess_can_split_ = True + + algo = algos.algos.group_var_float64 + dtype = np.float64 + rtol = 1e-5 + + def test_group_var_large_inputs(self): + + prng = RandomState(1234) + + out = np.array([[np.nan]], dtype=self.dtype) + counts = np.array([0],dtype='int64') + values = (prng.rand(10 ** 6) + 10 ** 12).astype(self.dtype) + values.shape = (10 ** 6, 1) + labels = np.zeros(10 ** 6, dtype='int64') + + self.algo(out, counts, values, labels) + + self.assertEqual(counts[0], 10 ** 6) + tm.assert_almost_equal(out[0, 0], 1.0 / 12, check_less_precise=True) + + +class TestGroupVarFloat32(tm.TestCase, GroupVarTestMixin): + __test__ = True + _multiprocess_can_split_ = True + + algo = algos.algos.group_var_float32 + dtype = np.float32 + rtol = 1e-2 + + def test_quantile(): s = Series(np.random.randn(100)) @@ -300,12 +554,12 @@ def test_unique_label_indices(): left = unique_label_indices(a) right = np.unique(a, return_index=True)[1] - tm.assert_array_equal(left, right) + tm.assert_numpy_array_equal(left, right) a[np.random.choice(len(a), 10)] = -1 left= unique_label_indices(a) right = np.unique(a, return_index=True)[1][1:] - tm.assert_array_equal(left, right) + tm.assert_numpy_array_equal(left, right) if __name__ == '__main__': import nose diff --git a/pandas/tests/test_base.py b/pandas/tests/test_base.py index e9526f9fad1ac..c9e4285d8b684 100644 --- a/pandas/tests/test_base.py +++ b/pandas/tests/test_base.py @@ -8,10 +8,11 @@ from pandas.compat import u, StringIO from pandas.core.base import FrozenList, FrozenNDArray, PandasDelegate from pandas.tseries.base import DatetimeIndexOpsMixin -from pandas.util.testing import assertRaisesRegexp, assert_isinstance +from pandas.util.testing import assertRaisesRegexp, assertIsInstance from pandas.tseries.common import is_datetimelike from pandas import Series, Index, Int64Index, DatetimeIndex, TimedeltaIndex, PeriodIndex, Timedelta import pandas.tslib as tslib +from pandas import _np_version_under1p9 import nose import pandas.util.testing as tm @@ -68,7 +69,7 @@ def test_slicing_maintains_type(self): def check_result(self, result, expected, klass=None): klass = klass or self.klass - assert_isinstance(result, klass) + assertIsInstance(result, klass) self.assertEqual(result, expected) @@ -109,12 +110,12 @@ def setUp(self): def test_shallow_copying(self): original = self.container.copy() - assert_isinstance(self.container.view(), FrozenNDArray) + assertIsInstance(self.container.view(), FrozenNDArray) self.assertFalse(isinstance(self.container.view(np.ndarray), FrozenNDArray)) self.assertIsNot(self.container.view(), self.container) self.assert_numpy_array_equal(self.container, original) # shallow copy should be the same too - assert_isinstance(self.container._shallow_copy(), FrozenNDArray) + assertIsInstance(self.container._shallow_copy(), FrozenNDArray) # setting should not be allowed def testit(container): container[0] = 16 @@ -181,23 +182,24 @@ def f(): class Ops(tm.TestCase): def setUp(self): - self.bool_index = tm.makeBoolIndex(10) - self.int_index = tm.makeIntIndex(10) - self.float_index = tm.makeFloatIndex(10) - self.dt_index = tm.makeDateIndex(10) - self.dt_tz_index = tm.makeDateIndex(10).tz_localize(tz='US/Eastern') - self.period_index = tm.makePeriodIndex(10) - self.string_index = tm.makeStringIndex(10) + self.bool_index = tm.makeBoolIndex(10, name='a') + self.int_index = tm.makeIntIndex(10, name='a') + self.float_index = tm.makeFloatIndex(10, name='a') + self.dt_index = tm.makeDateIndex(10, name='a') + self.dt_tz_index = tm.makeDateIndex(10, name='a').tz_localize(tz='US/Eastern') + self.period_index = tm.makePeriodIndex(10, name='a') + self.string_index = tm.makeStringIndex(10, name='a') + self.unicode_index = tm.makeUnicodeIndex(10, name='a') arr = np.random.randn(10) - self.int_series = Series(arr, index=self.int_index) - self.float_series = Series(arr, index=self.float_index) - self.dt_series = Series(arr, index=self.dt_index) + self.int_series = Series(arr, index=self.int_index, name='a') + self.float_series = Series(arr, index=self.float_index, name='a') + self.dt_series = Series(arr, index=self.dt_index, name='a') self.dt_tz_series = self.dt_tz_index.to_series(keep_tz=True) - self.period_series = Series(arr, index=self.period_index) - self.string_series = Series(arr, index=self.string_index) + self.period_series = Series(arr, index=self.period_index, name='a') + self.string_series = Series(arr, index=self.string_index, name='a') - types = ['bool','int','float','dt', 'dt_tz', 'period','string'] + types = ['bool','int','float','dt', 'dt_tz', 'period','string', 'unicode'] fmts = [ "{0}_{1}".format(t,f) for t in types for f in ['index','series'] ] self.objs = [ getattr(self,f) for f in fmts if getattr(self,f,None) is not None ] @@ -213,9 +215,9 @@ def check_ops_properties(self, props, filter=None, ignore_failures=False): try: if isinstance(o, Series): - expected = Series(getattr(o.index,op),index=o.index) + expected = Series(getattr(o.index,op), index=o.index, name='a') else: - expected = getattr(o,op) + expected = getattr(o, op) except (AttributeError): if ignore_failures: continue @@ -272,6 +274,45 @@ def setUp(self): self.is_valid_objs = [ o for o in self.objs if o._allow_index_ops ] self.not_valid_objs = [ o for o in self.objs if not o._allow_index_ops ] + def test_none_comparison(self): + + # bug brought up by #1079 + # changed from TypeError in 0.17.0 + for o in self.is_valid_objs: + if isinstance(o, Series): + + o[0] = np.nan + + result = o == None + self.assertFalse(result.iat[0]) + self.assertFalse(result.iat[1]) + + result = o != None + self.assertTrue(result.iat[0]) + self.assertTrue(result.iat[1]) + + result = None == o + self.assertFalse(result.iat[0]) + self.assertFalse(result.iat[1]) + + if _np_version_under1p9: + # fails as this tries not __eq__ which + # is not valid for numpy + pass + else: + result = None != o + self.assertTrue(result.iat[0]) + self.assertTrue(result.iat[1]) + + result = None > o + self.assertFalse(result.iat[0]) + self.assertFalse(result.iat[1]) + + result = o < None + self.assertFalse(result.iat[0]) + self.assertFalse(result.iat[1]) + + def test_ndarray_compat_properties(self): for o in self.objs: @@ -361,21 +402,28 @@ def test_value_counts_unique_nunique(self): # create repeated values, 'n'th element is repeated by n+1 times if isinstance(o, PeriodIndex): # freq must be specified because repeat makes freq ambiguous - expected_index = o[::-1] - o = klass(np.repeat(values, range(1, len(o) + 1)), freq=o.freq) + + # resets name from Index + expected_index = pd.Index(o[::-1], name=None) + + # attach name to klass + o = klass(np.repeat(values, range(1, len(o) + 1)), freq=o.freq, name='a') # don't test boolean elif isinstance(o,Index) and o.is_boolean(): continue elif isinstance(o, Index): - expected_index = values[::-1] - o = klass(np.repeat(values, range(1, len(o) + 1))) + expected_index = pd.Index(values[::-1], name=None) + o = klass(np.repeat(values, range(1, len(o) + 1)), name='a') else: - expected_index = values[::-1] + expected_index = pd.Index(values[::-1], name=None) idx = np.repeat(o.index.values, range(1, len(o) + 1)) - o = klass(np.repeat(values, range(1, len(o) + 1)), index=idx) + o = klass(np.repeat(values, range(1, len(o) + 1)), index=idx, name='a') - expected_s = Series(range(10, 0, -1), index=expected_index, dtype='int64') - tm.assert_series_equal(o.value_counts(), expected_s) + expected_s = Series(range(10, 0, -1), index=expected_index, dtype='int64', name='a') + result = o.value_counts() + tm.assert_series_equal(result, expected_s) + self.assertTrue(result.index.name is None) + self.assertEqual(result.name, 'a') result = o.unique() if isinstance(o, (DatetimeIndex, PeriodIndex)): @@ -410,21 +458,34 @@ def test_value_counts_unique_nunique(self): # create repeated values, 'n'th element is repeated by n+1 times if isinstance(o, PeriodIndex): # freq must be specified because repeat makes freq ambiguous - expected_index = o - o = klass(np.repeat(values, range(1, len(o) + 1)), freq=o.freq) + + # resets name from Index + expected_index = pd.Index(o, name=None) + # attach name to klass + o = klass(np.repeat(values, range(1, len(o) + 1)), freq=o.freq, name='a') elif isinstance(o, Index): - expected_index = values - o = klass(np.repeat(values, range(1, len(o) + 1))) + expected_index = pd.Index(values, name=None) + o = klass(np.repeat(values, range(1, len(o) + 1)), name='a') else: - expected_index = values + expected_index = pd.Index(values, name=None) idx = np.repeat(o.index.values, range(1, len(o) + 1)) - o = klass(np.repeat(values, range(1, len(o) + 1)), index=idx) - - expected_s_na = Series(list(range(10, 2, -1)) +[3], index=expected_index[9:0:-1], dtype='int64') - expected_s = Series(list(range(10, 2, -1)), index=expected_index[9:1:-1], dtype='int64') - - tm.assert_series_equal(o.value_counts(dropna=False), expected_s_na) + o = klass(np.repeat(values, range(1, len(o) + 1)), index=idx, name='a') + + expected_s_na = Series(list(range(10, 2, -1)) +[3], + index=expected_index[9:0:-1], + dtype='int64', name='a') + expected_s = Series(list(range(10, 2, -1)), + index=expected_index[9:1:-1], + dtype='int64', name='a') + + result_s_na = o.value_counts(dropna=False) + tm.assert_series_equal(result_s_na, expected_s_na) + self.assertTrue(result_s_na.index.name is None) + self.assertEqual(result_s_na.name, 'a') + result_s = o.value_counts() tm.assert_series_equal(o.value_counts(), expected_s) + self.assertTrue(result_s.index.name is None) + self.assertEqual(result_s.name, 'a') # numpy_array_equal cannot compare arrays includes nan result = o.unique() @@ -508,14 +569,15 @@ def test_value_counts_inferred(self): df = pd.read_fwf(f, widths=[6, 8, 3], names=["person_id", "dt", "food"], parse_dates=["dt"]) - s = klass(df['dt'].copy()) + s = klass(df['dt'].copy(), name='dt') - idx = pd.to_datetime(['2010-01-01 00:00:00Z', '2008-09-09 00:00:00Z', '2009-01-01 00:00:00X']) - expected_s = Series([3, 2, 1], index=idx) + idx = pd.to_datetime(['2010-01-01 00:00:00Z', '2008-09-09 00:00:00Z', + '2009-01-01 00:00:00X']) + expected_s = Series([3, 2, 1], index=idx, name='dt') tm.assert_series_equal(s.value_counts(), expected_s) - expected = np.array(['2010-01-01 00:00:00Z', '2009-01-01 00:00:00Z', '2008-09-09 00:00:00Z'], - dtype='datetime64[ns]') + expected = np.array(['2010-01-01 00:00:00Z', '2009-01-01 00:00:00Z', + '2008-09-09 00:00:00Z'], dtype='datetime64[ns]') if isinstance(s, DatetimeIndex): expected = DatetimeIndex(expected) self.assertTrue(s.unique().equals(expected)) @@ -526,7 +588,7 @@ def test_value_counts_inferred(self): # with NaT s = df['dt'].copy() - s = klass([v for v in s.values] + [pd.NaT]) + s = klass([v for v in s.values] + [pd.NaT], name='dt') result = s.value_counts() self.assertEqual(result.index.dtype, 'datetime64[ns]') @@ -547,10 +609,10 @@ def test_value_counts_inferred(self): # timedelta64[ns] td = df.dt - df.dt + timedelta(1) - td = klass(td) + td = klass(td, name='dt') result = td.value_counts() - expected_s = Series([6], index=[Timedelta('1day')]) + expected_s = Series([6], index=[Timedelta('1day')], name='dt') tm.assert_series_equal(result, expected_s) expected = TimedeltaIndex(['1 days']) @@ -560,9 +622,8 @@ def test_value_counts_inferred(self): self.assert_numpy_array_equal(td.unique(), expected.values) td2 = timedelta(1) + (df.dt - df.dt) - td2 = klass(td2) + td2 = klass(td2, name='dt') result2 = td2.value_counts() - tm.assert_series_equal(result2, expected_s) def test_factorize(self): @@ -629,7 +690,7 @@ def test_duplicated_drop_duplicates(self): # special case if original.is_boolean(): result = original.drop_duplicates() - expected = Index([False,True]) + expected = Index([False,True], name='a') tm.assert_index_equal(result, expected) continue @@ -653,22 +714,44 @@ def test_duplicated_drop_duplicates(self): self.assertTrue(duplicated.dtype == bool) tm.assert_index_equal(idx.drop_duplicates(), original) - last_base = [False] * len(idx) - last_base[3] = True - last_base[5] = True - expected = np.array(last_base) - duplicated = idx.duplicated(take_last=True) + base = [False] * len(idx) + base[3] = True + base[5] = True + expected = np.array(base) + + duplicated = idx.duplicated(keep='last') + tm.assert_numpy_array_equal(duplicated, expected) + self.assertTrue(duplicated.dtype == bool) + result = idx.drop_duplicates(keep='last') + tm.assert_index_equal(result, idx[~expected]) + + # deprecate take_last + with tm.assert_produces_warning(FutureWarning): + duplicated = idx.duplicated(take_last=True) + tm.assert_numpy_array_equal(duplicated, expected) + self.assertTrue(duplicated.dtype == bool) + with tm.assert_produces_warning(FutureWarning): + result = idx.drop_duplicates(take_last=True) + tm.assert_index_equal(result, idx[~expected]) + + base = [False] * len(original) + [True, True] + base[3] = True + base[5] = True + expected = np.array(base) + + duplicated = idx.duplicated(keep=False) tm.assert_numpy_array_equal(duplicated, expected) self.assertTrue(duplicated.dtype == bool) - tm.assert_index_equal(idx.drop_duplicates(take_last=True), - idx[~np.array(last_base)]) + result = idx.drop_duplicates(keep=False) + tm.assert_index_equal(result, idx[~expected]) with tm.assertRaisesRegexp(TypeError, "drop_duplicates\(\) got an unexpected keyword argument"): idx.drop_duplicates(inplace=True) else: - expected = Series([False] * len(original), index=original.index) + expected = Series([False] * len(original), + index=original.index, name='a') tm.assert_series_equal(original.duplicated(), expected) result = original.drop_duplicates() tm.assert_series_equal(result, original) @@ -676,20 +759,36 @@ def test_duplicated_drop_duplicates(self): idx = original.index[list(range(len(original))) + [5, 3]] values = original.values[list(range(len(original))) + [5, 3]] - s = Series(values, index=idx) + s = Series(values, index=idx, name='a') - expected = Series([False] * len(original) + [True, True], index=idx) + expected = Series([False] * len(original) + [True, True], + index=idx, name='a') tm.assert_series_equal(s.duplicated(), expected) tm.assert_series_equal(s.drop_duplicates(), original) - last_base = [False] * len(idx) - last_base[3] = True - last_base[5] = True - expected = Series(last_base, index=idx) - expected - tm.assert_series_equal(s.duplicated(take_last=True), expected) - tm.assert_series_equal(s.drop_duplicates(take_last=True), - s[~np.array(last_base)]) + base = [False] * len(idx) + base[3] = True + base[5] = True + expected = Series(base, index=idx, name='a') + + tm.assert_series_equal(s.duplicated(keep='last'), expected) + tm.assert_series_equal(s.drop_duplicates(keep='last'), + s[~np.array(base)]) + + # deprecate take_last + with tm.assert_produces_warning(FutureWarning): + tm.assert_series_equal(s.duplicated(take_last=True), expected) + with tm.assert_produces_warning(FutureWarning): + tm.assert_series_equal(s.drop_duplicates(take_last=True), + s[~np.array(base)]) + base = [False] * len(original) + [True, True] + base[3] = True + base[5] = True + expected = Series(base, index=idx, name='a') + + tm.assert_series_equal(s.duplicated(keep=False), expected) + tm.assert_series_equal(s.drop_duplicates(keep=False), + s[~np.array(base)]) s.drop_duplicates(inplace=True) tm.assert_series_equal(s, original) diff --git a/pandas/tests/test_categorical.py b/pandas/tests/test_categorical.py index c83ba897125bf..680b370cbca41 100755 --- a/pandas/tests/test_categorical.py +++ b/pandas/tests/test_categorical.py @@ -395,8 +395,8 @@ def f(): self.assertRaises(TypeError, lambda: cat_rev > a) # The following work via '__array_priority__ = 1000' - # works only on numpy >= 1.7.1 and not on PY3.2 - if LooseVersion(np.__version__) > "1.7.1" and not compat.PY3_2: + # works only on numpy >= 1.7.1 + if LooseVersion(np.__version__) > "1.7.1": self.assertRaises(TypeError, lambda: a < cat) self.assertRaises(TypeError, lambda: a < cat_rev) @@ -458,7 +458,8 @@ def test_describe(self): desc = cat.describe() expected = DataFrame.from_dict(dict(counts=[1, 2, 1], freqs=[1/4., 2/4., 1/4.], - categories=[1,2,np.nan] + categories=Categorical([1,2,np.nan], + [1, 2]) ) ).set_index('categories') tm.assert_frame_equal(desc, expected) @@ -492,7 +493,7 @@ def test_print(self): def test_big_print(self): factor = Categorical([0,1,2,0,1,2]*100, ['a', 'b', 'c'], name='cat', fastpath=True) expected = ["[a, b, c, a, b, ..., b, c, a, b, c]", - "Name: cat, Length: 600", + "Length: 600", "Categories (3, object): [a, b, c]"] expected = "\n".join(expected) @@ -501,15 +502,11 @@ def test_big_print(self): self.assertEqual(actual, expected) def test_empty_print(self): - factor = Categorical([], ["a","b","c"], name="cat") - expected = ("[], Name: cat, Categories (3, object): [a, b, c]") - # hack because array_repr changed in numpy > 1.6.x - actual = repr(factor) - self.assertEqual(actual, expected) - factor = Categorical([], ["a","b","c"]) expected = ("[], Categories (3, object): [a, b, c]") + # hack because array_repr changed in numpy > 1.6.x actual = repr(factor) + self.assertEqual(actual, expected) self.assertEqual(expected, actual) factor = Categorical([], ["a","b","c"], ordered=True) @@ -523,9 +520,9 @@ def test_empty_print(self): def test_print_none_width(self): # GH10087 - a = pd.Series(pd.Categorical([1,2,3,4], name="a")) + a = pd.Series(pd.Categorical([1,2,3,4])) exp = u("0 1\n1 2\n2 3\n3 4\n" + - "Name: a, dtype: category\nCategories (4, int64): [1, 2, 3, 4]") + "dtype: category\nCategories (4, int64): [1, 2, 3, 4]") with option_context("display.width", None): self.assertEqual(exp, repr(a)) @@ -962,20 +959,59 @@ def test_min_max(self): self.assertEqual(_max, 1) def test_unique(self): - cat = Categorical(["a","b"]) - exp = np.asarray(["a","b"]) + # categories are reordered based on value when ordered=False + cat = Categorical(["a", "b"]) + exp = np.asarray(["a", "b"]) + res = cat.unique() + self.assert_numpy_array_equal(res, exp) + + cat = Categorical(["a", "b", "a", "a"], categories=["a", "b", "c"]) res = cat.unique() self.assert_numpy_array_equal(res, exp) + tm.assert_categorical_equal(res, Categorical(exp)) - cat = Categorical(["a","b","a","a"], categories=["a","b","c"]) + cat = Categorical(["c", "a", "b", "a", "a"], categories=["a", "b", "c"]) + exp = np.asarray(["c", "a", "b"]) res = cat.unique() self.assert_numpy_array_equal(res, exp) + tm.assert_categorical_equal(res, Categorical(exp, categories=['c', 'a', 'b'])) - # unique should not sort - cat = Categorical(["b", "b", np.nan, "a"], categories=["a","b","c"]) + # nan must be removed + cat = Categorical(["b", np.nan, "b", np.nan, "a"], categories=["a", "b", "c"]) res = cat.unique() exp = np.asarray(["b", np.nan, "a"], dtype=object) self.assert_numpy_array_equal(res, exp) + tm.assert_categorical_equal(res, Categorical(["b", np.nan, "a"], categories=["b", "a"])) + + def test_unique_ordered(self): + # keep categories order when ordered=True + cat = Categorical(['b', 'a', 'b'], categories=['a', 'b'], ordered=True) + res = cat.unique() + exp = np.asarray(['b', 'a']) + exp_cat = Categorical(exp, categories=['a', 'b'], ordered=True) + self.assert_numpy_array_equal(res, exp) + tm.assert_categorical_equal(res, exp_cat) + + cat = Categorical(['c', 'b', 'a', 'a'], categories=['a', 'b', 'c'], ordered=True) + res = cat.unique() + exp = np.asarray(['c', 'b', 'a']) + exp_cat = Categorical(exp, categories=['a', 'b', 'c'], ordered=True) + self.assert_numpy_array_equal(res, exp) + tm.assert_categorical_equal(res, exp_cat) + + cat = Categorical(['b', 'a', 'a'], categories=['a', 'b', 'c'], ordered=True) + res = cat.unique() + exp = np.asarray(['b', 'a']) + exp_cat = Categorical(exp, categories=['a', 'b'], ordered=True) + self.assert_numpy_array_equal(res, exp) + tm.assert_categorical_equal(res, exp_cat) + + cat = Categorical(['b', 'b', np.nan, 'a'], categories=['a', 'b', 'c'], ordered=True) + res = cat.unique() + exp = np.asarray(['b', np.nan, 'a'], dtype=object) + exp_cat = Categorical(exp, categories=['a', 'b'], ordered=True) + self.assert_numpy_array_equal(res, exp) + tm.assert_categorical_equal(res, exp_cat) def test_mode(self): s = Categorical([1,1,2,4,5,5,5], categories=[5,4,3,2,1], ordered=True) @@ -1080,6 +1116,26 @@ def test_set_item_nan(self): exp = np.array([0,1,3,2]) self.assert_numpy_array_equal(cat.codes, exp) + def test_shift(self): + # GH 9416 + cat = pd.Categorical(['a', 'b', 'c', 'd', 'a']) + + # shift forward + sp1 = cat.shift(1) + xp1 = pd.Categorical([np.nan, 'a', 'b', 'c', 'd']) + self.assert_categorical_equal(sp1, xp1) + self.assert_categorical_equal(cat[:-1], sp1[1:]) + + # shift back + sn2 = cat.shift(-2) + xp2 = pd.Categorical(['c', 'd', 'a', np.nan, np.nan], + categories=['a', 'b', 'c', 'd']) + self.assert_categorical_equal(sn2, xp2) + self.assert_categorical_equal(cat[2:], sn2[:-2]) + + # shift by zero + self.assert_categorical_equal(cat, cat.shift(0)) + def test_nbytes(self): cat = pd.Categorical([1,2,3]) exp = cat._codes.nbytes + cat._categories.values.nbytes @@ -1150,6 +1206,13 @@ def test_deprecated_levels(self): self.assertFalse(LooseVersion(pd.__version__) >= '0.18') + def test_removed_names_produces_warning(self): + with tm.assert_produces_warning(UserWarning): + Categorical([0,1], name="a") + + with tm.assert_produces_warning(UserWarning): + Categorical.from_codes([1,2], ["a","b","c"], name="a") + def test_datetime_categorical_comparison(self): dt_cat = pd.Categorical(pd.date_range('2014-01-01', periods=3), ordered=True) self.assert_numpy_array_equal(dt_cat > dt_cat[0], [False, True, True]) @@ -1653,26 +1716,602 @@ def test_describe(self): self.assert_numpy_array_equal(res["cat"].values, res["s"].values) def test_repr(self): - a = pd.Series(pd.Categorical([1,2,3,4], name="a")) + a = pd.Series(pd.Categorical([1,2,3,4])) exp = u("0 1\n1 2\n2 3\n3 4\n" + - "Name: a, dtype: category\nCategories (4, int64): [1, 2, 3, 4]") + "dtype: category\nCategories (4, int64): [1, 2, 3, 4]") self.assertEqual(exp, a.__unicode__()) - a = pd.Series(pd.Categorical(["a","b"] *25, name="a")) + a = pd.Series(pd.Categorical(["a","b"] *25)) exp = u("0 a\n1 b\n" + " ..\n" + "48 a\n49 b\n" + - "Name: a, dtype: category\nCategories (2, object): [a, b]") + "dtype: category\nCategories (2, object): [a, b]") with option_context("display.max_rows", 5): self.assertEqual(exp, repr(a)) levs = list("abcdefghijklmnopqrstuvwxyz") - a = pd.Series(pd.Categorical(["a","b"], name="a", categories=levs, ordered=True)) + a = pd.Series(pd.Categorical(["a","b"], categories=levs, ordered=True)) exp = u("0 a\n1 b\n" + - "Name: a, dtype: category\n" + "dtype: category\n" "Categories (26, object): [a < b < c < d ... w < x < y < z]") self.assertEqual(exp,a.__unicode__()) + def test_categorical_repr(self): + c = pd.Categorical([1, 2 ,3]) + exp = """[1, 2, 3] +Categories (3, int64): [1, 2, 3]""" + self.assertEqual(repr(c), exp) + + c = pd.Categorical([1, 2 ,3, 1, 2 ,3], categories=[1, 2, 3]) + exp = """[1, 2, 3, 1, 2, 3] +Categories (3, int64): [1, 2, 3]""" + self.assertEqual(repr(c), exp) + + c = pd.Categorical([1, 2, 3, 4, 5] * 10) + exp = """[1, 2, 3, 4, 5, ..., 1, 2, 3, 4, 5] +Length: 50 +Categories (5, int64): [1, 2, 3, 4, 5]""" + self.assertEqual(repr(c), exp) + + c = pd.Categorical(np.arange(20)) + exp = """[0, 1, 2, 3, 4, ..., 15, 16, 17, 18, 19] +Length: 20 +Categories (20, int64): [0, 1, 2, 3, ..., 16, 17, 18, 19]""" + self.assertEqual(repr(c), exp) + + def test_categorical_repr_ordered(self): + c = pd.Categorical([1, 2 ,3], ordered=True) + exp = """[1, 2, 3] +Categories (3, int64): [1 < 2 < 3]""" + self.assertEqual(repr(c), exp) + + c = pd.Categorical([1, 2 ,3, 1, 2 ,3], categories=[1, 2, 3], ordered=True) + exp = """[1, 2, 3, 1, 2, 3] +Categories (3, int64): [1 < 2 < 3]""" + self.assertEqual(repr(c), exp) + + c = pd.Categorical([1, 2, 3, 4, 5] * 10, ordered=True) + exp = """[1, 2, 3, 4, 5, ..., 1, 2, 3, 4, 5] +Length: 50 +Categories (5, int64): [1 < 2 < 3 < 4 < 5]""" + self.assertEqual(repr(c), exp) + + c = pd.Categorical(np.arange(20), ordered=True) + exp = """[0, 1, 2, 3, 4, ..., 15, 16, 17, 18, 19] +Length: 20 +Categories (20, int64): [0 < 1 < 2 < 3 ... 16 < 17 < 18 < 19]""" + self.assertEqual(repr(c), exp) + + def test_categorical_repr_datetime(self): + idx = pd.date_range('2011-01-01 09:00', freq='H', periods=5) + c = pd.Categorical(idx) + exp = """[2011-01-01 09:00:00, 2011-01-01 10:00:00, 2011-01-01 11:00:00, 2011-01-01 12:00:00, 2011-01-01 13:00:00] +Categories (5, datetime64[ns]): [2011-01-01 09:00:00, 2011-01-01 10:00:00, 2011-01-01 11:00:00, + 2011-01-01 12:00:00, 2011-01-01 13:00:00]""" + self.assertEqual(repr(c), exp) + + c = pd.Categorical(idx.append(idx), categories=idx) + exp = """[2011-01-01 09:00:00, 2011-01-01 10:00:00, 2011-01-01 11:00:00, 2011-01-01 12:00:00, 2011-01-01 13:00:00, 2011-01-01 09:00:00, 2011-01-01 10:00:00, 2011-01-01 11:00:00, 2011-01-01 12:00:00, 2011-01-01 13:00:00] +Categories (5, datetime64[ns]): [2011-01-01 09:00:00, 2011-01-01 10:00:00, 2011-01-01 11:00:00, + 2011-01-01 12:00:00, 2011-01-01 13:00:00]""" + self.assertEqual(repr(c), exp) + + idx = pd.date_range('2011-01-01 09:00', freq='H', periods=5, tz='US/Eastern') + c = pd.Categorical(idx) + exp = """[2011-01-01 09:00:00-05:00, 2011-01-01 10:00:00-05:00, 2011-01-01 11:00:00-05:00, 2011-01-01 12:00:00-05:00, 2011-01-01 13:00:00-05:00] +Categories (5, datetime64[ns]): [2011-01-01 09:00:00-05:00, 2011-01-01 10:00:00-05:00, + 2011-01-01 11:00:00-05:00, 2011-01-01 12:00:00-05:00, + 2011-01-01 13:00:00-05:00]""" + self.assertEqual(repr(c), exp) + + c = pd.Categorical(idx.append(idx), categories=idx) + exp = """[2011-01-01 09:00:00-05:00, 2011-01-01 10:00:00-05:00, 2011-01-01 11:00:00-05:00, 2011-01-01 12:00:00-05:00, 2011-01-01 13:00:00-05:00, 2011-01-01 09:00:00-05:00, 2011-01-01 10:00:00-05:00, 2011-01-01 11:00:00-05:00, 2011-01-01 12:00:00-05:00, 2011-01-01 13:00:00-05:00] +Categories (5, datetime64[ns]): [2011-01-01 09:00:00-05:00, 2011-01-01 10:00:00-05:00, + 2011-01-01 11:00:00-05:00, 2011-01-01 12:00:00-05:00, + 2011-01-01 13:00:00-05:00]""" + self.assertEqual(repr(c), exp) + + def test_categorical_repr_datetime_ordered(self): + idx = pd.date_range('2011-01-01 09:00', freq='H', periods=5) + c = pd.Categorical(idx, ordered=True) + exp = """[2011-01-01 09:00:00, 2011-01-01 10:00:00, 2011-01-01 11:00:00, 2011-01-01 12:00:00, 2011-01-01 13:00:00] +Categories (5, datetime64[ns]): [2011-01-01 09:00:00 < 2011-01-01 10:00:00 < 2011-01-01 11:00:00 < + 2011-01-01 12:00:00 < 2011-01-01 13:00:00]""" + self.assertEqual(repr(c), exp) + + c = pd.Categorical(idx.append(idx), categories=idx, ordered=True) + exp = """[2011-01-01 09:00:00, 2011-01-01 10:00:00, 2011-01-01 11:00:00, 2011-01-01 12:00:00, 2011-01-01 13:00:00, 2011-01-01 09:00:00, 2011-01-01 10:00:00, 2011-01-01 11:00:00, 2011-01-01 12:00:00, 2011-01-01 13:00:00] +Categories (5, datetime64[ns]): [2011-01-01 09:00:00 < 2011-01-01 10:00:00 < 2011-01-01 11:00:00 < + 2011-01-01 12:00:00 < 2011-01-01 13:00:00]""" + self.assertEqual(repr(c), exp) + + idx = pd.date_range('2011-01-01 09:00', freq='H', periods=5, tz='US/Eastern') + c = pd.Categorical(idx, ordered=True) + exp = """[2011-01-01 09:00:00-05:00, 2011-01-01 10:00:00-05:00, 2011-01-01 11:00:00-05:00, 2011-01-01 12:00:00-05:00, 2011-01-01 13:00:00-05:00] +Categories (5, datetime64[ns]): [2011-01-01 09:00:00-05:00 < 2011-01-01 10:00:00-05:00 < + 2011-01-01 11:00:00-05:00 < 2011-01-01 12:00:00-05:00 < + 2011-01-01 13:00:00-05:00]""" + self.assertEqual(repr(c), exp) + + c = pd.Categorical(idx.append(idx), categories=idx, ordered=True) + exp = """[2011-01-01 09:00:00-05:00, 2011-01-01 10:00:00-05:00, 2011-01-01 11:00:00-05:00, 2011-01-01 12:00:00-05:00, 2011-01-01 13:00:00-05:00, 2011-01-01 09:00:00-05:00, 2011-01-01 10:00:00-05:00, 2011-01-01 11:00:00-05:00, 2011-01-01 12:00:00-05:00, 2011-01-01 13:00:00-05:00] +Categories (5, datetime64[ns]): [2011-01-01 09:00:00-05:00 < 2011-01-01 10:00:00-05:00 < + 2011-01-01 11:00:00-05:00 < 2011-01-01 12:00:00-05:00 < + 2011-01-01 13:00:00-05:00]""" + self.assertEqual(repr(c), exp) + + def test_categorical_repr_period(self): + idx = pd.period_range('2011-01-01 09:00', freq='H', periods=5) + c = pd.Categorical(idx) + exp = """[2011-01-01 09:00, 2011-01-01 10:00, 2011-01-01 11:00, 2011-01-01 12:00, 2011-01-01 13:00] +Categories (5, period): [2011-01-01 09:00, 2011-01-01 10:00, 2011-01-01 11:00, 2011-01-01 12:00, + 2011-01-01 13:00]""" + self.assertEqual(repr(c), exp) + + c = pd.Categorical(idx.append(idx), categories=idx) + exp = """[2011-01-01 09:00, 2011-01-01 10:00, 2011-01-01 11:00, 2011-01-01 12:00, 2011-01-01 13:00, 2011-01-01 09:00, 2011-01-01 10:00, 2011-01-01 11:00, 2011-01-01 12:00, 2011-01-01 13:00] +Categories (5, period): [2011-01-01 09:00, 2011-01-01 10:00, 2011-01-01 11:00, 2011-01-01 12:00, + 2011-01-01 13:00]""" + self.assertEqual(repr(c), exp) + + idx = pd.period_range('2011-01', freq='M', periods=5) + c = pd.Categorical(idx) + exp = """[2011-01, 2011-02, 2011-03, 2011-04, 2011-05] +Categories (5, period): [2011-01, 2011-02, 2011-03, 2011-04, 2011-05]""" + self.assertEqual(repr(c), exp) + + c = pd.Categorical(idx.append(idx), categories=idx) + exp = """[2011-01, 2011-02, 2011-03, 2011-04, 2011-05, 2011-01, 2011-02, 2011-03, 2011-04, 2011-05] +Categories (5, period): [2011-01, 2011-02, 2011-03, 2011-04, 2011-05]""" + self.assertEqual(repr(c), exp) + + def test_categorical_repr_period_ordered(self): + idx = pd.period_range('2011-01-01 09:00', freq='H', periods=5) + c = pd.Categorical(idx, ordered=True) + exp = """[2011-01-01 09:00, 2011-01-01 10:00, 2011-01-01 11:00, 2011-01-01 12:00, 2011-01-01 13:00] +Categories (5, period): [2011-01-01 09:00 < 2011-01-01 10:00 < 2011-01-01 11:00 < 2011-01-01 12:00 < + 2011-01-01 13:00]""" + self.assertEqual(repr(c), exp) + + c = pd.Categorical(idx.append(idx), categories=idx, ordered=True) + exp = """[2011-01-01 09:00, 2011-01-01 10:00, 2011-01-01 11:00, 2011-01-01 12:00, 2011-01-01 13:00, 2011-01-01 09:00, 2011-01-01 10:00, 2011-01-01 11:00, 2011-01-01 12:00, 2011-01-01 13:00] +Categories (5, period): [2011-01-01 09:00 < 2011-01-01 10:00 < 2011-01-01 11:00 < 2011-01-01 12:00 < + 2011-01-01 13:00]""" + self.assertEqual(repr(c), exp) + + idx = pd.period_range('2011-01', freq='M', periods=5) + c = pd.Categorical(idx, ordered=True) + exp = """[2011-01, 2011-02, 2011-03, 2011-04, 2011-05] +Categories (5, period): [2011-01 < 2011-02 < 2011-03 < 2011-04 < 2011-05]""" + self.assertEqual(repr(c), exp) + + c = pd.Categorical(idx.append(idx), categories=idx, ordered=True) + exp = """[2011-01, 2011-02, 2011-03, 2011-04, 2011-05, 2011-01, 2011-02, 2011-03, 2011-04, 2011-05] +Categories (5, period): [2011-01 < 2011-02 < 2011-03 < 2011-04 < 2011-05]""" + self.assertEqual(repr(c), exp) + + def test_categorical_repr_timedelta(self): + idx = pd.timedelta_range('1 days', periods=5) + c = pd.Categorical(idx) + exp = """[1 days, 2 days, 3 days, 4 days, 5 days] +Categories (5, timedelta64[ns]): [1 days, 2 days, 3 days, 4 days, 5 days]""" + self.assertEqual(repr(c), exp) + + c = pd.Categorical(idx.append(idx), categories=idx) + exp = """[1 days, 2 days, 3 days, 4 days, 5 days, 1 days, 2 days, 3 days, 4 days, 5 days] +Categories (5, timedelta64[ns]): [1 days, 2 days, 3 days, 4 days, 5 days]""" + self.assertEqual(repr(c), exp) + + idx = pd.timedelta_range('1 hours', periods=20) + c = pd.Categorical(idx) + exp = """[0 days 01:00:00, 1 days 01:00:00, 2 days 01:00:00, 3 days 01:00:00, 4 days 01:00:00, ..., 15 days 01:00:00, 16 days 01:00:00, 17 days 01:00:00, 18 days 01:00:00, 19 days 01:00:00] +Length: 20 +Categories (20, timedelta64[ns]): [0 days 01:00:00, 1 days 01:00:00, 2 days 01:00:00, + 3 days 01:00:00, ..., 16 days 01:00:00, 17 days 01:00:00, + 18 days 01:00:00, 19 days 01:00:00]""" + self.assertEqual(repr(c), exp) + + c = pd.Categorical(idx.append(idx), categories=idx) + exp = """[0 days 01:00:00, 1 days 01:00:00, 2 days 01:00:00, 3 days 01:00:00, 4 days 01:00:00, ..., 15 days 01:00:00, 16 days 01:00:00, 17 days 01:00:00, 18 days 01:00:00, 19 days 01:00:00] +Length: 40 +Categories (20, timedelta64[ns]): [0 days 01:00:00, 1 days 01:00:00, 2 days 01:00:00, + 3 days 01:00:00, ..., 16 days 01:00:00, 17 days 01:00:00, + 18 days 01:00:00, 19 days 01:00:00]""" + self.assertEqual(repr(c), exp) + + def test_categorical_repr_timedelta_ordered(self): + idx = pd.timedelta_range('1 days', periods=5) + c = pd.Categorical(idx, ordered=True) + exp = """[1 days, 2 days, 3 days, 4 days, 5 days] +Categories (5, timedelta64[ns]): [1 days < 2 days < 3 days < 4 days < 5 days]""" + self.assertEqual(repr(c), exp) + + c = pd.Categorical(idx.append(idx), categories=idx, ordered=True) + exp = """[1 days, 2 days, 3 days, 4 days, 5 days, 1 days, 2 days, 3 days, 4 days, 5 days] +Categories (5, timedelta64[ns]): [1 days < 2 days < 3 days < 4 days < 5 days]""" + self.assertEqual(repr(c), exp) + + idx = pd.timedelta_range('1 hours', periods=20) + c = pd.Categorical(idx, ordered=True) + exp = """[0 days 01:00:00, 1 days 01:00:00, 2 days 01:00:00, 3 days 01:00:00, 4 days 01:00:00, ..., 15 days 01:00:00, 16 days 01:00:00, 17 days 01:00:00, 18 days 01:00:00, 19 days 01:00:00] +Length: 20 +Categories (20, timedelta64[ns]): [0 days 01:00:00 < 1 days 01:00:00 < 2 days 01:00:00 < + 3 days 01:00:00 ... 16 days 01:00:00 < 17 days 01:00:00 < + 18 days 01:00:00 < 19 days 01:00:00]""" + self.assertEqual(repr(c), exp) + + c = pd.Categorical(idx.append(idx), categories=idx, ordered=True) + exp = """[0 days 01:00:00, 1 days 01:00:00, 2 days 01:00:00, 3 days 01:00:00, 4 days 01:00:00, ..., 15 days 01:00:00, 16 days 01:00:00, 17 days 01:00:00, 18 days 01:00:00, 19 days 01:00:00] +Length: 40 +Categories (20, timedelta64[ns]): [0 days 01:00:00 < 1 days 01:00:00 < 2 days 01:00:00 < + 3 days 01:00:00 ... 16 days 01:00:00 < 17 days 01:00:00 < + 18 days 01:00:00 < 19 days 01:00:00]""" + self.assertEqual(repr(c), exp) + + def test_categorical_series_repr(self): + s = pd.Series(pd.Categorical([1, 2 ,3])) + exp = """0 1 +1 2 +2 3 +dtype: category +Categories (3, int64): [1, 2, 3]""" + self.assertEqual(repr(s), exp) + + s = pd.Series(pd.Categorical(np.arange(10))) + exp = """0 0 +1 1 +2 2 +3 3 +4 4 +5 5 +6 6 +7 7 +8 8 +9 9 +dtype: category +Categories (10, int64): [0, 1, 2, 3, ..., 6, 7, 8, 9]""" + self.assertEqual(repr(s), exp) + + def test_categorical_series_repr_ordered(self): + s = pd.Series(pd.Categorical([1, 2 ,3], ordered=True)) + exp = """0 1 +1 2 +2 3 +dtype: category +Categories (3, int64): [1 < 2 < 3]""" + self.assertEqual(repr(s), exp) + + s = pd.Series(pd.Categorical(np.arange(10), ordered=True)) + exp = """0 0 +1 1 +2 2 +3 3 +4 4 +5 5 +6 6 +7 7 +8 8 +9 9 +dtype: category +Categories (10, int64): [0 < 1 < 2 < 3 ... 6 < 7 < 8 < 9]""" + self.assertEqual(repr(s), exp) + + def test_categorical_series_repr_datetime(self): + idx = pd.date_range('2011-01-01 09:00', freq='H', periods=5) + s = pd.Series(pd.Categorical(idx)) + exp = """0 2011-01-01 09:00:00 +1 2011-01-01 10:00:00 +2 2011-01-01 11:00:00 +3 2011-01-01 12:00:00 +4 2011-01-01 13:00:00 +dtype: category +Categories (5, datetime64[ns]): [2011-01-01 09:00:00, 2011-01-01 10:00:00, 2011-01-01 11:00:00, + 2011-01-01 12:00:00, 2011-01-01 13:00:00]""" + self.assertEqual(repr(s), exp) + + idx = pd.date_range('2011-01-01 09:00', freq='H', periods=5, tz='US/Eastern') + s = pd.Series(pd.Categorical(idx)) + exp = """0 2011-01-01 09:00:00-05:00 +1 2011-01-01 10:00:00-05:00 +2 2011-01-01 11:00:00-05:00 +3 2011-01-01 12:00:00-05:00 +4 2011-01-01 13:00:00-05:00 +dtype: category +Categories (5, datetime64[ns]): [2011-01-01 09:00:00-05:00, 2011-01-01 10:00:00-05:00, + 2011-01-01 11:00:00-05:00, 2011-01-01 12:00:00-05:00, + 2011-01-01 13:00:00-05:00]""" + self.assertEqual(repr(s), exp) + + def test_categorical_series_repr_datetime_ordered(self): + idx = pd.date_range('2011-01-01 09:00', freq='H', periods=5) + s = pd.Series(pd.Categorical(idx, ordered=True)) + exp = """0 2011-01-01 09:00:00 +1 2011-01-01 10:00:00 +2 2011-01-01 11:00:00 +3 2011-01-01 12:00:00 +4 2011-01-01 13:00:00 +dtype: category +Categories (5, datetime64[ns]): [2011-01-01 09:00:00 < 2011-01-01 10:00:00 < 2011-01-01 11:00:00 < + 2011-01-01 12:00:00 < 2011-01-01 13:00:00]""" + self.assertEqual(repr(s), exp) + + idx = pd.date_range('2011-01-01 09:00', freq='H', periods=5, tz='US/Eastern') + s = pd.Series(pd.Categorical(idx, ordered=True)) + exp = """0 2011-01-01 09:00:00-05:00 +1 2011-01-01 10:00:00-05:00 +2 2011-01-01 11:00:00-05:00 +3 2011-01-01 12:00:00-05:00 +4 2011-01-01 13:00:00-05:00 +dtype: category +Categories (5, datetime64[ns]): [2011-01-01 09:00:00-05:00 < 2011-01-01 10:00:00-05:00 < + 2011-01-01 11:00:00-05:00 < 2011-01-01 12:00:00-05:00 < + 2011-01-01 13:00:00-05:00]""" + self.assertEqual(repr(s), exp) + + def test_categorical_series_repr_period(self): + idx = pd.period_range('2011-01-01 09:00', freq='H', periods=5) + s = pd.Series(pd.Categorical(idx)) + exp = """0 2011-01-01 09:00 +1 2011-01-01 10:00 +2 2011-01-01 11:00 +3 2011-01-01 12:00 +4 2011-01-01 13:00 +dtype: category +Categories (5, period): [2011-01-01 09:00, 2011-01-01 10:00, 2011-01-01 11:00, 2011-01-01 12:00, + 2011-01-01 13:00]""" + self.assertEqual(repr(s), exp) + + idx = pd.period_range('2011-01', freq='M', periods=5) + s = pd.Series(pd.Categorical(idx)) + exp = """0 2011-01 +1 2011-02 +2 2011-03 +3 2011-04 +4 2011-05 +dtype: category +Categories (5, period): [2011-01, 2011-02, 2011-03, 2011-04, 2011-05]""" + self.assertEqual(repr(s), exp) + + def test_categorical_series_repr_period_ordered(self): + idx = pd.period_range('2011-01-01 09:00', freq='H', periods=5) + s = pd.Series(pd.Categorical(idx, ordered=True)) + exp = """0 2011-01-01 09:00 +1 2011-01-01 10:00 +2 2011-01-01 11:00 +3 2011-01-01 12:00 +4 2011-01-01 13:00 +dtype: category +Categories (5, period): [2011-01-01 09:00 < 2011-01-01 10:00 < 2011-01-01 11:00 < 2011-01-01 12:00 < + 2011-01-01 13:00]""" + self.assertEqual(repr(s), exp) + + idx = pd.period_range('2011-01', freq='M', periods=5) + s = pd.Series(pd.Categorical(idx, ordered=True)) + exp = """0 2011-01 +1 2011-02 +2 2011-03 +3 2011-04 +4 2011-05 +dtype: category +Categories (5, period): [2011-01 < 2011-02 < 2011-03 < 2011-04 < 2011-05]""" + self.assertEqual(repr(s), exp) + + def test_categorical_series_repr_timedelta(self): + idx = pd.timedelta_range('1 days', periods=5) + s = pd.Series(pd.Categorical(idx)) + exp = """0 1 days +1 2 days +2 3 days +3 4 days +4 5 days +dtype: category +Categories (5, timedelta64[ns]): [1 days, 2 days, 3 days, 4 days, 5 days]""" + self.assertEqual(repr(s), exp) + + idx = pd.timedelta_range('1 hours', periods=10) + s = pd.Series(pd.Categorical(idx)) + exp = """0 0 days 01:00:00 +1 1 days 01:00:00 +2 2 days 01:00:00 +3 3 days 01:00:00 +4 4 days 01:00:00 +5 5 days 01:00:00 +6 6 days 01:00:00 +7 7 days 01:00:00 +8 8 days 01:00:00 +9 9 days 01:00:00 +dtype: category +Categories (10, timedelta64[ns]): [0 days 01:00:00, 1 days 01:00:00, 2 days 01:00:00, + 3 days 01:00:00, ..., 6 days 01:00:00, 7 days 01:00:00, + 8 days 01:00:00, 9 days 01:00:00]""" + self.assertEqual(repr(s), exp) + + def test_categorical_series_repr_timedelta_ordered(self): + idx = pd.timedelta_range('1 days', periods=5) + s = pd.Series(pd.Categorical(idx, ordered=True)) + exp = """0 1 days +1 2 days +2 3 days +3 4 days +4 5 days +dtype: category +Categories (5, timedelta64[ns]): [1 days < 2 days < 3 days < 4 days < 5 days]""" + self.assertEqual(repr(s), exp) + + idx = pd.timedelta_range('1 hours', periods=10) + s = pd.Series(pd.Categorical(idx, ordered=True)) + exp = """0 0 days 01:00:00 +1 1 days 01:00:00 +2 2 days 01:00:00 +3 3 days 01:00:00 +4 4 days 01:00:00 +5 5 days 01:00:00 +6 6 days 01:00:00 +7 7 days 01:00:00 +8 8 days 01:00:00 +9 9 days 01:00:00 +dtype: category +Categories (10, timedelta64[ns]): [0 days 01:00:00 < 1 days 01:00:00 < 2 days 01:00:00 < + 3 days 01:00:00 ... 6 days 01:00:00 < 7 days 01:00:00 < + 8 days 01:00:00 < 9 days 01:00:00]""" + self.assertEqual(repr(s), exp) + + def test_categorical_index_repr(self): + idx = pd.CategoricalIndex(pd.Categorical([1, 2 ,3])) + exp = """CategoricalIndex([1, 2, 3], categories=[1, 2, 3], ordered=False, dtype='category')""" + self.assertEqual(repr(idx), exp) + + i = pd.CategoricalIndex(pd.Categorical(np.arange(10))) + exp = """CategoricalIndex([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], categories=[0, 1, 2, 3, 4, 5, 6, 7, ...], ordered=False, dtype='category')""" + self.assertEqual(repr(i), exp) + + def test_categorical_index_repr_ordered(self): + i = pd.CategoricalIndex(pd.Categorical([1, 2 ,3], ordered=True)) + exp = """CategoricalIndex([1, 2, 3], categories=[1, 2, 3], ordered=True, dtype='category')""" + self.assertEqual(repr(i), exp) + + i = pd.CategoricalIndex(pd.Categorical(np.arange(10), ordered=True)) + exp = """CategoricalIndex([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], categories=[0, 1, 2, 3, 4, 5, 6, 7, ...], ordered=True, dtype='category')""" + self.assertEqual(repr(i), exp) + + def test_categorical_index_repr_datetime(self): + idx = pd.date_range('2011-01-01 09:00', freq='H', periods=5) + i = pd.CategoricalIndex(pd.Categorical(idx)) + exp = """CategoricalIndex(['2011-01-01 09:00:00', '2011-01-01 10:00:00', + '2011-01-01 11:00:00', '2011-01-01 12:00:00', + '2011-01-01 13:00:00'], + categories=[2011-01-01 09:00:00, 2011-01-01 10:00:00, 2011-01-01 11:00:00, 2011-01-01 12:00:00, 2011-01-01 13:00:00], ordered=False, dtype='category')""" + self.assertEqual(repr(i), exp) + + idx = pd.date_range('2011-01-01 09:00', freq='H', periods=5, tz='US/Eastern') + i = pd.CategoricalIndex(pd.Categorical(idx)) + exp = """CategoricalIndex(['2011-01-01 09:00:00-05:00', '2011-01-01 10:00:00-05:00', + '2011-01-01 11:00:00-05:00', '2011-01-01 12:00:00-05:00', + '2011-01-01 13:00:00-05:00'], + categories=[2011-01-01 09:00:00-05:00, 2011-01-01 10:00:00-05:00, 2011-01-01 11:00:00-05:00, 2011-01-01 12:00:00-05:00, 2011-01-01 13:00:00-05:00], ordered=False, dtype='category')""" + self.assertEqual(repr(i), exp) + + def test_categorical_index_repr_datetime_ordered(self): + idx = pd.date_range('2011-01-01 09:00', freq='H', periods=5) + i = pd.CategoricalIndex(pd.Categorical(idx, ordered=True)) + exp = """CategoricalIndex(['2011-01-01 09:00:00', '2011-01-01 10:00:00', + '2011-01-01 11:00:00', '2011-01-01 12:00:00', + '2011-01-01 13:00:00'], + categories=[2011-01-01 09:00:00, 2011-01-01 10:00:00, 2011-01-01 11:00:00, 2011-01-01 12:00:00, 2011-01-01 13:00:00], ordered=True, dtype='category')""" + self.assertEqual(repr(i), exp) + + idx = pd.date_range('2011-01-01 09:00', freq='H', periods=5, tz='US/Eastern') + i = pd.CategoricalIndex(pd.Categorical(idx, ordered=True)) + exp = """CategoricalIndex(['2011-01-01 09:00:00-05:00', '2011-01-01 10:00:00-05:00', + '2011-01-01 11:00:00-05:00', '2011-01-01 12:00:00-05:00', + '2011-01-01 13:00:00-05:00'], + categories=[2011-01-01 09:00:00-05:00, 2011-01-01 10:00:00-05:00, 2011-01-01 11:00:00-05:00, 2011-01-01 12:00:00-05:00, 2011-01-01 13:00:00-05:00], ordered=True, dtype='category')""" + self.assertEqual(repr(i), exp) + + i = pd.CategoricalIndex(pd.Categorical(idx.append(idx), ordered=True)) + exp = """CategoricalIndex(['2011-01-01 09:00:00-05:00', '2011-01-01 10:00:00-05:00', + '2011-01-01 11:00:00-05:00', '2011-01-01 12:00:00-05:00', + '2011-01-01 13:00:00-05:00', '2011-01-01 09:00:00-05:00', + '2011-01-01 10:00:00-05:00', '2011-01-01 11:00:00-05:00', + '2011-01-01 12:00:00-05:00', '2011-01-01 13:00:00-05:00'], + categories=[2011-01-01 09:00:00-05:00, 2011-01-01 10:00:00-05:00, 2011-01-01 11:00:00-05:00, 2011-01-01 12:00:00-05:00, 2011-01-01 13:00:00-05:00], ordered=True, dtype='category')""" + self.assertEqual(repr(i), exp) + + def test_categorical_index_repr_period(self): + # test all length + idx = pd.period_range('2011-01-01 09:00', freq='H', periods=1) + i = pd.CategoricalIndex(pd.Categorical(idx)) + exp = """CategoricalIndex(['2011-01-01 09:00'], categories=[2011-01-01 09:00], ordered=False, dtype='category')""" + self.assertEqual(repr(i), exp) + + idx = pd.period_range('2011-01-01 09:00', freq='H', periods=2) + i = pd.CategoricalIndex(pd.Categorical(idx)) + exp = """CategoricalIndex(['2011-01-01 09:00', '2011-01-01 10:00'], categories=[2011-01-01 09:00, 2011-01-01 10:00], ordered=False, dtype='category')""" + self.assertEqual(repr(i), exp) + + idx = pd.period_range('2011-01-01 09:00', freq='H', periods=3) + i = pd.CategoricalIndex(pd.Categorical(idx)) + exp = """CategoricalIndex(['2011-01-01 09:00', '2011-01-01 10:00', '2011-01-01 11:00'], categories=[2011-01-01 09:00, 2011-01-01 10:00, 2011-01-01 11:00], ordered=False, dtype='category')""" + self.assertEqual(repr(i), exp) + + idx = pd.period_range('2011-01-01 09:00', freq='H', periods=5) + i = pd.CategoricalIndex(pd.Categorical(idx)) + exp = """CategoricalIndex(['2011-01-01 09:00', '2011-01-01 10:00', '2011-01-01 11:00', + '2011-01-01 12:00', '2011-01-01 13:00'], + categories=[2011-01-01 09:00, 2011-01-01 10:00, 2011-01-01 11:00, 2011-01-01 12:00, 2011-01-01 13:00], ordered=False, dtype='category')""" + self.assertEqual(repr(i), exp) + + i = pd.CategoricalIndex(pd.Categorical(idx.append(idx))) + exp = """CategoricalIndex(['2011-01-01 09:00', '2011-01-01 10:00', '2011-01-01 11:00', + '2011-01-01 12:00', '2011-01-01 13:00', '2011-01-01 09:00', + '2011-01-01 10:00', '2011-01-01 11:00', '2011-01-01 12:00', + '2011-01-01 13:00'], + categories=[2011-01-01 09:00, 2011-01-01 10:00, 2011-01-01 11:00, 2011-01-01 12:00, 2011-01-01 13:00], ordered=False, dtype='category')""" + self.assertEqual(repr(i), exp) + + idx = pd.period_range('2011-01', freq='M', periods=5) + i = pd.CategoricalIndex(pd.Categorical(idx)) + exp = """CategoricalIndex(['2011-01', '2011-02', '2011-03', '2011-04', '2011-05'], categories=[2011-01, 2011-02, 2011-03, 2011-04, 2011-05], ordered=False, dtype='category')""" + self.assertEqual(repr(i), exp) + + def test_categorical_index_repr_period_ordered(self): + idx = pd.period_range('2011-01-01 09:00', freq='H', periods=5) + i = pd.CategoricalIndex(pd.Categorical(idx, ordered=True)) + exp = """CategoricalIndex(['2011-01-01 09:00', '2011-01-01 10:00', '2011-01-01 11:00', + '2011-01-01 12:00', '2011-01-01 13:00'], + categories=[2011-01-01 09:00, 2011-01-01 10:00, 2011-01-01 11:00, 2011-01-01 12:00, 2011-01-01 13:00], ordered=True, dtype='category')""" + self.assertEqual(repr(i), exp) + + idx = pd.period_range('2011-01', freq='M', periods=5) + i = pd.CategoricalIndex(pd.Categorical(idx, ordered=True)) + exp = """CategoricalIndex(['2011-01', '2011-02', '2011-03', '2011-04', '2011-05'], categories=[2011-01, 2011-02, 2011-03, 2011-04, 2011-05], ordered=True, dtype='category')""" + self.assertEqual(repr(i), exp) + + def test_categorical_index_repr_timedelta(self): + idx = pd.timedelta_range('1 days', periods=5) + i = pd.CategoricalIndex(pd.Categorical(idx)) + exp = """CategoricalIndex(['1 days', '2 days', '3 days', '4 days', '5 days'], categories=[1 days 00:00:00, 2 days 00:00:00, 3 days 00:00:00, 4 days 00:00:00, 5 days 00:00:00], ordered=False, dtype='category')""" + self.assertEqual(repr(i), exp) + + idx = pd.timedelta_range('1 hours', periods=10) + i = pd.CategoricalIndex(pd.Categorical(idx)) + exp = """CategoricalIndex(['0 days 01:00:00', '1 days 01:00:00', '2 days 01:00:00', + '3 days 01:00:00', '4 days 01:00:00', '5 days 01:00:00', + '6 days 01:00:00', '7 days 01:00:00', '8 days 01:00:00', + '9 days 01:00:00'], + categories=[0 days 01:00:00, 1 days 01:00:00, 2 days 01:00:00, 3 days 01:00:00, 4 days 01:00:00, 5 days 01:00:00, 6 days 01:00:00, 7 days 01:00:00, ...], ordered=False, dtype='category')""" + self.assertEqual(repr(i), exp) + + def test_categorical_index_repr_timedelta_ordered(self): + idx = pd.timedelta_range('1 days', periods=5) + i = pd.CategoricalIndex(pd.Categorical(idx, ordered=True)) + exp = """CategoricalIndex(['1 days', '2 days', '3 days', '4 days', '5 days'], categories=[1 days 00:00:00, 2 days 00:00:00, 3 days 00:00:00, 4 days 00:00:00, 5 days 00:00:00], ordered=True, dtype='category')""" + self.assertEqual(repr(i), exp) + + idx = pd.timedelta_range('1 hours', periods=10) + i = pd.CategoricalIndex(pd.Categorical(idx, ordered=True)) + exp = """CategoricalIndex(['0 days 01:00:00', '1 days 01:00:00', '2 days 01:00:00', + '3 days 01:00:00', '4 days 01:00:00', '5 days 01:00:00', + '6 days 01:00:00', '7 days 01:00:00', '8 days 01:00:00', + '9 days 01:00:00'], + categories=[0 days 01:00:00, 1 days 01:00:00, 2 days 01:00:00, 3 days 01:00:00, 4 days 01:00:00, 5 days 01:00:00, 6 days 01:00:00, 7 days 01:00:00, ...], ordered=True, dtype='category')""" + self.assertEqual(repr(i), exp) + + def test_categorical_frame(self): + # normal DataFrame + dt = pd.date_range('2011-01-01 09:00', freq='H', periods=5, tz='US/Eastern') + p = pd.period_range('2011-01', freq='M', periods=5) + df = pd.DataFrame({'dt': dt, 'p': p}) + exp = """ dt p +0 2011-01-01 09:00:00-05:00 2011-01 +1 2011-01-01 10:00:00-05:00 2011-02 +2 2011-01-01 11:00:00-05:00 2011-03 +3 2011-01-01 12:00:00-05:00 2011-04 +4 2011-01-01 13:00:00-05:00 2011-05""" + + df = pd.DataFrame({'dt': pd.Categorical(dt), 'p': pd.Categorical(p)}) + self.assertEqual(repr(df), exp) + def test_info(self): # make sure it works @@ -2068,7 +2707,7 @@ def test_slicing_and_getting_ops(self): # row res_row = df.iloc[2,:] tm.assert_series_equal(res_row, exp_row) - tm.assert_isinstance(res_row["cats"], compat.string_types) + tm.assertIsInstance(res_row["cats"], compat.string_types) # col res_col = df.iloc[:,0] @@ -2088,7 +2727,7 @@ def test_slicing_and_getting_ops(self): # row res_row = df.loc["j",:] tm.assert_series_equal(res_row, exp_row) - tm.assert_isinstance(res_row["cats"], compat.string_types) + tm.assertIsInstance(res_row["cats"], compat.string_types) # col res_col = df.loc[:,"cats"] @@ -2109,7 +2748,7 @@ def test_slicing_and_getting_ops(self): # row res_row = df.ix["j",:] tm.assert_series_equal(res_row, exp_row) - tm.assert_isinstance(res_row["cats"], compat.string_types) + tm.assertIsInstance(res_row["cats"], compat.string_types) # col res_col = df.ix[:,"cats"] @@ -2141,27 +2780,27 @@ def test_slicing_and_getting_ops(self): self.assertEqual(res_val, exp_val) # i : int, slice, or sequence of integers - res_row = df.irow(2) + res_row = df.iloc[2] tm.assert_series_equal(res_row, exp_row) - tm.assert_isinstance(res_row["cats"], compat.string_types) + tm.assertIsInstance(res_row["cats"], compat.string_types) - res_df = df.irow(slice(2,4)) + res_df = df.iloc[slice(2,4)] tm.assert_frame_equal(res_df, exp_df) self.assertTrue(com.is_categorical_dtype(res_df["cats"])) - res_df = df.irow([2,3]) + res_df = df.iloc[[2,3]] tm.assert_frame_equal(res_df, exp_df) self.assertTrue(com.is_categorical_dtype(res_df["cats"])) - res_col = df.icol(0) + res_col = df.iloc[:,0] tm.assert_series_equal(res_col, exp_col) self.assertTrue(com.is_categorical_dtype(res_col)) - res_df = df.icol(slice(0,2)) + res_df = df.iloc[:,slice(0,2)] tm.assert_frame_equal(res_df, df) self.assertTrue(com.is_categorical_dtype(res_df["cats"])) - res_df = df.icol([0,1]) + res_df = df.iloc[:,[0,1]] tm.assert_frame_equal(res_df, df) self.assertTrue(com.is_categorical_dtype(res_df["cats"])) @@ -2182,8 +2821,8 @@ def test_slicing_doc_examples(self): tm.assert_series_equal(result, expected) result = df.loc["h":"j","cats"] - expected = Series(Categorical(['a','b','b'], name='cats', - categories=['a','b','c']), index=['h','i','j']) + expected = Series(Categorical(['a','b','b'], + categories=['a','b','c']), index=['h','i','j'], name='cats') tm.assert_series_equal(result, expected) result = df.ix["h":"j",0:1] @@ -2883,7 +3522,7 @@ def test_to_records(self): # this coerces result = df.to_records() expected = np.rec.array([(0, 'a'), (1, 'b'), (2, 'c')], - dtype=[('index', '""" self.assertEqual(result, expected) + df.index = Index(df.index.values, name='idx') + result = df.to_html(index=False) + self.assertEqual(result, expected) + def test_to_html_multiindex_sparsify_false_multi_sparse(self): with option_context('display.multi_sparse', False): index = MultiIndex.from_arrays([[0, 0, 1, 1], [0, 1, 0, 1]], @@ -990,7 +994,7 @@ def test_to_html_truncate(self):
    footAfootB

    20 rows × 20 columns

    '''.format(div_style) - if sys.version_info[0] < 3: + if compat.PY2: expected = expected.decode('utf-8') self.assertEqual(result, expected) @@ -1106,7 +1110,7 @@ def test_to_html_truncate_multi_index(self):

    8 rows × 8 columns

    '''.format(div_style) - if sys.version_info[0] < 3: + if compat.PY2: expected = expected.decode('utf-8') self.assertEqual(result, expected) @@ -1216,7 +1220,7 @@ def test_to_html_truncate_multi_index_sparse_off(self):

    8 rows × 8 columns

    '''.format(div_style) - if sys.version_info[0] < 3: + if compat.PY2: expected = expected.decode('utf-8') self.assertEqual(result, expected) @@ -1470,7 +1474,7 @@ def test_to_string(self): self.assertIsNone(retval) self.assertEqual(buf.getvalue(), s) - tm.assert_isinstance(s, compat.string_types) + tm.assertIsInstance(s, compat.string_types) # print in right order result = biggie.to_string(columns=['B', 'A'], col_space=17, @@ -1523,7 +1527,7 @@ def test_to_string_no_index(self): def test_to_string_float_formatting(self): self.reset_display_options() - fmt.set_option('display.precision', 6, 'display.column_space', + fmt.set_option('display.precision', 5, 'display.column_space', 12, 'display.notebook_repr_html', False) df = DataFrame({'x': [0, 0.25, 3456.000, 12e+45, 1.64e+6, @@ -1554,7 +1558,7 @@ def test_to_string_float_formatting(self): self.assertEqual(df_s, expected) self.reset_display_options() - self.assertEqual(get_option("display.precision"), 7) + self.assertEqual(get_option("display.precision"), 6) df = DataFrame({'x': [1e9, 0.2512]}) df_s = df.to_string() @@ -1719,7 +1723,7 @@ def test_to_html(self): self.assertIsNone(retval) self.assertEqual(buf.getvalue(), s) - tm.assert_isinstance(s, compat.string_types) + tm.assertIsInstance(s, compat.string_types) biggie.to_html(columns=['B', 'A'], col_space=17) biggie.to_html(columns=['B', 'A'], @@ -1922,15 +1926,195 @@ def test_to_html_index(self): 'C': ['one', 'two', np.NaN]}, columns=['A', 'B', 'C'], index=index) + expected_with_index = ('\n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + '
    ABC
    foo11.2one
    bar23.4two
    baz35.6NaN
    ') + self.assertEqual(df.to_html(), expected_with_index) + + expected_without_index = ('\n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + '
    ABC
    11.2one
    23.4two
    35.6NaN
    ') result = df.to_html(index=False) for i in index: self.assertNotIn(i, result) + self.assertEqual(result, expected_without_index) + df.index = Index(['foo', 'bar', 'baz'], name='idx') + expected_with_index = ('\n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + '
    ABC
    idx
    foo11.2one
    bar23.4two
    baz35.6NaN
    ') + self.assertEqual(df.to_html(), expected_with_index) + self.assertEqual(df.to_html(index=False), expected_without_index) tuples = [('foo', 'car'), ('foo', 'bike'), ('bar', 'car')] df.index = MultiIndex.from_tuples(tuples) + + expected_with_index = ('\n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + '
    ABC
    foocar11.2one
    bike23.4two
    barcar35.6NaN
    ') + self.assertEqual(df.to_html(), expected_with_index) + result = df.to_html(index=False) for i in ['foo', 'bar', 'car', 'bike']: self.assertNotIn(i, result) + # must be the same result as normal index + self.assertEqual(result, expected_without_index) + + df.index = MultiIndex.from_tuples(tuples, names=['idx1', 'idx2']) + expected_with_index = ('\n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + '
    ABC
    idx1idx2
    foocar11.2one
    bike23.4two
    barcar35.6NaN
    ') + self.assertEqual(df.to_html(), expected_with_index) + self.assertEqual(df.to_html(index=False), expected_without_index) def test_repr_html(self): self.frame._repr_html_() @@ -3055,7 +3239,7 @@ def test_output_significant_digits(self): # Issue #9764 # In case default display precision changes: - with pd.option_context('display.precision', 7): + with pd.option_context('display.precision', 6): # DataFrame example from issue #9764 d=pd.DataFrame({'col1':[9.999e-8, 1e-7, 1.0001e-7, 2e-7, 4.999e-7, 5e-7, 5.0001e-7, 6e-7, 9.999e-7, 1e-6, 1.0001e-6, 2e-6, 4.999e-6, 5e-6, 5.0001e-6, 6e-6]}) @@ -3070,6 +3254,17 @@ def test_output_significant_digits(self): for (start, stop), v in expected_output.items(): self.assertEqual(str(d[start:stop]), v) + def test_too_long(self): + # GH 10451 + with pd.option_context('display.precision', 4): + # need both a number > 1e8 and something that normally formats to having length > display.precision + 6 + df = pd.DataFrame(dict(x=[12345.6789])) + self.assertEqual(str(df), ' x\n0 12345.6789') + df = pd.DataFrame(dict(x=[2e8])) + self.assertEqual(str(df), ' x\n0 200000000') + df = pd.DataFrame(dict(x=[12345.6789, 2e8])) + self.assertEqual(str(df), ' x\n0 1.2346e+04\n1 2.0000e+08') + class TestRepr_timedelta64(tm.TestCase): diff --git a/pandas/tests/test_frame.py b/pandas/tests/test_frame.py index 4b1954a3be64e..7b6243f391a19 100644 --- a/pandas/tests/test_frame.py +++ b/pandas/tests/test_frame.py @@ -3,7 +3,7 @@ from __future__ import print_function # pylint: disable-msg=W0612,E1101 from copy import deepcopy -from datetime import datetime, timedelta, time +from datetime import datetime, timedelta, time, date import sys import operator import re @@ -24,7 +24,6 @@ from numpy.random import randn import numpy as np import numpy.ma as ma -from numpy.testing import assert_array_equal import numpy.ma.mrecords as mrecords import pandas.core.nanops as nanops @@ -40,12 +39,14 @@ from pandas.util.misc import is_little_endian from pandas.util.testing import (assert_almost_equal, + assert_numpy_array_equal, assert_series_equal, assert_frame_equal, assertRaisesRegexp, assertRaises, makeCustomDataframe as mkdf, - ensure_clean) + ensure_clean, + SubclassedDataFrame) from pandas.core.indexing import IndexingError from pandas.core.common import PandasError @@ -124,7 +125,7 @@ def test_getitem(self): df['@awesome_domain'] = ad self.assertRaises(KeyError, df.__getitem__, 'df["$10"]') res = df['@awesome_domain'] - assert_array_equal(ad, res.values) + assert_numpy_array_equal(ad, res.values) def test_getitem_dupe_cols(self): df = DataFrame([[1, 2, 3], [4, 5, 6]], columns=['a', 'a', 'b']) @@ -1465,7 +1466,7 @@ def f(): self.assertTrue(result.values.all()) self.assertTrue((cp.iloc[0:1] == df.iloc[0:1]).values.all()) - warnings.filterwarnings(action='ignore', category=FutureWarning) + warnings.filterwarnings(action='default', category=FutureWarning) cp = df.copy() cp.iloc[4:5] = 0 @@ -1780,16 +1781,20 @@ def test_single_element_ix_dont_upcast(self): def test_irow(self): df = DataFrame(np.random.randn(10, 4), index=lrange(0, 20, 2)) - result = df.irow(1) + # 10711, deprecated + with tm.assert_produces_warning(FutureWarning): + df.irow(1) + + result = df.iloc[1] exp = df.ix[2] assert_series_equal(result, exp) - result = df.irow(2) + result = df.iloc[2] exp = df.ix[4] assert_series_equal(result, exp) # slice - result = df.irow(slice(4, 8)) + result = df.iloc[slice(4, 8)] expected = df.ix[8:14] assert_frame_equal(result, expected) @@ -1803,23 +1808,28 @@ def f(): assert_series_equal(df[2], exp_col) # list of integers - result = df.irow([1, 2, 4, 6]) + result = df.iloc[[1, 2, 4, 6]] expected = df.reindex(df.index[[1, 2, 4, 6]]) assert_frame_equal(result, expected) def test_icol(self): + df = DataFrame(np.random.randn(4, 10), columns=lrange(0, 20, 2)) - result = df.icol(1) + # 10711, deprecated + with tm.assert_produces_warning(FutureWarning): + df.icol(1) + + result = df.iloc[:, 1] exp = df.ix[:, 2] assert_series_equal(result, exp) - result = df.icol(2) + result = df.iloc[:, 2] exp = df.ix[:, 4] assert_series_equal(result, exp) # slice - result = df.icol(slice(4, 8)) + result = df.iloc[:, slice(4, 8)] expected = df.ix[:, 8:14] assert_frame_equal(result, expected) @@ -1831,23 +1841,25 @@ def f(): self.assertTrue((df[8] == 0).all()) # list of integers - result = df.icol([1, 2, 4, 6]) + result = df.iloc[:, [1, 2, 4, 6]] expected = df.reindex(columns=df.columns[[1, 2, 4, 6]]) assert_frame_equal(result, expected) def test_irow_icol_duplicates(self): + # 10711, deprecated + df = DataFrame(np.random.rand(3, 3), columns=list('ABC'), index=list('aab')) - result = df.irow(0) + result = df.iloc[0] result2 = df.ix[0] - tm.assert_isinstance(result, Series) + tm.assertIsInstance(result, Series) assert_almost_equal(result.values, df.values[0]) assert_series_equal(result, result2) - result = df.T.icol(0) + result = df.T.iloc[:, 0] result2 = df.T.ix[:, 0] - tm.assert_isinstance(result, Series) + tm.assertIsInstance(result, Series) assert_almost_equal(result.values, df.values[0]) assert_series_equal(result, result2) @@ -1855,34 +1867,39 @@ def test_irow_icol_duplicates(self): df = DataFrame(np.random.randn(3, 3), columns=[['i', 'i', 'j'], ['A', 'A', 'B']], index=[['i', 'i', 'j'], ['X', 'X', 'Y']]) - rs = df.irow(0) + rs = df.iloc[0] xp = df.ix[0] assert_series_equal(rs, xp) - rs = df.icol(0) + rs = df.iloc[:, 0] xp = df.T.ix[0] assert_series_equal(rs, xp) - rs = df.icol([0]) + rs = df.iloc[:, [0]] xp = df.ix[:, [0]] assert_frame_equal(rs, xp) # #2259 df = DataFrame([[1, 2, 3], [4, 5, 6]], columns=[1, 1, 2]) - result = df.icol([0]) + result = df.iloc[:, [0]] expected = df.take([0], axis=1) assert_frame_equal(result, expected) def test_icol_sparse_propegate_fill_value(self): from pandas.sparse.api import SparseDataFrame df = SparseDataFrame({'A': [999, 1]}, default_fill_value=999) - self.assertTrue(len(df['A'].sp_values) == len(df.icol(0).sp_values)) + self.assertTrue(len(df['A'].sp_values) == len(df.iloc[:, 0].sp_values)) def test_iget_value(self): + # 10711 deprecated + + with tm.assert_produces_warning(FutureWarning): + self.frame.iget_value(0,0) + for i, row in enumerate(self.frame.index): for j, col in enumerate(self.frame.columns): - result = self.frame.iget_value(i, j) - expected = self.frame.get_value(row, col) + result = self.frame.iat[i,j] + expected = self.frame.at[row, col] assert_almost_equal(result, expected) def test_nested_exception(self): @@ -1912,6 +1929,12 @@ def test_reindex_methods(self): actual = df.reindex(target, method=method) assert_frame_equal(expected, actual) + actual = df.reindex_like(df, method=method, tolerance=0) + assert_frame_equal(df, actual) + + actual = df.reindex(target, method=method, tolerance=1) + assert_frame_equal(expected, actual) + e2 = expected[::-1] actual = df.reindex(target[::-1], method=method) assert_frame_equal(e2, actual) @@ -1927,6 +1950,10 @@ def test_reindex_methods(self): actual = df[::-1].reindex(target, method=switched_method) assert_frame_equal(expected, actual) + expected = pd.DataFrame({'x': [0, 1, 1, np.nan]}, index=target) + actual = df.reindex(target, method='nearest', tolerance=0.2) + assert_frame_equal(expected, actual) + def test_non_monotonic_reindex_methods(self): dr = pd.date_range('2013-08-01', periods=6, freq='B') data = np.random.randn(6,1) @@ -2203,7 +2230,6 @@ class TestDataFrame(tm.TestCase, CheckIndexing, def setUp(self): import warnings - warnings.filterwarnings(action='ignore', category=FutureWarning) self.frame = _frame.copy() self.frame2 = _frame2.copy() @@ -2439,7 +2465,7 @@ def test_set_index_cast_datetimeindex(self): 'B': np.random.randn(1000)}) idf = df.set_index('A') - tm.assert_isinstance(idf.index, DatetimeIndex) + tm.assertIsInstance(idf.index, DatetimeIndex) # don't cast a DatetimeIndex WITH a tz, leave as object # GH 6032 @@ -2602,7 +2628,7 @@ def test_constructor_list_frames(self): self.assertEqual(result.shape, (1,0)) result = DataFrame([DataFrame(dict(A = lrange(5)))]) - tm.assert_isinstance(result.iloc[0,0], DataFrame) + tm.assertIsInstance(result.iloc[0,0], DataFrame) def test_constructor_mixed_dtypes(self): @@ -2922,10 +2948,10 @@ def test_constructor_dict_cast(self): def test_constructor_dict_dont_upcast(self): d = {'Col1': {'Row1': 'A String', 'Row2': np.nan}} df = DataFrame(d) - tm.assert_isinstance(df['Col1']['Row2'], float) + tm.assertIsInstance(df['Col1']['Row2'], float) dm = DataFrame([[1, 2], ['a', 'b']], index=[1, 2], columns=[1, 2]) - tm.assert_isinstance(dm[1][1], int) + tm.assertIsInstance(dm[1][1], int) def test_constructor_dict_of_tuples(self): # GH #1491 @@ -3575,7 +3601,7 @@ def test_constructor_from_items(self): columns=self.mixed_frame.columns, orient='index') assert_frame_equal(recons, self.mixed_frame) - tm.assert_isinstance(recons['foo'][0], tuple) + tm.assertIsInstance(recons['foo'][0], tuple) rs = DataFrame.from_items([('A', [1, 2, 3]), ('B', [4, 5, 6])], orient='index', columns=['one', 'two', 'three']) @@ -3616,6 +3642,20 @@ def test_constructor_column_duplicates(self): [('a', [8]), ('a', [5]), ('b', [6])], columns=['b', 'a', 'a']) + def test_constructor_empty_with_string_dtype(self): + # GH 9428 + expected = DataFrame(index=[0, 1], columns=[0, 1], dtype=object) + + df = DataFrame(index=[0, 1], columns=[0, 1], dtype=str) + assert_frame_equal(df, expected) + df = DataFrame(index=[0, 1], columns=[0, 1], dtype=np.str_) + assert_frame_equal(df, expected) + df = DataFrame(index=[0, 1], columns=[0, 1], dtype=np.unicode_) + assert_frame_equal(df, expected) + df = DataFrame(index=[0, 1], columns=[0, 1], dtype='U5') + assert_frame_equal(df, expected) + + def test_column_dups_operations(self): def check(result, expected=None): @@ -4247,6 +4287,16 @@ def test_datetimelike_setitem_with_inference(self): expected = Series([np.dtype('timedelta64[ns]')]*6+[np.dtype('datetime64[ns]')]*2,index=list('ABCDEFGH')) assert_series_equal(result,expected) + def test_setitem_datetime_coercion(self): + # GH 1048 + df = pd.DataFrame({'c': [pd.Timestamp('2010-10-01')]*3}) + df.loc[0:1, 'c'] = np.datetime64('2008-08-08') + self.assertEqual(pd.Timestamp('2008-08-08'), df.loc[0, 'c']) + self.assertEqual(pd.Timestamp('2008-08-08'), df.loc[1, 'c']) + df.loc[2, 'c'] = date(2005, 5, 5) + self.assertEqual(pd.Timestamp('2005-05-05'), df.loc[2, 'c']) + + def test_new_empty_index(self): df1 = DataFrame(randn(0, 3)) df2 = DataFrame(randn(0, 3)) @@ -4368,7 +4418,7 @@ def test_astype_str(self): def test_array_interface(self): result = np.sqrt(self.frame) - tm.assert_isinstance(result, type(self.frame)) + tm.assertIsInstance(result, type(self.frame)) self.assertIs(result.index, self.frame.index) self.assertIs(result.columns, self.frame.columns) @@ -4639,13 +4689,13 @@ def test_from_records_empty(self): def test_from_records_empty_with_nonempty_fields_gh3682(self): a = np.array([(1, 2)], dtype=[('id', np.int64), ('value', np.int64)]) df = DataFrame.from_records(a, index='id') - assert_array_equal(df.index, Index([1], name='id')) + assert_numpy_array_equal(df.index, Index([1], name='id')) self.assertEqual(df.index.name, 'id') - assert_array_equal(df.columns, Index(['value'])) + assert_numpy_array_equal(df.columns, Index(['value'])) b = np.array([], dtype=[('id', np.int64), ('value', np.int64)]) df = DataFrame.from_records(b, index='id') - assert_array_equal(df.index, Index([], name='id')) + assert_numpy_array_equal(df.index, Index([], name='id')) self.assertEqual(df.index.name, 'id') def test_from_records_with_datetimes(self): @@ -4709,6 +4759,33 @@ def test_join_str_datetime(self): self.assertEqual(len(tst.columns), 3) + def test_join_multiindex_leftright(self): + # GH 10741 + df1 = pd.DataFrame([['a', 'x', 0.471780], ['a','y', 0.774908], + ['a', 'z', 0.563634], ['b', 'x', -0.353756], + ['b', 'y', 0.368062], ['b', 'z', -1.721840], + ['c', 'x', 1], ['c', 'y', 2], ['c', 'z', 3]], + columns=['first', 'second', 'value1']).set_index(['first', 'second']) + df2 = pd.DataFrame([['a', 10], ['b', 20]], columns=['first', 'value2']).set_index(['first']) + + exp = pd.DataFrame([[0.471780, 10], [0.774908, 10], [0.563634, 10], + [-0.353756, 20], [0.368062, 20], [-1.721840, 20], + [1.000000, np.nan], [2.000000, np.nan], [3.000000, np.nan]], + index=df1.index, columns=['value1', 'value2']) + + # these must be the same results (but columns are flipped) + tm.assert_frame_equal(df1.join(df2, how='left'), exp) + tm.assert_frame_equal(df2.join(df1, how='right'), exp[['value2', 'value1']]) + + exp_idx = pd.MultiIndex.from_product([['a', 'b'], ['x', 'y', 'z']], + names=['first', 'second']) + exp = pd.DataFrame([[0.471780, 10], [0.774908, 10], [0.563634, 10], + [-0.353756, 20], [0.368062, 20], [-1.721840, 20]], + index=exp_idx, columns=['value1', 'value2']) + + tm.assert_frame_equal(df1.join(df2, how='right'), exp) + tm.assert_frame_equal(df2.join(df1, how='left'), exp[['value2', 'value1']]) + def test_from_records_sequencelike(self): df = DataFrame({'A' : np.array(np.random.randn(6), dtype = np.float64), 'A1': np.array(np.random.randn(6), dtype = np.float64), @@ -4730,7 +4807,7 @@ def test_from_records_sequencelike(self): for i in range(len(df.index)): tup = [] for _, b in compat.iteritems(blocks): - tup.extend(b.irow(i).values) + tup.extend(b.iloc[i].values) tuples.append(tuple(tup)) recarray = np.array(tuples, dtype=dtypes).view(np.recarray) @@ -5134,7 +5211,7 @@ def test_itertuples(self): 'ints': lrange(5)}, columns=['floats', 'ints']) for tup in df.itertuples(index=False): - tm.assert_isinstance(tup[1], np.integer) + tm.assertIsInstance(tup[1], np.integer) df = DataFrame(data={"a": [1, 2, 3], "b": [4, 5, 6]}) dfaa = df[['a', 'a']] @@ -5596,9 +5673,9 @@ def test_arith_flex_frame(self): result = self.frame[:0].add(self.frame) assert_frame_equal(result, self.frame * np.nan) with assertRaisesRegexp(NotImplementedError, 'fill_value'): - self.frame.add(self.frame.irow(0), fill_value=3) + self.frame.add(self.frame.iloc[0], fill_value=3) with assertRaisesRegexp(NotImplementedError, 'fill_value'): - self.frame.add(self.frame.irow(0), axis='index', fill_value=3) + self.frame.add(self.frame.iloc[0], axis='index', fill_value=3) def test_binary_ops_align(self): @@ -6083,7 +6160,7 @@ def test_boolean_comparison(self): assert_frame_equal(result,expected) result = df.values>b - assert_array_equal(result,expected.values) + assert_numpy_array_equal(result,expected.values) result = df>l assert_frame_equal(result,expected) @@ -6095,7 +6172,7 @@ def test_boolean_comparison(self): assert_frame_equal(result,expected) result = df.values>b_r - assert_array_equal(result,expected.values) + assert_numpy_array_equal(result,expected.values) self.assertRaises(ValueError, df.__gt__, b_c) self.assertRaises(ValueError, df.values.__gt__, b_c) @@ -6115,7 +6192,7 @@ def test_boolean_comparison(self): assert_frame_equal(result,expected) result = df.values == b_r - assert_array_equal(result,expected.values) + assert_numpy_array_equal(result,expected.values) self.assertRaises(ValueError, lambda : df == b_c) self.assertFalse((df.values == b_c)) @@ -6149,6 +6226,34 @@ def test_equals_different_blocks(self): self.assertTrue(df0.equals(df1)) self.assertTrue(df1.equals(df0)) + def test_copy_blocks(self): + # API/ENH 9607 + df = DataFrame(self.frame, copy=True) + column = df.columns[0] + + # use the default copy=True, change a column + blocks = df.as_blocks() + for dtype, _df in blocks.items(): + if column in _df: + _df.ix[:, column] = _df[column] + 1 + + # make sure we did not change the original DataFrame + self.assertFalse(_df[column].equals(df[column])) + + def test_no_copy_blocks(self): + # API/ENH 9607 + df = DataFrame(self.frame, copy=True) + column = df.columns[0] + + # use the copy=False, change a column + blocks = df.as_blocks(copy=False) + for dtype, _df in blocks.items(): + if column in _df: + _df.ix[:, column] = _df[column] + 1 + + # make sure we did change the original DataFrame + self.assertTrue(_df[column].equals(df[column])) + def test_to_csv_from_csv(self): pname = '__tmp_to_csv_from_csv__' @@ -6327,7 +6432,7 @@ def _to_uni(x): # labeling them dupe.1,dupe.2, etc'. monkey patch columns recons.columns = df.columns if rnlvl and not cnlvl: - delta_lvl = [recons.icol(i).values for i in range(rnlvl-1)] + delta_lvl = [recons.iloc[:, i].values for i in range(rnlvl-1)] ix=MultiIndex.from_arrays([list(recons.index)]+delta_lvl) recons.index = ix recons = recons.iloc[:,rnlvl-1:] @@ -6405,7 +6510,8 @@ def make_dtnat_arr(n,nnat=None): with ensure_clean('.csv') as pth: df=DataFrame(dict(a=s1,b=s2)) df.to_csv(pth,chunksize=chunksize) - recons = DataFrame.from_csv(pth).convert_objects('coerce') + recons = DataFrame.from_csv(pth).convert_objects(datetime=True, + coerce=True) assert_frame_equal(df, recons,check_names=False,check_less_precise=True) for ncols in [4]: @@ -7115,7 +7221,7 @@ def test_dtypes(self): def test_convert_objects(self): oops = self.mixed_frame.T.T - converted = oops.convert_objects() + converted = oops.convert_objects(datetime=True) assert_frame_equal(converted, self.mixed_frame) self.assertEqual(converted['A'].dtype, np.float64) @@ -7128,7 +7234,8 @@ def test_convert_objects(self): self.mixed_frame['J'] = '1.' self.mixed_frame['K'] = '1' self.mixed_frame.ix[0:5,['J','K']] = 'garbled' - converted = self.mixed_frame.convert_objects(convert_numeric=True) + converted = self.mixed_frame.convert_objects(datetime=True, + numeric=True) self.assertEqual(converted['H'].dtype, 'float64') self.assertEqual(converted['I'].dtype, 'int64') self.assertEqual(converted['J'].dtype, 'float64') @@ -7150,14 +7257,14 @@ def test_convert_objects(self): # mixed in a single column df = DataFrame(dict(s = Series([1, 'na', 3 ,4]))) - result = df.convert_objects(convert_numeric=True) + result = df.convert_objects(datetime=True, numeric=True) expected = DataFrame(dict(s = Series([1, np.nan, 3 ,4]))) assert_frame_equal(result, expected) def test_convert_objects_no_conversion(self): mixed1 = DataFrame( {'a': [1, 2, 3], 'b': [4.0, 5, 6], 'c': ['x', 'y', 'z']}) - mixed2 = mixed1.convert_objects() + mixed2 = mixed1.convert_objects(datetime=True) assert_frame_equal(mixed1, mixed2) def test_append_series_dict(self): @@ -7304,10 +7411,10 @@ def test_asfreq_datetimeindex(self): index=[datetime(2011, 11, 1), datetime(2011, 11, 2), datetime(2011, 11, 3)]) df = df.asfreq('B') - tm.assert_isinstance(df.index, DatetimeIndex) + tm.assertIsInstance(df.index, DatetimeIndex) ts = df['A'].asfreq('B') - tm.assert_isinstance(ts.index, DatetimeIndex) + tm.assertIsInstance(ts.index, DatetimeIndex) def test_at_time_between_time_datetimeindex(self): index = date_range("2012-01-01", "2012-01-05", freq='30min') @@ -7791,10 +7898,21 @@ def test_drop_duplicates(self): expected = df[:2] assert_frame_equal(result, expected) - result = df.drop_duplicates('AAA', take_last=True) + result = df.drop_duplicates('AAA', keep='last') expected = df.ix[[6, 7]] assert_frame_equal(result, expected) + result = df.drop_duplicates('AAA', keep=False) + expected = df.ix[[]] + assert_frame_equal(result, expected) + self.assertEqual(len(result), 0) + + # deprecate take_last + with tm.assert_produces_warning(FutureWarning): + result = df.drop_duplicates('AAA', take_last=True) + expected = df.ix[[6, 7]] + assert_frame_equal(result, expected) + # multi column expected = df.ix[[0, 1, 2, 3]] result = df.drop_duplicates(np.array(['AAA', 'B'])) @@ -7802,7 +7920,17 @@ def test_drop_duplicates(self): result = df.drop_duplicates(['AAA', 'B']) assert_frame_equal(result, expected) - result = df.drop_duplicates(('AAA', 'B'), take_last=True) + result = df.drop_duplicates(('AAA', 'B'), keep='last') + expected = df.ix[[0, 5, 6, 7]] + assert_frame_equal(result, expected) + + result = df.drop_duplicates(('AAA', 'B'), keep=False) + expected = df.ix[[0]] + assert_frame_equal(result, expected) + + # deprecate take_last + with tm.assert_produces_warning(FutureWarning): + result = df.drop_duplicates(('AAA', 'B'), take_last=True) expected = df.ix[[0, 5, 6, 7]] assert_frame_equal(result, expected) @@ -7814,8 +7942,53 @@ def test_drop_duplicates(self): expected = df2.drop_duplicates(['AAA', 'B']) assert_frame_equal(result, expected) - result = df2.drop_duplicates(take_last=True) - expected = df2.drop_duplicates(['AAA', 'B'], take_last=True) + result = df2.drop_duplicates(keep='last') + expected = df2.drop_duplicates(['AAA', 'B'], keep='last') + assert_frame_equal(result, expected) + + result = df2.drop_duplicates(keep=False) + expected = df2.drop_duplicates(['AAA', 'B'], keep=False) + assert_frame_equal(result, expected) + + # deprecate take_last + with tm.assert_produces_warning(FutureWarning): + result = df2.drop_duplicates(take_last=True) + with tm.assert_produces_warning(FutureWarning): + expected = df2.drop_duplicates(['AAA', 'B'], take_last=True) + assert_frame_equal(result, expected) + + def test_drop_duplicates_for_take_all(self): + df = DataFrame({'AAA': ['foo', 'bar', 'baz', 'bar', + 'foo', 'bar', 'qux', 'foo'], + 'B': ['one', 'one', 'two', 'two', + 'two', 'two', 'one', 'two'], + 'C': [1, 1, 2, 2, 2, 2, 1, 2], + 'D': lrange(8)}) + + # single column + result = df.drop_duplicates('AAA') + expected = df.iloc[[0, 1, 2, 6]] + assert_frame_equal(result, expected) + + result = df.drop_duplicates('AAA', keep='last') + expected = df.iloc[[2, 5, 6, 7]] + assert_frame_equal(result, expected) + + result = df.drop_duplicates('AAA', keep=False) + expected = df.iloc[[2, 6]] + assert_frame_equal(result, expected) + + # multiple columns + result = df.drop_duplicates(['AAA', 'B']) + expected = df.iloc[[0, 1, 2, 3, 4, 6]] + assert_frame_equal(result, expected) + + result = df.drop_duplicates(['AAA', 'B'], keep='last') + expected = df.iloc[[0, 1, 2, 5, 6, 7]] + assert_frame_equal(result, expected) + + result = df.drop_duplicates(['AAA', 'B'], keep=False) + expected = df.iloc[[0, 1, 2, 6]] assert_frame_equal(result, expected) def test_drop_duplicates_deprecated_warning(self): @@ -7844,6 +8017,14 @@ def test_drop_duplicates_deprecated_warning(self): self.assertRaises(TypeError, df.drop_duplicates, kwargs={'subset': 'AAA', 'bad_arg': True}) + # deprecate take_last + # Raises warning + with tm.assert_produces_warning(FutureWarning): + result = df.drop_duplicates(take_last=False, subset='AAA') + assert_frame_equal(result, expected) + + self.assertRaises(ValueError, df.drop_duplicates, keep='invalid_name') + def test_drop_duplicates_tuple(self): df = DataFrame({('AA', 'AB'): ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'bar', 'foo'], @@ -7857,7 +8038,18 @@ def test_drop_duplicates_tuple(self): expected = df[:2] assert_frame_equal(result, expected) - result = df.drop_duplicates(('AA', 'AB'), take_last=True) + result = df.drop_duplicates(('AA', 'AB'), keep='last') + expected = df.ix[[6, 7]] + assert_frame_equal(result, expected) + + result = df.drop_duplicates(('AA', 'AB'), keep=False) + expected = df.ix[[]] # empty df + self.assertEqual(len(result), 0) + assert_frame_equal(result, expected) + + # deprecate take_last + with tm.assert_produces_warning(FutureWarning): + result = df.drop_duplicates(('AA', 'AB'), take_last=True) expected = df.ix[[6, 7]] assert_frame_equal(result, expected) @@ -7880,7 +8072,18 @@ def test_drop_duplicates_NA(self): expected = df.ix[[0, 2, 3]] assert_frame_equal(result, expected) - result = df.drop_duplicates('A', take_last=True) + result = df.drop_duplicates('A', keep='last') + expected = df.ix[[1, 6, 7]] + assert_frame_equal(result, expected) + + result = df.drop_duplicates('A', keep=False) + expected = df.ix[[]] # empty df + assert_frame_equal(result, expected) + self.assertEqual(len(result), 0) + + # deprecate take_last + with tm.assert_produces_warning(FutureWarning): + result = df.drop_duplicates('A', take_last=True) expected = df.ix[[1, 6, 7]] assert_frame_equal(result, expected) @@ -7889,7 +8092,17 @@ def test_drop_duplicates_NA(self): expected = df.ix[[0, 2, 3, 6]] assert_frame_equal(result, expected) - result = df.drop_duplicates(['A', 'B'], take_last=True) + result = df.drop_duplicates(['A', 'B'], keep='last') + expected = df.ix[[1, 5, 6, 7]] + assert_frame_equal(result, expected) + + result = df.drop_duplicates(['A', 'B'], keep=False) + expected = df.ix[[6]] + assert_frame_equal(result, expected) + + # deprecate take_last + with tm.assert_produces_warning(FutureWarning): + result = df.drop_duplicates(['A', 'B'], take_last=True) expected = df.ix[[1, 5, 6, 7]] assert_frame_equal(result, expected) @@ -7906,7 +8119,18 @@ def test_drop_duplicates_NA(self): expected = df[:2] assert_frame_equal(result, expected) - result = df.drop_duplicates('C', take_last=True) + result = df.drop_duplicates('C', keep='last') + expected = df.ix[[3, 7]] + assert_frame_equal(result, expected) + + result = df.drop_duplicates('C', keep=False) + expected = df.ix[[]] # empty df + assert_frame_equal(result, expected) + self.assertEqual(len(result), 0) + + # deprecate take_last + with tm.assert_produces_warning(FutureWarning): + result = df.drop_duplicates('C', take_last=True) expected = df.ix[[3, 7]] assert_frame_equal(result, expected) @@ -7915,10 +8139,54 @@ def test_drop_duplicates_NA(self): expected = df.ix[[0, 1, 2, 4]] assert_frame_equal(result, expected) - result = df.drop_duplicates(['C', 'B'], take_last=True) + result = df.drop_duplicates(['C', 'B'], keep='last') + expected = df.ix[[1, 3, 6, 7]] + assert_frame_equal(result, expected) + + result = df.drop_duplicates(['C', 'B'], keep=False) + expected = df.ix[[1]] + assert_frame_equal(result, expected) + + # deprecate take_last + with tm.assert_produces_warning(FutureWarning): + result = df.drop_duplicates(['C', 'B'], take_last=True) expected = df.ix[[1, 3, 6, 7]] assert_frame_equal(result, expected) + def test_drop_duplicates_NA_for_take_all(self): + # none + df = DataFrame({'A': [None, None, 'foo', 'bar', + 'foo', 'baz', 'bar', 'qux'], + 'C': [1.0, np.nan, np.nan, np.nan, 1., 2., 3, 1.]}) + + # single column + result = df.drop_duplicates('A') + expected = df.iloc[[0, 2, 3, 5, 7]] + assert_frame_equal(result, expected) + + result = df.drop_duplicates('A', keep='last') + expected = df.iloc[[1, 4, 5, 6, 7]] + assert_frame_equal(result, expected) + + result = df.drop_duplicates('A', keep=False) + expected = df.iloc[[5, 7]] + assert_frame_equal(result, expected) + + # nan + + # single column + result = df.drop_duplicates('C') + expected = df.iloc[[0, 1, 5, 6]] + assert_frame_equal(result, expected) + + result = df.drop_duplicates('C', keep='last') + expected = df.iloc[[3, 5, 6, 7]] + assert_frame_equal(result, expected) + + result = df.drop_duplicates('C', keep=False) + expected = df.iloc[[5, 6]] + assert_frame_equal(result, expected) + def test_drop_duplicates_inplace(self): orig = DataFrame({'A': ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'bar', 'foo'], @@ -7935,7 +8203,22 @@ def test_drop_duplicates_inplace(self): assert_frame_equal(result, expected) df = orig.copy() - df.drop_duplicates('A', take_last=True, inplace=True) + df.drop_duplicates('A', keep='last', inplace=True) + expected = orig.ix[[6, 7]] + result = df + assert_frame_equal(result, expected) + + df = orig.copy() + df.drop_duplicates('A', keep=False, inplace=True) + expected = orig.ix[[]] + result = df + assert_frame_equal(result, expected) + self.assertEqual(len(df), 0) + + # deprecate take_last + df = orig.copy() + with tm.assert_produces_warning(FutureWarning): + df.drop_duplicates('A', take_last=True, inplace=True) expected = orig.ix[[6, 7]] result = df assert_frame_equal(result, expected) @@ -7948,7 +8231,21 @@ def test_drop_duplicates_inplace(self): assert_frame_equal(result, expected) df = orig.copy() - df.drop_duplicates(['A', 'B'], take_last=True, inplace=True) + df.drop_duplicates(['A', 'B'], keep='last', inplace=True) + expected = orig.ix[[0, 5, 6, 7]] + result = df + assert_frame_equal(result, expected) + + df = orig.copy() + df.drop_duplicates(['A', 'B'], keep=False, inplace=True) + expected = orig.ix[[0]] + result = df + assert_frame_equal(result, expected) + + # deprecate take_last + df = orig.copy() + with tm.assert_produces_warning(FutureWarning): + df.drop_duplicates(['A', 'B'], take_last=True, inplace=True) expected = orig.ix[[0, 5, 6, 7]] result = df assert_frame_equal(result, expected) @@ -7964,8 +8261,23 @@ def test_drop_duplicates_inplace(self): assert_frame_equal(result, expected) df2 = orig2.copy() - df2.drop_duplicates(take_last=True, inplace=True) - expected = orig2.drop_duplicates(['A', 'B'], take_last=True) + df2.drop_duplicates(keep='last', inplace=True) + expected = orig2.drop_duplicates(['A', 'B'], keep='last') + result = df2 + assert_frame_equal(result, expected) + + df2 = orig2.copy() + df2.drop_duplicates(keep=False, inplace=True) + expected = orig2.drop_duplicates(['A', 'B'], keep=False) + result = df2 + assert_frame_equal(result, expected) + + # deprecate take_last + df2 = orig2.copy() + with tm.assert_produces_warning(FutureWarning): + df2.drop_duplicates(take_last=True, inplace=True) + with tm.assert_produces_warning(FutureWarning): + expected = orig2.drop_duplicates(['A', 'B'], take_last=True) result = df2 assert_frame_equal(result, expected) @@ -9354,7 +9666,7 @@ def test_xs_duplicates(self): df = DataFrame(randn(5, 2), index=['b', 'b', 'c', 'b', 'a']) cross = df.xs('c') - exp = df.irow(2) + exp = df.iloc[2] assert_series_equal(cross, exp) def test_xs_keep_level(self): @@ -9423,6 +9735,47 @@ def test_pivot_integer_bug(self): repr(result) self.assert_numpy_array_equal(result.columns, ['A', 'B']) + def test_pivot_index_none(self): + # gh-3962 + data = { + 'index': ['A', 'B', 'C', 'C', 'B', 'A'], + 'columns': ['One', 'One', 'One', 'Two', 'Two', 'Two'], + 'values': [1., 2., 3., 3., 2., 1.] + } + + frame = DataFrame(data).set_index('index') + result = frame.pivot(columns='columns', values='values') + expected = DataFrame({ + 'One': {'A': 1., 'B': 2., 'C': 3.}, + 'Two': {'A': 1., 'B': 2., 'C': 3.} + }) + + expected.index.name, expected.columns.name = 'index', 'columns' + assert_frame_equal(result, expected) + + # omit values + result = frame.pivot(columns='columns') + + expected.columns = pd.MultiIndex.from_tuples([('values', 'One'), + ('values', 'Two')], + names=[None, 'columns']) + expected.index.name = 'index' + assert_frame_equal(result, expected, check_names=False) + self.assertEqual(result.index.name, 'index',) + self.assertEqual(result.columns.names, (None, 'columns')) + expected.columns = expected.columns.droplevel(0) + + data = { + 'index': range(7), + 'columns': ['One', 'One', 'One', 'Two', 'Two', 'Two'], + 'values': [1., 2., 3., 3., 2., 1.] + } + + result = frame.pivot(columns='columns', values='values') + + expected.columns.name = 'columns' + assert_frame_equal(result, expected) + def test_reindex(self): newFrame = self.frame.reindex(self.ts1.index) @@ -9494,6 +9847,18 @@ def test_reindex_nan(self): df.index = df.index.astype('object') tm.assert_frame_equal(df.reindex(i), df.iloc[j]) + # GH10388 + df = pd.DataFrame({'other':['a', 'b', np.nan, 'c'], + 'date':['2015-03-22', np.nan, '2012-01-08', np.nan], + 'amount':[2, 3, 4, 5]}) + + df['date'] = pd.to_datetime(df.date) + df['delta'] = (pd.to_datetime('2015-06-18') - df['date']).shift(1) + + left = df.set_index(['delta', 'other', 'date']).reset_index() + right = df.reindex(columns=['delta', 'other', 'date', 'amount']) + assert_frame_equal(left, right) + def test_reindex_name_remains(self): s = Series(random.rand(10)) df = DataFrame(s, index=np.arange(len(s))) @@ -9772,6 +10137,39 @@ def test_align_int_fill_bug(self): expected = df2 - df2.mean() assert_frame_equal(result, expected) + def test_align_multiindex(self): + # GH 10665 + # same test cases as test_align_multiindex in test_series.py + + midx = pd.MultiIndex.from_product([range(2), range(3), range(2)], + names=('a', 'b', 'c')) + idx = pd.Index(range(2), name='b') + df1 = pd.DataFrame(np.arange(12,dtype='int64'), index=midx) + df2 = pd.DataFrame(np.arange(2,dtype='int64'), index=idx) + + # these must be the same results (but flipped) + res1l, res1r = df1.align(df2, join='left') + res2l, res2r = df2.align(df1, join='right') + + expl = df1 + tm.assert_frame_equal(expl, res1l) + tm.assert_frame_equal(expl, res2r) + expr = pd.DataFrame([0, 0, 1, 1, np.nan, np.nan] * 2, index=midx) + tm.assert_frame_equal(expr, res1r) + tm.assert_frame_equal(expr, res2l) + + res1l, res1r = df1.align(df2, join='right') + res2l, res2r = df2.align(df1, join='left') + + exp_idx = pd.MultiIndex.from_product([range(2), range(2), range(2)], + names=('a', 'b', 'c')) + expl = pd.DataFrame([0, 1, 2, 3, 6, 7, 8, 9], index=exp_idx) + tm.assert_frame_equal(expl, res1l) + tm.assert_frame_equal(expl, res2r) + expr = pd.DataFrame([0, 0, 1, 1] * 2, index=exp_idx) + tm.assert_frame_equal(expr, res1r) + tm.assert_frame_equal(expr, res2l) + def test_where(self): default_frame = DataFrame(np.random.randn(5, 3),columns=['A','B','C']) @@ -10006,6 +10404,110 @@ def test_where_complex(self): df[df.abs() >= 5] = np.nan assert_frame_equal(df,expected) + def test_where_axis(self): + # GH 9736 + df = DataFrame(np.random.randn(2, 2)) + mask = DataFrame([[False, False], [False, False]]) + s = Series([0, 1]) + + expected = DataFrame([[0, 0], [1, 1]], dtype='float64') + result = df.where(mask, s, axis='index') + assert_frame_equal(result, expected) + + result = df.copy() + result.where(mask, s, axis='index', inplace=True) + assert_frame_equal(result, expected) + + expected = DataFrame([[0, 1], [0, 1]], dtype='float64') + result = df.where(mask, s, axis='columns') + assert_frame_equal(result, expected) + + result = df.copy() + result.where(mask, s, axis='columns', inplace=True) + assert_frame_equal(result, expected) + + # Upcast needed + df = DataFrame([[1, 2], [3, 4]], dtype='int64') + mask = DataFrame([[False, False], [False, False]]) + s = Series([0, np.nan]) + + expected = DataFrame([[0, 0], [np.nan, np.nan]], dtype='float64') + result = df.where(mask, s, axis='index') + assert_frame_equal(result, expected) + + result = df.copy() + result.where(mask, s, axis='index', inplace=True) + assert_frame_equal(result, expected) + + expected = DataFrame([[0, np.nan], [0, np.nan]], dtype='float64') + result = df.where(mask, s, axis='columns') + assert_frame_equal(result, expected) + + expected = DataFrame({0 : np.array([0, 0], dtype='int64'), + 1 : np.array([np.nan, np.nan], dtype='float64')}) + result = df.copy() + result.where(mask, s, axis='columns', inplace=True) + assert_frame_equal(result, expected) + + # Multiple dtypes (=> multiple Blocks) + df = pd.concat([DataFrame(np.random.randn(10, 2)), + DataFrame(np.random.randint(0, 10, size=(10, 2)))], + ignore_index=True, axis=1) + mask = DataFrame(False, columns=df.columns, index=df.index) + s1 = Series(1, index=df.columns) + s2 = Series(2, index=df.index) + + result = df.where(mask, s1, axis='columns') + expected = DataFrame(1.0, columns=df.columns, index=df.index) + expected[2] = expected[2].astype(int) + expected[3] = expected[3].astype(int) + assert_frame_equal(result, expected) + + result = df.copy() + result.where(mask, s1, axis='columns', inplace=True) + assert_frame_equal(result, expected) + + result = df.where(mask, s2, axis='index') + expected = DataFrame(2.0, columns=df.columns, index=df.index) + expected[2] = expected[2].astype(int) + expected[3] = expected[3].astype(int) + assert_frame_equal(result, expected) + + result = df.copy() + result.where(mask, s2, axis='index', inplace=True) + assert_frame_equal(result, expected) + + # DataFrame vs DataFrame + d1 = df.copy().drop(1, axis=0) + expected = df.copy() + expected.loc[1, :] = np.nan + + result = df.where(mask, d1) + assert_frame_equal(result, expected) + result = df.where(mask, d1, axis='index') + assert_frame_equal(result, expected) + result = df.copy() + result.where(mask, d1, inplace=True) + assert_frame_equal(result, expected) + result = df.copy() + result.where(mask, d1, inplace=True, axis='index') + assert_frame_equal(result, expected) + + d2 = df.copy().drop(1, axis=1) + expected = df.copy() + expected.loc[:, 1] = np.nan + + result = df.where(mask, d2) + assert_frame_equal(result, expected) + result = df.where(mask, d2, axis='columns') + assert_frame_equal(result, expected) + result = df.copy() + result.where(mask, d2, inplace=True) + assert_frame_equal(result, expected) + result = df.copy() + result.where(mask, d2, inplace=True, axis='columns') + assert_frame_equal(result, expected) + def test_mask(self): df = DataFrame(np.random.randn(5, 3)) cond = df > 0 @@ -10320,6 +10822,15 @@ def test_shift_bool(self): columns=['high', 'low']) assert_frame_equal(rs, xp) + def test_shift_categorical(self): + # GH 9416 + s1 = pd.Series(['a', 'b', 'c'], dtype='category') + s2 = pd.Series(['A', 'B', 'C'], dtype='category') + df = DataFrame({'one': s1, 'two': s2}) + rs = df.shift(1) + xp = DataFrame({'one': s1.shift(1), 'two': s2.shift(1)}) + assert_frame_equal(rs, xp) + def test_shift_empty(self): # Regression test for #8019 df = DataFrame({'foo': []}) @@ -10382,6 +10893,13 @@ def test_apply(self): [[1, 2, 3], [4, 5, 6], [7, 8, 9]], index=['a', 'a', 'c']) self.assertRaises(ValueError, df.apply, lambda x: x, 2) + # GH9573 + df = DataFrame({'c0':['A','A','B','B'], 'c1':['C','C','D','D']}) + df = df.apply(lambda ts: ts.astype('category')) + self.assertEqual(df.shape, (4, 2)) + self.assertTrue(isinstance(df['c0'].dtype, com.CategoricalDtype)) + self.assertTrue(isinstance(df['c1'].dtype, com.CategoricalDtype)) + def test_apply_mixed_datetimelike(self): # mixed datetimelike # GH 7778 @@ -10507,10 +11025,10 @@ def _checkit(axis=0, raw=False): res = df.apply(f, axis=axis, raw=raw) if is_reduction: agg_axis = df._get_agg_axis(axis) - tm.assert_isinstance(res, Series) + tm.assertIsInstance(res, Series) self.assertIs(res.index, agg_axis) else: - tm.assert_isinstance(res, DataFrame) + tm.assertIsInstance(res, DataFrame) _checkit() _checkit(axis=1) @@ -10523,7 +11041,7 @@ def _checkit(axis=0, raw=False): _check(no_index, lambda x: x.mean()) result = no_cols.apply(lambda x: x.mean(), broadcast=True) - tm.assert_isinstance(result, DataFrame) + tm.assertIsInstance(result, DataFrame) def test_apply_with_args_kwds(self): def add_some(x, howmuch=0): @@ -10650,7 +11168,7 @@ def test_apply_convert_objects(self): 'F': np.random.randn(11)}) result = data.apply(lambda x: x, axis=1) - assert_frame_equal(result.convert_objects(), data) + assert_frame_equal(result.convert_objects(datetime=True), data) def test_apply_attach_name(self): result = self.frame.apply(lambda x: x.name) @@ -10682,7 +11200,7 @@ def test_apply_multi_index(self): s.index = MultiIndex.from_arrays([['a','a','b'], ['c','d','d']]) s.columns = ['col1','col2'] res = s.apply(lambda x: Series({'min': min(x), 'max': max(x)}), 1) - tm.assert_isinstance(res.index, MultiIndex) + tm.assertIsInstance(res.index, MultiIndex) def test_applymap(self): applied = self.frame.applymap(lambda x: x * 2) @@ -10691,7 +11209,7 @@ def test_applymap(self): # GH #465, function returning tuples result = self.frame.applymap(lambda x: (x, x)) - tm.assert_isinstance(result['A'][0], tuple) + tm.assertIsInstance(result['A'][0], tuple) # GH 2909, object conversion to float in constructor? df = DataFrame(data=[1,'a']) @@ -10734,7 +11252,7 @@ def test_filter(self): idx = self.frame.index[0:4] filtered = self.frame.filter(idx, axis='index') expected = self.frame.reindex(index=idx) - assert_frame_equal(filtered,expected) + assert_frame_equal(filtered, expected) # like fcopy = self.frame.copy() @@ -10749,6 +11267,17 @@ def test_filter(self): filtered = df.filter(like='_') self.assertEqual(len(filtered.columns), 2) + # regex with ints in column names + # from PR #10384 + df = DataFrame(0., index=[0, 1, 2], columns=['A1', 1, 'B', 2, 'C']) + expected = DataFrame(0., index=[0, 1, 2], columns=[1, 2]) + filtered = df.filter(regex='^[0-9]+$') + self.assert_frame_equal(filtered, expected) + + expected = DataFrame(0., index=[0, 1, 2], columns=[0, '0', 1, '1']) + filtered = expected.filter(regex='^[0-9]+$') # shouldn't remove anything + self.assert_frame_equal(filtered, expected) + # pass in None with assertRaisesRegexp(TypeError, 'Must pass'): self.frame.filter(items=None) @@ -11432,61 +11961,65 @@ def test_update_from_non_df(self): assert_frame_equal(df, expected) def test_combineAdd(self): - # trivial - comb = self.frame.combineAdd(self.frame) - assert_frame_equal(comb, self.frame * 2) - - # more rigorous - a = DataFrame([[1., nan, nan, 2., nan]], - columns=np.arange(5)) - b = DataFrame([[2., 3., nan, 2., 6., nan]], - columns=np.arange(6)) - expected = DataFrame([[3., 3., nan, 4., 6., nan]], - columns=np.arange(6)) - - result = a.combineAdd(b) - assert_frame_equal(result, expected) - result2 = a.T.combineAdd(b.T) - assert_frame_equal(result2, expected.T) - - expected2 = a.combine(b, operator.add, fill_value=0.) - assert_frame_equal(expected, expected2) - - # corner cases - comb = self.frame.combineAdd(self.empty) - assert_frame_equal(comb, self.frame) - comb = self.empty.combineAdd(self.frame) - assert_frame_equal(comb, self.frame) - - # integer corner case - df1 = DataFrame({'x': [5]}) - df2 = DataFrame({'x': [1]}) - df3 = DataFrame({'x': [6]}) - comb = df1.combineAdd(df2) - assert_frame_equal(comb, df3) - - # mixed type GH2191 - df1 = DataFrame({'A': [1, 2], 'B': [3, 4]}) - df2 = DataFrame({'A': [1, 2], 'C': [5, 6]}) - rs = df1.combineAdd(df2) - xp = DataFrame({'A': [2, 4], 'B': [3, 4.], 'C': [5, 6.]}) - assert_frame_equal(xp, rs) + with tm.assert_produces_warning(FutureWarning): + # trivial + comb = self.frame.combineAdd(self.frame) + assert_frame_equal(comb, self.frame * 2) + + # more rigorous + a = DataFrame([[1., nan, nan, 2., nan]], + columns=np.arange(5)) + b = DataFrame([[2., 3., nan, 2., 6., nan]], + columns=np.arange(6)) + expected = DataFrame([[3., 3., nan, 4., 6., nan]], + columns=np.arange(6)) + + result = a.combineAdd(b) + assert_frame_equal(result, expected) + result2 = a.T.combineAdd(b.T) + assert_frame_equal(result2, expected.T) + + expected2 = a.combine(b, operator.add, fill_value=0.) + assert_frame_equal(expected, expected2) + + # corner cases + comb = self.frame.combineAdd(self.empty) + assert_frame_equal(comb, self.frame) + + comb = self.empty.combineAdd(self.frame) + assert_frame_equal(comb, self.frame) + + # integer corner case + df1 = DataFrame({'x': [5]}) + df2 = DataFrame({'x': [1]}) + df3 = DataFrame({'x': [6]}) + comb = df1.combineAdd(df2) + assert_frame_equal(comb, df3) + + # mixed type GH2191 + df1 = DataFrame({'A': [1, 2], 'B': [3, 4]}) + df2 = DataFrame({'A': [1, 2], 'C': [5, 6]}) + rs = df1.combineAdd(df2) + xp = DataFrame({'A': [2, 4], 'B': [3, 4.], 'C': [5, 6.]}) + assert_frame_equal(xp, rs) # TODO: test integer fill corner? def test_combineMult(self): - # trivial - comb = self.frame.combineMult(self.frame) - assert_frame_equal(comb, self.frame ** 2) + with tm.assert_produces_warning(FutureWarning): + # trivial + comb = self.frame.combineMult(self.frame) - # corner cases - comb = self.frame.combineMult(self.empty) - assert_frame_equal(comb, self.frame) + assert_frame_equal(comb, self.frame ** 2) - comb = self.empty.combineMult(self.frame) - assert_frame_equal(comb, self.frame) + # corner cases + comb = self.frame.combineMult(self.empty) + assert_frame_equal(comb, self.frame) + + comb = self.empty.combineMult(self.frame) + assert_frame_equal(comb, self.frame) def test_combine_generic(self): df1 = self.frame @@ -11674,10 +12207,10 @@ def test_count(self): # corner case frame = DataFrame() ct1 = frame.count(1) - tm.assert_isinstance(ct1, Series) + tm.assertIsInstance(ct1, Series) ct2 = frame.count(0) - tm.assert_isinstance(ct2, Series) + tm.assertIsInstance(ct2, Series) # GH #423 df = DataFrame(index=lrange(10)) @@ -12036,8 +12569,8 @@ def test_mode(self): def test_sum_corner(self): axis0 = self.empty.sum(0) axis1 = self.empty.sum(1) - tm.assert_isinstance(axis0, Series) - tm.assert_isinstance(axis1, Series) + tm.assertIsInstance(axis0, Series) + tm.assertIsInstance(axis1, Series) self.assertEqual(len(axis0), 0) self.assertEqual(len(axis1), 0) @@ -12114,8 +12647,8 @@ def test_quantile(self): result = df.quantile([.5, .75], axis=1) expected = DataFrame({1: [1.5, 1.75], 2: [2.5, 2.75], - 3: [3.5, 3.75]}, index=["0.5", "0.75"]) - assert_frame_equal(result, expected) + 3: [3.5, 3.75]}, index=[0.5, 0.75]) + assert_frame_equal(result, expected, check_index_type=True) # We may want to break API in the future to change this # so that we exclude non-numeric along the same axis @@ -14443,16 +14976,8 @@ def test_assign_bad(self): def test_dataframe_metadata(self): - class TestDataFrame(DataFrame): - _metadata = ['testattr'] - - @property - def _constructor(self): - return TestDataFrame - - - df = TestDataFrame({'X': [1, 2, 3], 'Y': [1, 2, 3]}, - index=['a', 'b', 'c']) + df = SubclassedDataFrame({'X': [1, 2, 3], 'Y': [1, 2, 3]}, + index=['a', 'b', 'c']) df.testattr = 'XXX' self.assertEqual(df.testattr, 'XXX') @@ -14461,6 +14986,46 @@ def _constructor(self): self.assertEqual(df.iloc[[0, 1], :].testattr, 'XXX') # GH9776 self.assertEqual(df.iloc[0:1, :].testattr, 'XXX') + # GH10553 + unpickled = self.round_trip_pickle(df) + assert_frame_equal(df, unpickled) + self.assertEqual(df._metadata, unpickled._metadata) + self.assertEqual(df.testattr, unpickled.testattr) + + def test_nlargest(self): + # GH10393 + from string import ascii_lowercase + df = pd.DataFrame({'a': np.random.permutation(10), + 'b': list(ascii_lowercase[:10])}) + result = df.nlargest(5, 'a') + expected = df.sort('a', ascending=False).head(5) + tm.assert_frame_equal(result, expected) + + def test_nlargest_multiple_columns(self): + from string import ascii_lowercase + df = pd.DataFrame({'a': np.random.permutation(10), + 'b': list(ascii_lowercase[:10]), + 'c': np.random.permutation(10).astype('float64')}) + result = df.nlargest(5, ['a', 'b']) + expected = df.sort(['a', 'b'], ascending=False).head(5) + tm.assert_frame_equal(result, expected) + + def test_nsmallest(self): + from string import ascii_lowercase + df = pd.DataFrame({'a': np.random.permutation(10), + 'b': list(ascii_lowercase[:10])}) + result = df.nsmallest(5, 'a') + expected = df.sort('a').head(5) + tm.assert_frame_equal(result, expected) + + def test_nsmallest_multiple_columns(self): + from string import ascii_lowercase + df = pd.DataFrame({'a': np.random.permutation(10), + 'b': list(ascii_lowercase[:10]), + 'c': np.random.permutation(10).astype('float64')}) + result = df.nsmallest(5, ['a', 'c']) + expected = df.sort(['a', 'c']).head(5) + tm.assert_frame_equal(result, expected) def test_to_panel_expanddim(self): # GH 9762 diff --git a/pandas/tests/test_generic.py b/pandas/tests/test_generic.py index 44f7791b7f8ba..c1f6045c61d54 100644 --- a/pandas/tests/test_generic.py +++ b/pandas/tests/test_generic.py @@ -374,7 +374,7 @@ def test_sample(self): self._compare(o.sample(frac=0.7,random_state=np.random.RandomState(test)), o.sample(frac=0.7, random_state=np.random.RandomState(test))) - + # Check for error when random_state argument invalid. with tm.assertRaises(ValueError): @@ -415,6 +415,10 @@ def test_sample(self): bad_weights = [0.5]*11 o.sample(n=3, weights=bad_weights) + with tm.assertRaises(ValueError): + bad_weight_series = Series([0,0,0.2]) + o.sample(n=4, weights=bad_weight_series) + # Check won't accept negative weights with tm.assertRaises(ValueError): bad_weights = [-0.1]*10 @@ -431,6 +435,16 @@ def test_sample(self): weights_with_ninf[0] = -np.inf o.sample(n=3, weights=weights_with_ninf) + # All zeros raises errors + zero_weights = [0]*10 + with tm.assertRaises(ValueError): + o.sample(n=3, weights=zero_weights) + + # All missing weights + nan_weights = [np.nan]*10 + with tm.assertRaises(ValueError): + o.sample(n=3, weights=nan_weights) + # A few dataframe test with degenerate weights. easy_weight_list = [0]*10 @@ -496,7 +510,6 @@ def test_sample(self): assert_frame_equal(df.sample(n=1, axis='index', weights=weight), df.iloc[5:6]) - # Check out of range axis values with tm.assertRaises(ValueError): df.sample(n=1, axis=2) @@ -527,6 +540,26 @@ def test_sample(self): assert_panel_equal(p.sample(n=3, random_state=42), p.sample(n=3, axis=1, random_state=42)) assert_frame_equal(df.sample(n=3, random_state=42), df.sample(n=3, axis=0, random_state=42)) + # Test that function aligns weights with frame + df = DataFrame({'col1':[5,6,7], 'col2':['a','b','c'], }, index = [9,5,3]) + s = Series([1,0,0], index=[3,5,9]) + assert_frame_equal(df.loc[[3]], df.sample(1, weights=s)) + + # Weights have index values to be dropped because not in + # sampled DataFrame + s2 = Series([0.001,0,10000], index=[3,5,10]) + assert_frame_equal(df.loc[[3]], df.sample(1, weights=s2)) + + # Weights have empty values to be filed with zeros + s3 = Series([0.01,0], index=[3,5]) + assert_frame_equal(df.loc[[3]], df.sample(1, weights=s3)) + + # No overlap in weight and sampled DataFrame indices + s4 = Series([1,0], index=[1,2]) + with tm.assertRaises(ValueError): + df.sample(1, weights=s4) + + def test_size_compat(self): # GH8846 # size property should be defined @@ -1117,6 +1150,14 @@ def test_interp_inplace(self): result['a'].interpolate(inplace=True, downcast='infer') assert_frame_equal(result, expected.astype('int64')) + def test_interp_inplace_row(self): + # GH 10395 + result = DataFrame({'a': [1.,2.,3.,4.], 'b': [np.nan, 2., 3., 4.], + 'c': [3, 2, 2, 2]}) + expected = result.interpolate(method='linear', axis=1, inplace=False) + result.interpolate(method='linear', axis=1, inplace=True) + assert_frame_equal(result, expected) + def test_interp_ignore_all_good(self): # GH df = DataFrame({'A': [1, 2, np.nan, 4], @@ -1365,6 +1406,23 @@ def test_spline(self): expected = Series([1., 2., 3., 4., 5., 6., 7.]) assert_series_equal(result, expected) + def test_spline_extrapolate(self): + tm.skip_if_no_package('scipy', '0.15', 'setting ext on scipy.interpolate.UnivariateSpline') + s = Series([1, 2, 3, 4, np.nan, 6, np.nan]) + result3 = s.interpolate(method='spline', order=1, ext=3) + expected3 = Series([1., 2., 3., 4., 5., 6., 6.]) + assert_series_equal(result3, expected3) + + result1 = s.interpolate(method='spline', order=1, ext=0) + expected1 = Series([1., 2., 3., 4., 5., 6., 7.]) + assert_series_equal(result1, expected1) + + def test_spline_smooth(self): + tm._skip_if_no_scipy() + s = Series([1, 2, np.nan, 4, 5.1, np.nan, 7]) + self.assertNotEqual(s.interpolate(method='spline', order=3, s=0)[5], + s.interpolate(method='spline', order=3)[5]) + def test_metadata_propagation_indiv(self): # groupby diff --git a/pandas/tests/test_graphics.py b/pandas/tests/test_graphics.py index 2c8123244c53c..1907cbd78da1d 100644 --- a/pandas/tests/test_graphics.py +++ b/pandas/tests/test_graphics.py @@ -25,18 +25,16 @@ from numpy import random from numpy.random import rand, randn -from numpy.testing import assert_array_equal, assert_allclose +from numpy.testing import assert_allclose from numpy.testing.decorators import slow import pandas.tools.plotting as plotting -def _skip_if_mpl_14_or_dev_boxplot(): - # GH 8382 - # Boxplot failures on 1.4 and 1.4.1 - # Don't need try / except since that's done at class level - import matplotlib - if str(matplotlib.__version__) >= LooseVersion('1.4'): - raise nose.SkipTest("Matplotlib Regression in 1.4 and current dev.") +""" +These tests are for ``Dataframe.plot`` and ``Series.plot``. +Other plot methods such as ``.hist``, ``.boxplot`` and other miscellaneous +are tested in test_graphics_others.py +""" def _skip_if_no_scipy_gaussian_kde(): @@ -46,6 +44,7 @@ def _skip_if_no_scipy_gaussian_kde(): except ImportError: raise nose.SkipTest("scipy version doesn't support gaussian_kde") + def _ok_for_gaussian_kde(kind): if kind in ['kde','density']: try: @@ -55,6 +54,7 @@ def _ok_for_gaussian_kde(kind): return False return True + @tm.mplskip class TestPlotBase(tm.TestCase): @@ -646,11 +646,11 @@ def test_bar_log(self): expected = np.hstack((.1, expected, 1e4)) ax = Series([200, 500]).plot(log=True, kind='bar') - assert_array_equal(ax.yaxis.get_ticklocs(), expected) + tm.assert_numpy_array_equal(ax.yaxis.get_ticklocs(), expected) tm.close() ax = Series([200, 500]).plot(log=True, kind='barh') - assert_array_equal(ax.xaxis.get_ticklocs(), expected) + tm.assert_numpy_array_equal(ax.xaxis.get_ticklocs(), expected) tm.close() # GH 9905 @@ -660,13 +660,13 @@ def test_bar_log(self): expected = np.hstack((1.0e-04, expected, 1.0e+01)) ax = Series([0.1, 0.01, 0.001]).plot(log=True, kind='bar') - assert_array_equal(ax.get_ylim(), (0.001, 0.10000000000000001)) - assert_array_equal(ax.yaxis.get_ticklocs(), expected) + tm.assert_numpy_array_equal(ax.get_ylim(), (0.001, 0.10000000000000001)) + tm.assert_numpy_array_equal(ax.yaxis.get_ticklocs(), expected) tm.close() ax = Series([0.1, 0.01, 0.001]).plot(log=True, kind='barh') - assert_array_equal(ax.get_xlim(), (0.001, 0.10000000000000001)) - assert_array_equal(ax.xaxis.get_ticklocs(), expected) + tm.assert_numpy_array_equal(ax.get_xlim(), (0.001, 0.10000000000000001)) + tm.assert_numpy_array_equal(ax.xaxis.get_ticklocs(), expected) @slow def test_bar_ignore_index(self): @@ -943,20 +943,6 @@ def test_plot_fails_with_dupe_color_and_style(self): with tm.assertRaises(ValueError): x.plot(style='k--', color='k') - @slow - def test_hist_by_no_extra_plots(self): - df = self.hist_df - axes = df.height.hist(by=df.gender) - self.assertEqual(len(self.plt.get_fignums()), 1) - - def test_plot_fails_when_ax_differs_from_figure(self): - from pylab import figure - fig1 = figure() - fig2 = figure() - ax1 = fig1.add_subplot(111) - with tm.assertRaises(AssertionError): - self.ts.hist(ax=ax1, figure=fig2) - @slow def test_hist_kde(self): ax = self.ts.plot(kind='hist', logy=True) @@ -1001,12 +987,12 @@ def test_kde_missing_vals(self): def test_hist_kwargs(self): ax = self.ts.plot(kind='hist', bins=5) self.assertEqual(len(ax.patches), 5) - self._check_text_labels(ax.yaxis.get_label(), 'Degree') + self._check_text_labels(ax.yaxis.get_label(), 'Frequency') tm.close() if self.mpl_ge_1_3_1: ax = self.ts.plot(kind='hist', orientation='horizontal') - self._check_text_labels(ax.xaxis.get_label(), 'Degree') + self._check_text_labels(ax.xaxis.get_label(), 'Frequency') tm.close() ax = self.ts.plot(kind='hist', align='left', stacked=True) @@ -1037,25 +1023,6 @@ def test_boxplot_series(self): self._check_text_labels(ylabels, [''] * len(ylabels)) @slow - def test_autocorrelation_plot(self): - from pandas.tools.plotting import autocorrelation_plot - _check_plot_works(autocorrelation_plot, self.ts) - _check_plot_works(autocorrelation_plot, self.ts.values) - - ax = autocorrelation_plot(self.ts, label='Test') - self._check_legend_labels(ax, labels=['Test']) - - @slow - def test_lag_plot(self): - from pandas.tools.plotting import lag_plot - _check_plot_works(lag_plot, self.ts) - _check_plot_works(lag_plot, self.ts, lag=5) - - @slow - def test_bootstrap_plot(self): - from pandas.tools.plotting import bootstrap_plot - _check_plot_works(bootstrap_plot, self.ts, size=10) - def test_invalid_plot_data(self): s = Series(list('abcd')) for kind in plotting._common_kinds: @@ -1146,6 +1113,77 @@ def test_series_grid_settings(self): self._check_grid_settings(Series([1,2,3]), plotting._series_kinds + plotting._common_kinds) + @slow + def test_standard_colors(self): + for c in ['r', 'red', 'green', '#FF0000']: + result = plotting._get_standard_colors(1, color=c) + self.assertEqual(result, [c]) + + result = plotting._get_standard_colors(1, color=[c]) + self.assertEqual(result, [c]) + + result = plotting._get_standard_colors(3, color=c) + self.assertEqual(result, [c] * 3) + + result = plotting._get_standard_colors(3, color=[c]) + self.assertEqual(result, [c] * 3) + + @slow + def test_standard_colors_all(self): + import matplotlib.colors as colors + + # multiple colors like mediumaquamarine + for c in colors.cnames: + result = plotting._get_standard_colors(num_colors=1, color=c) + self.assertEqual(result, [c]) + + result = plotting._get_standard_colors(num_colors=1, color=[c]) + self.assertEqual(result, [c]) + + result = plotting._get_standard_colors(num_colors=3, color=c) + self.assertEqual(result, [c] * 3) + + result = plotting._get_standard_colors(num_colors=3, color=[c]) + self.assertEqual(result, [c] * 3) + + # single letter colors like k + for c in colors.ColorConverter.colors: + result = plotting._get_standard_colors(num_colors=1, color=c) + self.assertEqual(result, [c]) + + result = plotting._get_standard_colors(num_colors=1, color=[c]) + self.assertEqual(result, [c]) + + result = plotting._get_standard_colors(num_colors=3, color=c) + self.assertEqual(result, [c] * 3) + + result = plotting._get_standard_colors(num_colors=3, color=[c]) + self.assertEqual(result, [c] * 3) + + def test_series_plot_color_kwargs(self): + # GH1890 + ax = Series(np.arange(12) + 1).plot(color='green') + self._check_colors(ax.get_lines(), linecolors=['green']) + + def test_time_series_plot_color_kwargs(self): + # #1890 + ax = Series(np.arange(12) + 1, index=date_range( + '1/1/2000', periods=12)).plot(color='green') + self._check_colors(ax.get_lines(), linecolors=['green']) + + def test_time_series_plot_color_with_empty_kwargs(self): + import matplotlib as mpl + + def_colors = mpl.rcParams['axes.color_cycle'] + index = date_range('1/1/2000', periods=12) + s = Series(np.arange(1, 13), index=index) + + ncolors = 3 + + for i in range(ncolors): + ax = s.plot() + self._check_colors(ax.get_lines(), linecolors=def_colors[:ncolors]) + @tm.mplskip class TestDataFramePlots(TestPlotBase): @@ -1736,7 +1774,6 @@ def test_bar_colors(self): default_colors = plt.rcParams.get('axes.color_cycle') - df = DataFrame(randn(5, 5)) ax = df.plot(kind='bar') self._check_colors(ax.patches[::5], facecolors=default_colors[:5]) @@ -1762,6 +1799,11 @@ def test_bar_colors(self): ax = df.ix[:, [0]].plot(kind='bar', color='DodgerBlue') self._check_colors([ax.patches[0]], facecolors=['DodgerBlue']) + tm.close() + + ax = df.plot(kind='bar', color='green') + self._check_colors(ax.patches[::5], facecolors=['green'] * 5) + tm.close() @slow def test_bar_linewidth(self): @@ -2112,7 +2154,7 @@ def test_bar_log_no_subplots(self): # no subplots df = DataFrame({'A': [3] * 5, 'B': lrange(1, 6)}, index=lrange(5)) ax = df.plot(kind='bar', grid=True, log=True) - assert_array_equal(ax.yaxis.get_ticklocs(), expected) + tm.assert_numpy_array_equal(ax.yaxis.get_ticklocs(), expected) @slow def test_bar_log_subplots(self): @@ -2124,8 +2166,8 @@ def test_bar_log_subplots(self): Series([300, 500])]).plot(log=True, kind='bar', subplots=True) - assert_array_equal(ax[0].yaxis.get_ticklocs(), expected) - assert_array_equal(ax[1].yaxis.get_ticklocs(), expected) + tm.assert_numpy_array_equal(ax[0].yaxis.get_ticklocs(), expected) + tm.assert_numpy_array_equal(ax[1].yaxis.get_ticklocs(), expected) @slow def test_boxplot(self): @@ -2136,7 +2178,7 @@ def test_boxplot(self): ax = _check_plot_works(df.plot, kind='box') self._check_text_labels(ax.get_xticklabels(), labels) - assert_array_equal(ax.xaxis.get_ticklocs(), + tm.assert_numpy_array_equal(ax.xaxis.get_ticklocs(), np.arange(1, len(numeric_cols) + 1)) self.assertEqual(len(ax.lines), self.bp_n_objects * len(numeric_cols)) @@ -2163,7 +2205,7 @@ def test_boxplot(self): numeric_cols = df._get_numeric_data().columns labels = [com.pprint_thing(c) for c in numeric_cols] self._check_text_labels(ax.get_xticklabels(), labels) - assert_array_equal(ax.xaxis.get_ticklocs(), positions) + tm.assert_numpy_array_equal(ax.xaxis.get_ticklocs(), positions) self.assertEqual(len(ax.lines), self.bp_n_objects * len(numeric_cols)) @slow @@ -2189,7 +2231,7 @@ def test_boxplot_vertical(self): positions = np.array([3, 2, 8]) ax = df.plot(kind='box', positions=positions, vert=False) self._check_text_labels(ax.get_yticklabels(), labels) - assert_array_equal(ax.yaxis.get_ticklocs(), positions) + tm.assert_numpy_array_equal(ax.yaxis.get_ticklocs(), positions) self.assertEqual(len(ax.lines), self.bp_n_objects * len(numeric_cols)) @slow @@ -2225,112 +2267,6 @@ def test_boxplot_subplots_return_type(self): expected_keys=['height', 'weight', 'category'], check_ax_title=False) - @slow - def test_boxplot_legacy(self): - df = DataFrame(randn(6, 4), - index=list(string.ascii_letters[:6]), - columns=['one', 'two', 'three', 'four']) - df['indic'] = ['foo', 'bar'] * 3 - df['indic2'] = ['foo', 'bar', 'foo'] * 2 - - _check_plot_works(df.boxplot, return_type='dict') - _check_plot_works(df.boxplot, column=['one', 'two'], return_type='dict') - _check_plot_works(df.boxplot, column=['one', 'two'], by='indic') - _check_plot_works(df.boxplot, column='one', by=['indic', 'indic2']) - _check_plot_works(df.boxplot, by='indic') - _check_plot_works(df.boxplot, by=['indic', 'indic2']) - _check_plot_works(plotting.boxplot, df['one'], return_type='dict') - _check_plot_works(df.boxplot, notch=1, return_type='dict') - _check_plot_works(df.boxplot, by='indic', notch=1) - - df = DataFrame(np.random.rand(10, 2), columns=['Col1', 'Col2']) - df['X'] = Series(['A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B']) - df['Y'] = Series(['A'] * 10) - _check_plot_works(df.boxplot, by='X') - - # When ax is supplied and required number of axes is 1, - # passed ax should be used: - fig, ax = self.plt.subplots() - axes = df.boxplot('Col1', by='X', ax=ax) - self.assertIs(ax.get_axes(), axes) - - fig, ax = self.plt.subplots() - axes = df.groupby('Y').boxplot(ax=ax, return_type='axes') - self.assertIs(ax.get_axes(), axes['A']) - - # Multiple columns with an ax argument should use same figure - fig, ax = self.plt.subplots() - axes = df.boxplot(column=['Col1', 'Col2'], by='X', ax=ax, return_type='axes') - self.assertIs(axes['Col1'].get_figure(), fig) - - # When by is None, check that all relevant lines are present in the dict - fig, ax = self.plt.subplots() - d = df.boxplot(ax=ax, return_type='dict') - lines = list(itertools.chain.from_iterable(d.values())) - self.assertEqual(len(ax.get_lines()), len(lines)) - - @slow - def test_boxplot_return_type_legacy(self): - # API change in https://github.com/pydata/pandas/pull/7096 - import matplotlib as mpl - - df = DataFrame(randn(6, 4), - index=list(string.ascii_letters[:6]), - columns=['one', 'two', 'three', 'four']) - with tm.assertRaises(ValueError): - df.boxplot(return_type='NOTATYPE') - - with tm.assert_produces_warning(FutureWarning): - result = df.boxplot() - # change to Axes in future - self._check_box_return_type(result, 'dict') - - with tm.assert_produces_warning(False): - result = df.boxplot(return_type='dict') - self._check_box_return_type(result, 'dict') - - with tm.assert_produces_warning(False): - result = df.boxplot(return_type='axes') - self._check_box_return_type(result, 'axes') - - with tm.assert_produces_warning(False): - result = df.boxplot(return_type='both') - self._check_box_return_type(result, 'both') - - @slow - def test_boxplot_axis_limits(self): - - def _check_ax_limits(col, ax): - y_min, y_max = ax.get_ylim() - self.assertTrue(y_min <= col.min()) - self.assertTrue(y_max >= col.max()) - - df = self.hist_df.copy() - df['age'] = np.random.randint(1, 20, df.shape[0]) - # One full row - height_ax, weight_ax = df.boxplot(['height', 'weight'], by='category') - _check_ax_limits(df['height'], height_ax) - _check_ax_limits(df['weight'], weight_ax) - self.assertEqual(weight_ax._sharey, height_ax) - - # Two rows, one partial - p = df.boxplot(['height', 'weight', 'age'], by='category') - height_ax, weight_ax, age_ax = p[0, 0], p[0, 1], p[1, 0] - dummy_ax = p[1, 1] - _check_ax_limits(df['height'], height_ax) - _check_ax_limits(df['weight'], weight_ax) - _check_ax_limits(df['age'], age_ax) - self.assertEqual(weight_ax._sharey, height_ax) - self.assertEqual(age_ax._sharey, height_ax) - self.assertIsNone(dummy_ax._sharey) - - @slow - def test_boxplot_empty_column(self): - _skip_if_mpl_14_or_dev_boxplot() - df = DataFrame(np.random.randn(20, 4)) - df.loc[:, 0] = np.nan - _check_plot_works(df.boxplot, return_type='axes') - @slow def test_kde_df(self): tm._skip_if_no_scipy() @@ -2478,251 +2414,6 @@ def test_hist_df_coord(self): self._check_box_coord(axes[2].patches, expected_x=np.array([0, 0, 0, 0, 0]), expected_w=np.array([6, 7, 8, 9, 10])) - @slow - def test_hist_df_legacy(self): - _check_plot_works(self.hist_df.hist) - - # make sure layout is handled - df = DataFrame(randn(100, 3)) - axes = _check_plot_works(df.hist, grid=False) - self._check_axes_shape(axes, axes_num=3, layout=(2, 2)) - self.assertFalse(axes[1, 1].get_visible()) - - df = DataFrame(randn(100, 1)) - _check_plot_works(df.hist) - - # make sure layout is handled - df = DataFrame(randn(100, 6)) - axes = _check_plot_works(df.hist, layout=(4, 2)) - self._check_axes_shape(axes, axes_num=6, layout=(4, 2)) - - # make sure sharex, sharey is handled - _check_plot_works(df.hist, sharex=True, sharey=True) - - # handle figsize arg - _check_plot_works(df.hist, figsize=(8, 10)) - - # check bins argument - _check_plot_works(df.hist, bins=5) - - # make sure xlabelsize and xrot are handled - ser = df[0] - xf, yf = 20, 18 - xrot, yrot = 30, 40 - axes = ser.hist(xlabelsize=xf, xrot=xrot, ylabelsize=yf, yrot=yrot) - self._check_ticks_props(axes, xlabelsize=xf, xrot=xrot, - ylabelsize=yf, yrot=yrot) - - xf, yf = 20, 18 - xrot, yrot = 30, 40 - axes = df.hist(xlabelsize=xf, xrot=xrot, ylabelsize=yf, yrot=yrot) - self._check_ticks_props(axes, xlabelsize=xf, xrot=xrot, - ylabelsize=yf, yrot=yrot) - - tm.close() - # make sure kwargs to hist are handled - ax = ser.hist(normed=True, cumulative=True, bins=4) - # height of last bin (index 5) must be 1.0 - self.assertAlmostEqual(ax.get_children()[5].get_height(), 1.0) - - tm.close() - ax = ser.hist(log=True) - # scale of y must be 'log' - self._check_ax_scales(ax, yaxis='log') - - tm.close() - - # propagate attr exception from matplotlib.Axes.hist - with tm.assertRaises(AttributeError): - ser.hist(foo='bar') - - @slow - def test_hist_layout(self): - df = DataFrame(randn(100, 3)) - - layout_to_expected_size = ( - {'layout': None, 'expected_size': (2, 2)}, # default is 2x2 - {'layout': (2, 2), 'expected_size': (2, 2)}, - {'layout': (4, 1), 'expected_size': (4, 1)}, - {'layout': (1, 4), 'expected_size': (1, 4)}, - {'layout': (3, 3), 'expected_size': (3, 3)}, - {'layout': (-1, 4), 'expected_size': (1, 4)}, - {'layout': (4, -1), 'expected_size': (4, 1)}, - {'layout': (-1, 2), 'expected_size': (2, 2)}, - {'layout': (2, -1), 'expected_size': (2, 2)} - ) - - for layout_test in layout_to_expected_size: - axes = df.hist(layout=layout_test['layout']) - expected = layout_test['expected_size'] - self._check_axes_shape(axes, axes_num=3, layout=expected) - - # layout too small for all 4 plots - with tm.assertRaises(ValueError): - df.hist(layout=(1, 1)) - - # invalid format for layout - with tm.assertRaises(ValueError): - df.hist(layout=(1,)) - with tm.assertRaises(ValueError): - df.hist(layout=(-1, -1)) - - - @slow - def test_scatter(self): - tm._skip_if_no_scipy() - - df = DataFrame(randn(100, 2)) - - def scat(**kwds): - return plotting.scatter_matrix(df, **kwds) - - _check_plot_works(scat) - _check_plot_works(scat, marker='+') - _check_plot_works(scat, vmin=0) - if _ok_for_gaussian_kde('kde'): - _check_plot_works(scat, diagonal='kde') - if _ok_for_gaussian_kde('density'): - _check_plot_works(scat, diagonal='density') - _check_plot_works(scat, diagonal='hist') - _check_plot_works(scat, range_padding=.1) - - def scat2(x, y, by=None, ax=None, figsize=None): - return plotting.scatter_plot(df, x, y, by, ax, figsize=None) - - _check_plot_works(scat2, 0, 1) - grouper = Series(np.repeat([1, 2, 3, 4, 5], 20), df.index) - _check_plot_works(scat2, 0, 1, by=grouper) - - def test_scatter_matrix_axis(self): - tm._skip_if_no_scipy() - scatter_matrix = plotting.scatter_matrix - - with tm.RNGContext(42): - df = DataFrame(randn(100, 3)) - - axes = _check_plot_works(scatter_matrix, df, range_padding=.1) - axes0_labels = axes[0][0].yaxis.get_majorticklabels() - # GH 5662 - expected = ['-2', '-1', '0', '1', '2'] - self._check_text_labels(axes0_labels, expected) - self._check_ticks_props(axes, xlabelsize=8, xrot=90, ylabelsize=8, yrot=0) - - df[0] = ((df[0] - 2) / 3) - axes = _check_plot_works(scatter_matrix, df, range_padding=.1) - axes0_labels = axes[0][0].yaxis.get_majorticklabels() - expected = ['-1.2', '-1.0', '-0.8', '-0.6', '-0.4', '-0.2', '0.0'] - self._check_text_labels(axes0_labels, expected) - self._check_ticks_props(axes, xlabelsize=8, xrot=90, ylabelsize=8, yrot=0) - - @slow - def test_andrews_curves(self): - from pandas.tools.plotting import andrews_curves - from matplotlib import cm - - df = self.iris - - _check_plot_works(andrews_curves, df, 'Name') - - rgba = ('#556270', '#4ECDC4', '#C7F464') - ax = _check_plot_works(andrews_curves, df, 'Name', color=rgba) - self._check_colors(ax.get_lines()[:10], linecolors=rgba, mapping=df['Name'][:10]) - - cnames = ['dodgerblue', 'aquamarine', 'seagreen'] - ax = _check_plot_works(andrews_curves, df, 'Name', color=cnames) - self._check_colors(ax.get_lines()[:10], linecolors=cnames, mapping=df['Name'][:10]) - - ax = _check_plot_works(andrews_curves, df, 'Name', colormap=cm.jet) - cmaps = lmap(cm.jet, np.linspace(0, 1, df['Name'].nunique())) - self._check_colors(ax.get_lines()[:10], linecolors=cmaps, mapping=df['Name'][:10]) - - colors = ['b', 'g', 'r'] - df = DataFrame({"A": [1, 2, 3], - "B": [1, 2, 3], - "C": [1, 2, 3], - "Name": colors}) - ax = andrews_curves(df, 'Name', color=colors) - handles, labels = ax.get_legend_handles_labels() - self._check_colors(handles, linecolors=colors) - - with tm.assert_produces_warning(FutureWarning): - andrews_curves(data=df, class_column='Name') - - @slow - def test_parallel_coordinates(self): - from pandas.tools.plotting import parallel_coordinates - from matplotlib import cm - - df = self.iris - - ax = _check_plot_works(parallel_coordinates, df, 'Name') - nlines = len(ax.get_lines()) - nxticks = len(ax.xaxis.get_ticklabels()) - - rgba = ('#556270', '#4ECDC4', '#C7F464') - ax = _check_plot_works(parallel_coordinates, df, 'Name', color=rgba) - self._check_colors(ax.get_lines()[:10], linecolors=rgba, mapping=df['Name'][:10]) - - cnames = ['dodgerblue', 'aquamarine', 'seagreen'] - ax = _check_plot_works(parallel_coordinates, df, 'Name', color=cnames) - self._check_colors(ax.get_lines()[:10], linecolors=cnames, mapping=df['Name'][:10]) - - ax = _check_plot_works(parallel_coordinates, df, 'Name', colormap=cm.jet) - cmaps = lmap(cm.jet, np.linspace(0, 1, df['Name'].nunique())) - self._check_colors(ax.get_lines()[:10], linecolors=cmaps, mapping=df['Name'][:10]) - - ax = _check_plot_works(parallel_coordinates, df, 'Name', axvlines=False) - assert len(ax.get_lines()) == (nlines - nxticks) - - colors = ['b', 'g', 'r'] - df = DataFrame({"A": [1, 2, 3], - "B": [1, 2, 3], - "C": [1, 2, 3], - "Name": colors}) - ax = parallel_coordinates(df, 'Name', color=colors) - handles, labels = ax.get_legend_handles_labels() - self._check_colors(handles, linecolors=colors) - - with tm.assert_produces_warning(FutureWarning): - parallel_coordinates(data=df, class_column='Name') - with tm.assert_produces_warning(FutureWarning): - parallel_coordinates(df, 'Name', colors=colors) - - @slow - def test_radviz(self): - from pandas.tools.plotting import radviz - from matplotlib import cm - - df = self.iris - _check_plot_works(radviz, df, 'Name') - - rgba = ('#556270', '#4ECDC4', '#C7F464') - ax = _check_plot_works(radviz, df, 'Name', color=rgba) - # skip Circle drawn as ticks - patches = [p for p in ax.patches[:20] if p.get_label() != ''] - self._check_colors(patches[:10], facecolors=rgba, mapping=df['Name'][:10]) - - cnames = ['dodgerblue', 'aquamarine', 'seagreen'] - _check_plot_works(radviz, df, 'Name', color=cnames) - patches = [p for p in ax.patches[:20] if p.get_label() != ''] - self._check_colors(patches, facecolors=cnames, mapping=df['Name'][:10]) - - _check_plot_works(radviz, df, 'Name', colormap=cm.jet) - cmaps = lmap(cm.jet, np.linspace(0, 1, df['Name'].nunique())) - patches = [p for p in ax.patches[:20] if p.get_label() != ''] - self._check_colors(patches, facecolors=cmaps, mapping=df['Name'][:10]) - - colors = [[0., 0., 1., 1.], - [0., 0.5, 1., 1.], - [1., 0., 0., 1.]] - df = DataFrame({"A": [1, 2, 3], - "B": [2, 1, 3], - "C": [3, 2, 1], - "Name": ['b', 'g', 'r']}) - ax = radviz(df, 'Name', color=colors) - handles, labels = ax.get_legend_handles_labels() - self._check_colors(handles, facecolors=colors) - @slow def test_plot_int_columns(self): df = DataFrame(randn(100, 4)).cumsum() @@ -2897,6 +2588,71 @@ def test_line_colors(self): ax = df.ix[:, [0]].plot(color='DodgerBlue') self._check_colors(ax.lines, linecolors=['DodgerBlue']) + ax = df.plot(color='red') + self._check_colors(ax.get_lines(), linecolors=['red'] * 5) + tm.close() + + @slow + def test_line_colors_and_styles_subplots(self): + # GH 9894 + from matplotlib import cm + default_colors = self.plt.rcParams.get('axes.color_cycle') + + df = DataFrame(randn(5, 5)) + + axes = df.plot(subplots=True) + for ax, c in zip(axes, list(default_colors)): + self._check_colors(ax.get_lines(), linecolors=c) + tm.close() + + # single color char + axes = df.plot(subplots=True, color='k') + for ax in axes: + self._check_colors(ax.get_lines(), linecolors=['k']) + tm.close() + + # single color str + axes = df.plot(subplots=True, color='green') + for ax in axes: + self._check_colors(ax.get_lines(), linecolors=['green']) + tm.close() + + custom_colors = 'rgcby' + axes = df.plot(color=custom_colors, subplots=True) + for ax, c in zip(axes, list(custom_colors)): + self._check_colors(ax.get_lines(), linecolors=[c]) + tm.close() + + axes = df.plot(color=list(custom_colors), subplots=True) + for ax, c in zip(axes, list(custom_colors)): + self._check_colors(ax.get_lines(), linecolors=[c]) + tm.close() + + rgba_colors = lmap(cm.jet, np.linspace(0, 1, len(df))) + for cmap in ['jet', cm.jet]: + axes = df.plot(colormap=cmap, subplots=True) + for ax, c in zip(axes, rgba_colors): + self._check_colors(ax.get_lines(), linecolors=[c]) + tm.close() + + # make color a list if plotting one column frame + # handles cases like df.plot(color='DodgerBlue') + axes = df.ix[:, [0]].plot(color='DodgerBlue', subplots=True) + self._check_colors(axes[0].lines, linecolors=['DodgerBlue']) + + # single character style + axes = df.plot(style='r', subplots=True) + for ax in axes: + self._check_colors(ax.get_lines(), linecolors=['r']) + tm.close() + + # list of styles + styles = list('rgcby') + axes = df.plot(style=styles, subplots=True) + for ax, c in zip(axes, styles): + self._check_colors(ax.get_lines(), linecolors=[c]) + tm.close() + @slow def test_area_colors(self): from matplotlib import cm @@ -2972,6 +2728,10 @@ def test_hist_colors(self): ax = df.ix[:, [0]].plot(kind='hist', color='DodgerBlue') self._check_colors([ax.patches[0]], facecolors=['DodgerBlue']) + ax = df.plot(kind='hist', color='green') + self._check_colors(ax.patches[::10], facecolors=['green'] * 5) + tm.close() + @slow def test_kde_colors(self): tm._skip_if_no_scipy() @@ -2995,6 +2755,64 @@ def test_kde_colors(self): rgba_colors = lmap(cm.jet, np.linspace(0, 1, len(df))) self._check_colors(ax.get_lines(), linecolors=rgba_colors) + @slow + def test_kde_colors_and_styles_subplots(self): + tm._skip_if_no_scipy() + _skip_if_no_scipy_gaussian_kde() + + from matplotlib import cm + default_colors = self.plt.rcParams.get('axes.color_cycle') + + df = DataFrame(randn(5, 5)) + + axes = df.plot(kind='kde', subplots=True) + for ax, c in zip(axes, list(default_colors)): + self._check_colors(ax.get_lines(), linecolors=[c]) + tm.close() + + # single color char + axes = df.plot(kind='kde', color='k', subplots=True) + for ax in axes: + self._check_colors(ax.get_lines(), linecolors=['k']) + tm.close() + + # single color str + axes = df.plot(kind='kde', color='red', subplots=True) + for ax in axes: + self._check_colors(ax.get_lines(), linecolors=['red']) + tm.close() + + custom_colors = 'rgcby' + axes = df.plot(kind='kde', color=custom_colors, subplots=True) + for ax, c in zip(axes, list(custom_colors)): + self._check_colors(ax.get_lines(), linecolors=[c]) + tm.close() + + rgba_colors = lmap(cm.jet, np.linspace(0, 1, len(df))) + for cmap in ['jet', cm.jet]: + axes = df.plot(kind='kde', colormap=cmap, subplots=True) + for ax, c in zip(axes, rgba_colors): + self._check_colors(ax.get_lines(), linecolors=[c]) + tm.close() + + # make color a list if plotting one column frame + # handles cases like df.plot(color='DodgerBlue') + axes = df.ix[:, [0]].plot(kind='kde', color='DodgerBlue', subplots=True) + self._check_colors(axes[0].lines, linecolors=['DodgerBlue']) + + # single character style + axes = df.plot(kind='kde', style='r', subplots=True) + for ax in axes: + self._check_colors(ax.get_lines(), linecolors=['r']) + tm.close() + + # list of styles + styles = list('rgcby') + axes = df.plot(kind='kde', style=styles, subplots=True) + for ax, c in zip(axes, styles): + self._check_colors(ax.get_lines(), linecolors=[c]) + tm.close() + @slow def test_boxplot_colors(self): @@ -3070,7 +2888,7 @@ def test_unordered_ts(self): xticks = ax.lines[0].get_xdata() self.assertTrue(xticks[0] < xticks[1]) ydata = ax.lines[0].get_ydata() - assert_array_equal(ydata, np.array([1.0, 2.0, 3.0])) + tm.assert_numpy_array_equal(ydata, np.array([1.0, 2.0, 3.0])) def test_all_invalid_plot_data(self): df = DataFrame(list('abcd')) @@ -3463,6 +3281,35 @@ def test_sharey_and_ax(self): self.assertTrue(ax.yaxis.get_label().get_visible(), "y label is invisible but shouldn't") + def test_memory_leak(self): + """ Check that every plot type gets properly collected. """ + import weakref + import gc + + results = {} + for kind in plotting._plot_klass.keys(): + args = {} + if kind in ['hexbin', 'scatter', 'pie']: + df = self.hexbin_df + args = {'x': 'A', 'y': 'B'} + elif kind == 'area': + df = self.tdf.abs() + else: + df = self.tdf + + # Use a weakref so we can see if the object gets collected without + # also preventing it from being collected + results[kind] = weakref.proxy(df.plot(kind=kind, **args)) + + # have matplotlib delete all the figures + tm.close() + # force a garbage collection + gc.collect() + for key in results: + # check that every plot was collected + with tm.assertRaises(ReferenceError): + # need to actually access something to get an error + results[key].lines @slow def test_df_grid_settings(self): @@ -3470,392 +3317,6 @@ def test_df_grid_settings(self): self._check_grid_settings(DataFrame({'a':[1,2,3],'b':[2,3,4]}), plotting._dataframe_kinds, kws={'x':'a','y':'b'}) - -@tm.mplskip -class TestDataFrameGroupByPlots(TestPlotBase): - - @slow - def test_boxplot(self): - grouped = self.hist_df.groupby(by='gender') - with warnings.catch_warnings(): - warnings.simplefilter('ignore') - axes = _check_plot_works(grouped.boxplot, return_type='axes') - self._check_axes_shape(list(axes.values()), axes_num=2, layout=(1, 2)) - - axes = _check_plot_works(grouped.boxplot, subplots=False, - return_type='axes') - self._check_axes_shape(axes, axes_num=1, layout=(1, 1)) - tuples = lzip(string.ascii_letters[:10], range(10)) - df = DataFrame(np.random.rand(10, 3), - index=MultiIndex.from_tuples(tuples)) - - grouped = df.groupby(level=1) - axes = _check_plot_works(grouped.boxplot, return_type='axes') - self._check_axes_shape(list(axes.values()), axes_num=10, layout=(4, 3)) - - axes = _check_plot_works(grouped.boxplot, subplots=False, - return_type='axes') - self._check_axes_shape(axes, axes_num=1, layout=(1, 1)) - - grouped = df.unstack(level=1).groupby(level=0, axis=1) - axes = _check_plot_works(grouped.boxplot, return_type='axes') - self._check_axes_shape(list(axes.values()), axes_num=3, layout=(2, 2)) - - axes = _check_plot_works(grouped.boxplot, subplots=False, - return_type='axes') - self._check_axes_shape(axes, axes_num=1, layout=(1, 1)) - - @slow - def test_grouped_plot_fignums(self): - n = 10 - weight = Series(np.random.normal(166, 20, size=n)) - height = Series(np.random.normal(60, 10, size=n)) - with tm.RNGContext(42): - gender = tm.choice(['male', 'female'], size=n) - df = DataFrame({'height': height, 'weight': weight, 'gender': gender}) - gb = df.groupby('gender') - - res = gb.plot() - self.assertEqual(len(self.plt.get_fignums()), 2) - self.assertEqual(len(res), 2) - tm.close() - - res = gb.boxplot(return_type='axes') - self.assertEqual(len(self.plt.get_fignums()), 1) - self.assertEqual(len(res), 2) - tm.close() - - # now works with GH 5610 as gender is excluded - res = df.groupby('gender').hist() - tm.close() - - def test_series_plot_color_kwargs(self): - # GH1890 - ax = Series(np.arange(12) + 1).plot(color='green') - self._check_colors(ax.get_lines(), linecolors=['green']) - - def test_time_series_plot_color_kwargs(self): - # #1890 - ax = Series(np.arange(12) + 1, index=date_range( - '1/1/2000', periods=12)).plot(color='green') - self._check_colors(ax.get_lines(), linecolors=['green']) - - def test_time_series_plot_color_with_empty_kwargs(self): - import matplotlib as mpl - - def_colors = mpl.rcParams['axes.color_cycle'] - index = date_range('1/1/2000', periods=12) - s = Series(np.arange(1, 13), index=index) - - ncolors = 3 - - for i in range(ncolors): - ax = s.plot() - self._check_colors(ax.get_lines(), linecolors=def_colors[:ncolors]) - - @slow - def test_grouped_hist(self): - df = DataFrame(randn(500, 2), columns=['A', 'B']) - df['C'] = np.random.randint(0, 4, 500) - df['D'] = ['X'] * 500 - - axes = plotting.grouped_hist(df.A, by=df.C) - self._check_axes_shape(axes, axes_num=4, layout=(2, 2)) - - tm.close() - axes = df.hist(by=df.C) - self._check_axes_shape(axes, axes_num=4, layout=(2, 2)) - - tm.close() - # group by a key with single value - axes = df.hist(by='D', rot=30) - self._check_axes_shape(axes, axes_num=1, layout=(1, 1)) - self._check_ticks_props(axes, xrot=30) - - tm.close() - # make sure kwargs to hist are handled - xf, yf = 20, 18 - xrot, yrot = 30, 40 - axes = plotting.grouped_hist(df.A, by=df.C, normed=True, - cumulative=True, bins=4, - xlabelsize=xf, xrot=xrot, ylabelsize=yf, yrot=yrot) - # height of last bin (index 5) must be 1.0 - for ax in axes.ravel(): - height = ax.get_children()[5].get_height() - self.assertAlmostEqual(height, 1.0) - self._check_ticks_props(axes, xlabelsize=xf, xrot=xrot, - ylabelsize=yf, yrot=yrot) - - tm.close() - axes = plotting.grouped_hist(df.A, by=df.C, log=True) - # scale of y must be 'log' - self._check_ax_scales(axes, yaxis='log') - - tm.close() - # propagate attr exception from matplotlib.Axes.hist - with tm.assertRaises(AttributeError): - plotting.grouped_hist(df.A, by=df.C, foo='bar') - - with tm.assert_produces_warning(FutureWarning): - df.hist(by='C', figsize='default') - - @slow - def test_grouped_hist2(self): - n = 10 - weight = Series(np.random.normal(166, 20, size=n)) - height = Series(np.random.normal(60, 10, size=n)) - with tm.RNGContext(42): - gender_int = tm.choice([0, 1], size=n) - df_int = DataFrame({'height': height, 'weight': weight, - 'gender': gender_int}) - gb = df_int.groupby('gender') - axes = gb.hist() - self.assertEqual(len(axes), 2) - self.assertEqual(len(self.plt.get_fignums()), 2) - tm.close() - - @slow - def test_grouped_box_return_type(self): - df = self.hist_df - - # old style: return_type=None - result = df.boxplot(by='gender') - self.assertIsInstance(result, np.ndarray) - self._check_box_return_type(result, None, - expected_keys=['height', 'weight', 'category']) - - # now for groupby - with tm.assert_produces_warning(FutureWarning): - result = df.groupby('gender').boxplot() - self._check_box_return_type(result, 'dict', expected_keys=['Male', 'Female']) - - columns2 = 'X B C D A G Y N Q O'.split() - df2 = DataFrame(random.randn(50, 10), columns=columns2) - categories2 = 'A B C D E F G H I J'.split() - df2['category'] = categories2 * 5 - - for t in ['dict', 'axes', 'both']: - returned = df.groupby('classroom').boxplot(return_type=t) - self._check_box_return_type(returned, t, expected_keys=['A', 'B', 'C']) - - returned = df.boxplot(by='classroom', return_type=t) - self._check_box_return_type(returned, t, - expected_keys=['height', 'weight', 'category']) - - returned = df2.groupby('category').boxplot(return_type=t) - self._check_box_return_type(returned, t, expected_keys=categories2) - - returned = df2.boxplot(by='category', return_type=t) - self._check_box_return_type(returned, t, expected_keys=columns2) - - @slow - def test_grouped_box_layout(self): - df = self.hist_df - - self.assertRaises(ValueError, df.boxplot, column=['weight', 'height'], - by=df.gender, layout=(1, 1)) - self.assertRaises(ValueError, df.boxplot, column=['height', 'weight', 'category'], - layout=(2, 1), return_type='dict') - self.assertRaises(ValueError, df.boxplot, column=['weight', 'height'], - by=df.gender, layout=(-1, -1)) - - box = _check_plot_works(df.groupby('gender').boxplot, column='height', - return_type='dict') - self._check_axes_shape(self.plt.gcf().axes, axes_num=2, layout=(1, 2)) - - box = _check_plot_works(df.groupby('category').boxplot, column='height', - return_type='dict') - self._check_axes_shape(self.plt.gcf().axes, axes_num=4, layout=(2, 2)) - - # GH 6769 - box = _check_plot_works(df.groupby('classroom').boxplot, - column='height', return_type='dict') - self._check_axes_shape(self.plt.gcf().axes, axes_num=3, layout=(2, 2)) - - # GH 5897 - axes = df.boxplot(column=['height', 'weight', 'category'], by='gender', - return_type='axes') - self._check_axes_shape(self.plt.gcf().axes, axes_num=3, layout=(2, 2)) - for ax in [axes['height']]: - self._check_visible(ax.get_xticklabels(), visible=False) - self._check_visible([ax.xaxis.get_label()], visible=False) - for ax in [axes['weight'], axes['category']]: - self._check_visible(ax.get_xticklabels()) - self._check_visible([ax.xaxis.get_label()]) - - box = df.groupby('classroom').boxplot( - column=['height', 'weight', 'category'], return_type='dict') - self._check_axes_shape(self.plt.gcf().axes, axes_num=3, layout=(2, 2)) - - box = _check_plot_works(df.groupby('category').boxplot, column='height', - layout=(3, 2), return_type='dict') - self._check_axes_shape(self.plt.gcf().axes, axes_num=4, layout=(3, 2)) - box = _check_plot_works(df.groupby('category').boxplot, column='height', - layout=(3, -1), return_type='dict') - self._check_axes_shape(self.plt.gcf().axes, axes_num=4, layout=(3, 2)) - - box = df.boxplot(column=['height', 'weight', 'category'], by='gender', - layout=(4, 1)) - self._check_axes_shape(self.plt.gcf().axes, axes_num=3, layout=(4, 1)) - - box = df.boxplot(column=['height', 'weight', 'category'], by='gender', - layout=(-1, 1)) - self._check_axes_shape(self.plt.gcf().axes, axes_num=3, layout=(3, 1)) - - box = df.groupby('classroom').boxplot( - column=['height', 'weight', 'category'], layout=(1, 4), - return_type='dict') - self._check_axes_shape(self.plt.gcf().axes, axes_num=3, layout=(1, 4)) - - box = df.groupby('classroom').boxplot( - column=['height', 'weight', 'category'], layout=(1, -1), - return_type='dict') - self._check_axes_shape(self.plt.gcf().axes, axes_num=3, layout=(1, 3)) - - - @slow - def test_grouped_box_multiple_axes(self): - # GH 6970, GH 7069 - df = self.hist_df - - # check warning to ignore sharex / sharey - # this check should be done in the first function which - # passes multiple axes to plot, hist or boxplot - # location should be changed if other test is added - # which has earlier alphabetical order - with tm.assert_produces_warning(UserWarning): - fig, axes = self.plt.subplots(2, 2) - df.groupby('category').boxplot(column='height', return_type='axes', ax=axes) - self._check_axes_shape(self.plt.gcf().axes, axes_num=4, layout=(2, 2)) - - fig, axes = self.plt.subplots(2, 3) - with warnings.catch_warnings(): - warnings.simplefilter('ignore') - returned = df.boxplot(column=['height', 'weight', 'category'], - by='gender', return_type='axes', ax=axes[0]) - returned = np.array(list(returned.values())) - self._check_axes_shape(returned, axes_num=3, layout=(1, 3)) - self.assert_numpy_array_equal(returned, axes[0]) - self.assertIs(returned[0].figure, fig) - - # draw on second row - with warnings.catch_warnings(): - warnings.simplefilter('ignore') - returned = df.groupby('classroom').boxplot( - column=['height', 'weight', 'category'], - return_type='axes', ax=axes[1]) - returned = np.array(list(returned.values())) - self._check_axes_shape(returned, axes_num=3, layout=(1, 3)) - self.assert_numpy_array_equal(returned, axes[1]) - self.assertIs(returned[0].figure, fig) - - with tm.assertRaises(ValueError): - fig, axes = self.plt.subplots(2, 3) - # pass different number of axes from required - axes = df.groupby('classroom').boxplot(ax=axes) - - @slow - def test_grouped_hist_layout(self): - - df = self.hist_df - self.assertRaises(ValueError, df.hist, column='weight', by=df.gender, - layout=(1, 1)) - self.assertRaises(ValueError, df.hist, column='height', by=df.category, - layout=(1, 3)) - self.assertRaises(ValueError, df.hist, column='height', by=df.category, - layout=(-1, -1)) - - axes = _check_plot_works(df.hist, column='height', by=df.gender, - layout=(2, 1)) - self._check_axes_shape(axes, axes_num=2, layout=(2, 1)) - - axes = _check_plot_works(df.hist, column='height', by=df.gender, - layout=(2, -1)) - self._check_axes_shape(axes, axes_num=2, layout=(2, 1)) - - axes = df.hist(column='height', by=df.category, layout=(4, 1)) - self._check_axes_shape(axes, axes_num=4, layout=(4, 1)) - - axes = df.hist(column='height', by=df.category, layout=(-1, 1)) - self._check_axes_shape(axes, axes_num=4, layout=(4, 1)) - - axes = df.hist(column='height', by=df.category, layout=(4, 2), figsize=(12, 8)) - self._check_axes_shape(axes, axes_num=4, layout=(4, 2), figsize=(12, 8)) - tm.close() - - # GH 6769 - axes = _check_plot_works(df.hist, column='height', by='classroom', layout=(2, 2)) - self._check_axes_shape(axes, axes_num=3, layout=(2, 2)) - - # without column - axes = _check_plot_works(df.hist, by='classroom') - self._check_axes_shape(axes, axes_num=3, layout=(2, 2)) - - axes = df.hist(by='gender', layout=(3, 5)) - self._check_axes_shape(axes, axes_num=2, layout=(3, 5)) - - axes = df.hist(column=['height', 'weight', 'category']) - self._check_axes_shape(axes, axes_num=3, layout=(2, 2)) - - @slow - def test_grouped_hist_multiple_axes(self): - # GH 6970, GH 7069 - df = self.hist_df - - fig, axes = self.plt.subplots(2, 3) - returned = df.hist(column=['height', 'weight', 'category'], ax=axes[0]) - self._check_axes_shape(returned, axes_num=3, layout=(1, 3)) - self.assert_numpy_array_equal(returned, axes[0]) - self.assertIs(returned[0].figure, fig) - returned = df.hist(by='classroom', ax=axes[1]) - self._check_axes_shape(returned, axes_num=3, layout=(1, 3)) - self.assert_numpy_array_equal(returned, axes[1]) - self.assertIs(returned[0].figure, fig) - - with tm.assertRaises(ValueError): - fig, axes = self.plt.subplots(2, 3) - # pass different number of axes from required - axes = df.hist(column='height', ax=axes) - @slow - def test_axis_share_x(self): - df = self.hist_df - # GH4089 - ax1, ax2 = df.hist(column='height', by=df.gender, sharex=True) - - # share x - self.assertTrue(ax1._shared_x_axes.joined(ax1, ax2)) - self.assertTrue(ax2._shared_x_axes.joined(ax1, ax2)) - - # don't share y - self.assertFalse(ax1._shared_y_axes.joined(ax1, ax2)) - self.assertFalse(ax2._shared_y_axes.joined(ax1, ax2)) - - @slow - def test_axis_share_y(self): - df = self.hist_df - ax1, ax2 = df.hist(column='height', by=df.gender, sharey=True) - - # share y - self.assertTrue(ax1._shared_y_axes.joined(ax1, ax2)) - self.assertTrue(ax2._shared_y_axes.joined(ax1, ax2)) - - # don't share x - self.assertFalse(ax1._shared_x_axes.joined(ax1, ax2)) - self.assertFalse(ax2._shared_x_axes.joined(ax1, ax2)) - - @slow - def test_axis_share_xy(self): - df = self.hist_df - ax1, ax2 = df.hist(column='height', by=df.gender, sharex=True, - sharey=True) - - # share both x and y - self.assertTrue(ax1._shared_x_axes.joined(ax1, ax2)) - self.assertTrue(ax2._shared_x_axes.joined(ax1, ax2)) - - self.assertTrue(ax1._shared_y_axes.joined(ax1, ax2)) - self.assertTrue(ax2._shared_y_axes.joined(ax1, ax2)) - def test_option_mpl_style(self): set_option('display.mpl_style', 'default') set_option('display.mpl_style', None) @@ -3870,6 +3331,10 @@ def test_invalid_colormap(self): with tm.assertRaises(ValueError): df.plot(colormap='invalid_colormap') + +@tm.mplskip +class TestDataFrameGroupByPlots(TestPlotBase): + def test_series_groupby_plotting_nominally_works(self): n = 10 weight = Series(np.random.normal(166, 20, size=n)) diff --git a/pandas/tests/test_graphics_others.py b/pandas/tests/test_graphics_others.py new file mode 100644 index 0000000000000..f461a8ab624dc --- /dev/null +++ b/pandas/tests/test_graphics_others.py @@ -0,0 +1,913 @@ +#!/usr/bin/env python +# coding: utf-8 + +import nose +import itertools +import os +import string +import warnings +from distutils.version import LooseVersion + +from datetime import datetime, date + +from pandas import (Series, DataFrame, MultiIndex, PeriodIndex, date_range, + bdate_range) +from pandas.compat import (range, lrange, StringIO, lmap, lzip, u, zip, + iteritems, OrderedDict, PY3) +from pandas.util.decorators import cache_readonly +import pandas.core.common as com +import pandas.util.testing as tm +from pandas.util.testing import ensure_clean +from pandas.core.config import set_option + + +import numpy as np +from numpy import random +from numpy.random import rand, randn + +from numpy.testing import assert_array_equal, assert_allclose +from numpy.testing.decorators import slow +import pandas.tools.plotting as plotting + +from pandas.tests.test_graphics import (TestPlotBase, _check_plot_works, + curpath, _ok_for_gaussian_kde) + + +""" +These tests are for ``DataFrame.hist``, ``DataFrame.boxplot`` and +other miscellaneous plots. +`Dataframe.plot`` and ``Series.plot`` are tested in test_graphics.py +""" + + +def _skip_if_mpl_14_or_dev_boxplot(): + # GH 8382 + # Boxplot failures on 1.4 and 1.4.1 + # Don't need try / except since that's done at class level + import matplotlib + if str(matplotlib.__version__) >= LooseVersion('1.4'): + raise nose.SkipTest("Matplotlib Regression in 1.4 and current dev.") + + +@tm.mplskip +class TestSeriesPlots(TestPlotBase): + + def setUp(self): + TestPlotBase.setUp(self) + import matplotlib as mpl + mpl.rcdefaults() + + self.ts = tm.makeTimeSeries() + self.ts.name = 'ts' + + self.series = tm.makeStringSeries() + self.series.name = 'series' + + self.iseries = tm.makePeriodSeries() + self.iseries.name = 'iseries' + + @slow + def test_hist_legacy(self): + _check_plot_works(self.ts.hist) + _check_plot_works(self.ts.hist, grid=False) + _check_plot_works(self.ts.hist, figsize=(8, 10)) + _check_plot_works(self.ts.hist, by=self.ts.index.month) + _check_plot_works(self.ts.hist, by=self.ts.index.month, bins=5) + + fig, ax = self.plt.subplots(1, 1) + _check_plot_works(self.ts.hist, ax=ax) + _check_plot_works(self.ts.hist, ax=ax, figure=fig) + _check_plot_works(self.ts.hist, figure=fig) + tm.close() + + fig, (ax1, ax2) = self.plt.subplots(1, 2) + _check_plot_works(self.ts.hist, figure=fig, ax=ax1) + _check_plot_works(self.ts.hist, figure=fig, ax=ax2) + + with tm.assertRaises(ValueError): + self.ts.hist(by=self.ts.index, figure=fig) + + @slow + def test_hist_bins_legacy(self): + df = DataFrame(np.random.randn(10, 2)) + ax = df.hist(bins=2)[0][0] + self.assertEqual(len(ax.patches), 2) + + @slow + def test_hist_layout(self): + df = self.hist_df + with tm.assertRaises(ValueError): + df.height.hist(layout=(1, 1)) + + with tm.assertRaises(ValueError): + df.height.hist(layout=[1, 1]) + + @slow + def test_hist_layout_with_by(self): + df = self.hist_df + + axes = _check_plot_works(df.height.hist, by=df.gender, layout=(2, 1)) + self._check_axes_shape(axes, axes_num=2, layout=(2, 1)) + + axes = _check_plot_works(df.height.hist, by=df.gender, layout=(3, -1)) + self._check_axes_shape(axes, axes_num=2, layout=(3, 1)) + + axes = _check_plot_works(df.height.hist, by=df.category, layout=(4, 1)) + self._check_axes_shape(axes, axes_num=4, layout=(4, 1)) + + axes = _check_plot_works(df.height.hist, by=df.category, layout=(2, -1)) + self._check_axes_shape(axes, axes_num=4, layout=(2, 2)) + + axes = _check_plot_works(df.height.hist, by=df.category, layout=(3, -1)) + self._check_axes_shape(axes, axes_num=4, layout=(3, 2)) + + axes = _check_plot_works(df.height.hist, by=df.category, layout=(-1, 4)) + self._check_axes_shape(axes, axes_num=4, layout=(1, 4)) + + axes = _check_plot_works(df.height.hist, by=df.classroom, layout=(2, 2)) + self._check_axes_shape(axes, axes_num=3, layout=(2, 2)) + + axes = df.height.hist(by=df.category, layout=(4, 2), figsize=(12, 7)) + self._check_axes_shape(axes, axes_num=4, layout=(4, 2), figsize=(12, 7)) + + @slow + def test_hist_no_overlap(self): + from matplotlib.pyplot import subplot, gcf + x = Series(randn(2)) + y = Series(randn(2)) + subplot(121) + x.hist() + subplot(122) + y.hist() + fig = gcf() + axes = fig.get_axes() + self.assertEqual(len(axes), 2) + + @slow + def test_hist_by_no_extra_plots(self): + df = self.hist_df + axes = df.height.hist(by=df.gender) + self.assertEqual(len(self.plt.get_fignums()), 1) + + @slow + def test_plot_fails_when_ax_differs_from_figure(self): + from pylab import figure + fig1 = figure() + fig2 = figure() + ax1 = fig1.add_subplot(111) + with tm.assertRaises(AssertionError): + self.ts.hist(ax=ax1, figure=fig2) + + @slow + def test_autocorrelation_plot(self): + from pandas.tools.plotting import autocorrelation_plot + _check_plot_works(autocorrelation_plot, self.ts) + _check_plot_works(autocorrelation_plot, self.ts.values) + + ax = autocorrelation_plot(self.ts, label='Test') + self._check_legend_labels(ax, labels=['Test']) + + @slow + def test_lag_plot(self): + from pandas.tools.plotting import lag_plot + _check_plot_works(lag_plot, self.ts) + _check_plot_works(lag_plot, self.ts, lag=5) + + @slow + def test_bootstrap_plot(self): + from pandas.tools.plotting import bootstrap_plot + _check_plot_works(bootstrap_plot, self.ts, size=10) + + +@tm.mplskip +class TestDataFramePlots(TestPlotBase): + + def setUp(self): + TestPlotBase.setUp(self) + import matplotlib as mpl + mpl.rcdefaults() + + self.tdf = tm.makeTimeDataFrame() + self.hexbin_df = DataFrame({"A": np.random.uniform(size=20), + "B": np.random.uniform(size=20), + "C": np.arange(20) + np.random.uniform(size=20)}) + + from pandas import read_csv + path = os.path.join(curpath(), 'data', 'iris.csv') + self.iris = read_csv(path) + + @slow + def test_boxplot_legacy(self): + df = DataFrame(randn(6, 4), + index=list(string.ascii_letters[:6]), + columns=['one', 'two', 'three', 'four']) + df['indic'] = ['foo', 'bar'] * 3 + df['indic2'] = ['foo', 'bar', 'foo'] * 2 + + _check_plot_works(df.boxplot, return_type='dict') + _check_plot_works(df.boxplot, column=['one', 'two'], return_type='dict') + _check_plot_works(df.boxplot, column=['one', 'two'], by='indic') + _check_plot_works(df.boxplot, column='one', by=['indic', 'indic2']) + _check_plot_works(df.boxplot, by='indic') + _check_plot_works(df.boxplot, by=['indic', 'indic2']) + _check_plot_works(plotting.boxplot, df['one'], return_type='dict') + _check_plot_works(df.boxplot, notch=1, return_type='dict') + _check_plot_works(df.boxplot, by='indic', notch=1) + + df = DataFrame(np.random.rand(10, 2), columns=['Col1', 'Col2']) + df['X'] = Series(['A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B']) + df['Y'] = Series(['A'] * 10) + _check_plot_works(df.boxplot, by='X') + + # When ax is supplied and required number of axes is 1, + # passed ax should be used: + fig, ax = self.plt.subplots() + axes = df.boxplot('Col1', by='X', ax=ax) + self.assertIs(ax.get_axes(), axes) + + fig, ax = self.plt.subplots() + axes = df.groupby('Y').boxplot(ax=ax, return_type='axes') + self.assertIs(ax.get_axes(), axes['A']) + + # Multiple columns with an ax argument should use same figure + fig, ax = self.plt.subplots() + axes = df.boxplot(column=['Col1', 'Col2'], by='X', ax=ax, return_type='axes') + self.assertIs(axes['Col1'].get_figure(), fig) + + # When by is None, check that all relevant lines are present in the dict + fig, ax = self.plt.subplots() + d = df.boxplot(ax=ax, return_type='dict') + lines = list(itertools.chain.from_iterable(d.values())) + self.assertEqual(len(ax.get_lines()), len(lines)) + + @slow + def test_boxplot_return_type_legacy(self): + # API change in https://github.com/pydata/pandas/pull/7096 + import matplotlib as mpl + + df = DataFrame(randn(6, 4), + index=list(string.ascii_letters[:6]), + columns=['one', 'two', 'three', 'four']) + with tm.assertRaises(ValueError): + df.boxplot(return_type='NOTATYPE') + + with tm.assert_produces_warning(FutureWarning): + result = df.boxplot() + # change to Axes in future + self._check_box_return_type(result, 'dict') + + with tm.assert_produces_warning(False): + result = df.boxplot(return_type='dict') + self._check_box_return_type(result, 'dict') + + with tm.assert_produces_warning(False): + result = df.boxplot(return_type='axes') + self._check_box_return_type(result, 'axes') + + with tm.assert_produces_warning(False): + result = df.boxplot(return_type='both') + self._check_box_return_type(result, 'both') + + @slow + def test_boxplot_axis_limits(self): + + def _check_ax_limits(col, ax): + y_min, y_max = ax.get_ylim() + self.assertTrue(y_min <= col.min()) + self.assertTrue(y_max >= col.max()) + + df = self.hist_df.copy() + df['age'] = np.random.randint(1, 20, df.shape[0]) + # One full row + height_ax, weight_ax = df.boxplot(['height', 'weight'], by='category') + _check_ax_limits(df['height'], height_ax) + _check_ax_limits(df['weight'], weight_ax) + self.assertEqual(weight_ax._sharey, height_ax) + + # Two rows, one partial + p = df.boxplot(['height', 'weight', 'age'], by='category') + height_ax, weight_ax, age_ax = p[0, 0], p[0, 1], p[1, 0] + dummy_ax = p[1, 1] + _check_ax_limits(df['height'], height_ax) + _check_ax_limits(df['weight'], weight_ax) + _check_ax_limits(df['age'], age_ax) + self.assertEqual(weight_ax._sharey, height_ax) + self.assertEqual(age_ax._sharey, height_ax) + self.assertIsNone(dummy_ax._sharey) + + @slow + def test_boxplot_empty_column(self): + _skip_if_mpl_14_or_dev_boxplot() + df = DataFrame(np.random.randn(20, 4)) + df.loc[:, 0] = np.nan + _check_plot_works(df.boxplot, return_type='axes') + + @slow + def test_hist_df_legacy(self): + _check_plot_works(self.hist_df.hist) + + # make sure layout is handled + df = DataFrame(randn(100, 3)) + axes = _check_plot_works(df.hist, grid=False) + self._check_axes_shape(axes, axes_num=3, layout=(2, 2)) + self.assertFalse(axes[1, 1].get_visible()) + + df = DataFrame(randn(100, 1)) + _check_plot_works(df.hist) + + # make sure layout is handled + df = DataFrame(randn(100, 6)) + axes = _check_plot_works(df.hist, layout=(4, 2)) + self._check_axes_shape(axes, axes_num=6, layout=(4, 2)) + + # make sure sharex, sharey is handled + _check_plot_works(df.hist, sharex=True, sharey=True) + + # handle figsize arg + _check_plot_works(df.hist, figsize=(8, 10)) + + # check bins argument + _check_plot_works(df.hist, bins=5) + + # make sure xlabelsize and xrot are handled + ser = df[0] + xf, yf = 20, 18 + xrot, yrot = 30, 40 + axes = ser.hist(xlabelsize=xf, xrot=xrot, ylabelsize=yf, yrot=yrot) + self._check_ticks_props(axes, xlabelsize=xf, xrot=xrot, + ylabelsize=yf, yrot=yrot) + + xf, yf = 20, 18 + xrot, yrot = 30, 40 + axes = df.hist(xlabelsize=xf, xrot=xrot, ylabelsize=yf, yrot=yrot) + self._check_ticks_props(axes, xlabelsize=xf, xrot=xrot, + ylabelsize=yf, yrot=yrot) + + tm.close() + # make sure kwargs to hist are handled + ax = ser.hist(normed=True, cumulative=True, bins=4) + # height of last bin (index 5) must be 1.0 + self.assertAlmostEqual(ax.get_children()[5].get_height(), 1.0) + + tm.close() + ax = ser.hist(log=True) + # scale of y must be 'log' + self._check_ax_scales(ax, yaxis='log') + + tm.close() + + # propagate attr exception from matplotlib.Axes.hist + with tm.assertRaises(AttributeError): + ser.hist(foo='bar') + + @slow + def test_hist_layout(self): + df = DataFrame(randn(100, 3)) + + layout_to_expected_size = ( + {'layout': None, 'expected_size': (2, 2)}, # default is 2x2 + {'layout': (2, 2), 'expected_size': (2, 2)}, + {'layout': (4, 1), 'expected_size': (4, 1)}, + {'layout': (1, 4), 'expected_size': (1, 4)}, + {'layout': (3, 3), 'expected_size': (3, 3)}, + {'layout': (-1, 4), 'expected_size': (1, 4)}, + {'layout': (4, -1), 'expected_size': (4, 1)}, + {'layout': (-1, 2), 'expected_size': (2, 2)}, + {'layout': (2, -1), 'expected_size': (2, 2)} + ) + + for layout_test in layout_to_expected_size: + axes = df.hist(layout=layout_test['layout']) + expected = layout_test['expected_size'] + self._check_axes_shape(axes, axes_num=3, layout=expected) + + # layout too small for all 4 plots + with tm.assertRaises(ValueError): + df.hist(layout=(1, 1)) + + # invalid format for layout + with tm.assertRaises(ValueError): + df.hist(layout=(1,)) + with tm.assertRaises(ValueError): + df.hist(layout=(-1, -1)) + + @slow + def test_scatter_plot_legacy(self): + tm._skip_if_no_scipy() + + df = DataFrame(randn(100, 2)) + + def scat(**kwds): + return plotting.scatter_matrix(df, **kwds) + + _check_plot_works(scat) + _check_plot_works(scat, marker='+') + _check_plot_works(scat, vmin=0) + if _ok_for_gaussian_kde('kde'): + _check_plot_works(scat, diagonal='kde') + if _ok_for_gaussian_kde('density'): + _check_plot_works(scat, diagonal='density') + _check_plot_works(scat, diagonal='hist') + _check_plot_works(scat, range_padding=.1) + + def scat2(x, y, by=None, ax=None, figsize=None): + return plotting.scatter_plot(df, x, y, by, ax, figsize=None) + + _check_plot_works(scat2, 0, 1) + grouper = Series(np.repeat([1, 2, 3, 4, 5], 20), df.index) + _check_plot_works(scat2, 0, 1, by=grouper) + + def test_scatter_matrix_axis(self): + tm._skip_if_no_scipy() + scatter_matrix = plotting.scatter_matrix + + with tm.RNGContext(42): + df = DataFrame(randn(100, 3)) + + axes = _check_plot_works(scatter_matrix, df, range_padding=.1) + axes0_labels = axes[0][0].yaxis.get_majorticklabels() + # GH 5662 + expected = ['-2', '-1', '0', '1', '2'] + self._check_text_labels(axes0_labels, expected) + self._check_ticks_props(axes, xlabelsize=8, xrot=90, ylabelsize=8, yrot=0) + + df[0] = ((df[0] - 2) / 3) + axes = _check_plot_works(scatter_matrix, df, range_padding=.1) + axes0_labels = axes[0][0].yaxis.get_majorticklabels() + expected = ['-1.2', '-1.0', '-0.8', '-0.6', '-0.4', '-0.2', '0.0'] + self._check_text_labels(axes0_labels, expected) + self._check_ticks_props(axes, xlabelsize=8, xrot=90, ylabelsize=8, yrot=0) + + @slow + def test_andrews_curves(self): + from pandas.tools.plotting import andrews_curves + from matplotlib import cm + + df = self.iris + + _check_plot_works(andrews_curves, df, 'Name') + + rgba = ('#556270', '#4ECDC4', '#C7F464') + ax = _check_plot_works(andrews_curves, df, 'Name', color=rgba) + self._check_colors(ax.get_lines()[:10], linecolors=rgba, mapping=df['Name'][:10]) + + cnames = ['dodgerblue', 'aquamarine', 'seagreen'] + ax = _check_plot_works(andrews_curves, df, 'Name', color=cnames) + self._check_colors(ax.get_lines()[:10], linecolors=cnames, mapping=df['Name'][:10]) + + ax = _check_plot_works(andrews_curves, df, 'Name', colormap=cm.jet) + cmaps = lmap(cm.jet, np.linspace(0, 1, df['Name'].nunique())) + self._check_colors(ax.get_lines()[:10], linecolors=cmaps, mapping=df['Name'][:10]) + + colors = ['b', 'g', 'r'] + df = DataFrame({"A": [1, 2, 3], + "B": [1, 2, 3], + "C": [1, 2, 3], + "Name": colors}) + ax = andrews_curves(df, 'Name', color=colors) + handles, labels = ax.get_legend_handles_labels() + self._check_colors(handles, linecolors=colors) + + with tm.assert_produces_warning(FutureWarning): + andrews_curves(data=df, class_column='Name') + + @slow + def test_parallel_coordinates(self): + from pandas.tools.plotting import parallel_coordinates + from matplotlib import cm + + df = self.iris + + ax = _check_plot_works(parallel_coordinates, df, 'Name') + nlines = len(ax.get_lines()) + nxticks = len(ax.xaxis.get_ticklabels()) + + rgba = ('#556270', '#4ECDC4', '#C7F464') + ax = _check_plot_works(parallel_coordinates, df, 'Name', color=rgba) + self._check_colors(ax.get_lines()[:10], linecolors=rgba, mapping=df['Name'][:10]) + + cnames = ['dodgerblue', 'aquamarine', 'seagreen'] + ax = _check_plot_works(parallel_coordinates, df, 'Name', color=cnames) + self._check_colors(ax.get_lines()[:10], linecolors=cnames, mapping=df['Name'][:10]) + + ax = _check_plot_works(parallel_coordinates, df, 'Name', colormap=cm.jet) + cmaps = lmap(cm.jet, np.linspace(0, 1, df['Name'].nunique())) + self._check_colors(ax.get_lines()[:10], linecolors=cmaps, mapping=df['Name'][:10]) + + ax = _check_plot_works(parallel_coordinates, df, 'Name', axvlines=False) + assert len(ax.get_lines()) == (nlines - nxticks) + + colors = ['b', 'g', 'r'] + df = DataFrame({"A": [1, 2, 3], + "B": [1, 2, 3], + "C": [1, 2, 3], + "Name": colors}) + ax = parallel_coordinates(df, 'Name', color=colors) + handles, labels = ax.get_legend_handles_labels() + self._check_colors(handles, linecolors=colors) + + with tm.assert_produces_warning(FutureWarning): + parallel_coordinates(data=df, class_column='Name') + with tm.assert_produces_warning(FutureWarning): + parallel_coordinates(df, 'Name', colors=colors) + + @slow + def test_radviz(self): + from pandas.tools.plotting import radviz + from matplotlib import cm + + df = self.iris + _check_plot_works(radviz, df, 'Name') + + rgba = ('#556270', '#4ECDC4', '#C7F464') + ax = _check_plot_works(radviz, df, 'Name', color=rgba) + # skip Circle drawn as ticks + patches = [p for p in ax.patches[:20] if p.get_label() != ''] + self._check_colors(patches[:10], facecolors=rgba, mapping=df['Name'][:10]) + + cnames = ['dodgerblue', 'aquamarine', 'seagreen'] + _check_plot_works(radviz, df, 'Name', color=cnames) + patches = [p for p in ax.patches[:20] if p.get_label() != ''] + self._check_colors(patches, facecolors=cnames, mapping=df['Name'][:10]) + + _check_plot_works(radviz, df, 'Name', colormap=cm.jet) + cmaps = lmap(cm.jet, np.linspace(0, 1, df['Name'].nunique())) + patches = [p for p in ax.patches[:20] if p.get_label() != ''] + self._check_colors(patches, facecolors=cmaps, mapping=df['Name'][:10]) + + colors = [[0., 0., 1., 1.], + [0., 0.5, 1., 1.], + [1., 0., 0., 1.]] + df = DataFrame({"A": [1, 2, 3], + "B": [2, 1, 3], + "C": [3, 2, 1], + "Name": ['b', 'g', 'r']}) + ax = radviz(df, 'Name', color=colors) + handles, labels = ax.get_legend_handles_labels() + self._check_colors(handles, facecolors=colors) + + +@tm.mplskip +class TestDataFrameGroupByPlots(TestPlotBase): + + @slow + def test_boxplot_legacy(self): + grouped = self.hist_df.groupby(by='gender') + with warnings.catch_warnings(): + warnings.simplefilter('ignore') + axes = _check_plot_works(grouped.boxplot, return_type='axes') + self._check_axes_shape(list(axes.values()), axes_num=2, layout=(1, 2)) + + axes = _check_plot_works(grouped.boxplot, subplots=False, + return_type='axes') + self._check_axes_shape(axes, axes_num=1, layout=(1, 1)) + tuples = lzip(string.ascii_letters[:10], range(10)) + df = DataFrame(np.random.rand(10, 3), + index=MultiIndex.from_tuples(tuples)) + + grouped = df.groupby(level=1) + axes = _check_plot_works(grouped.boxplot, return_type='axes') + self._check_axes_shape(list(axes.values()), axes_num=10, layout=(4, 3)) + + axes = _check_plot_works(grouped.boxplot, subplots=False, + return_type='axes') + self._check_axes_shape(axes, axes_num=1, layout=(1, 1)) + + grouped = df.unstack(level=1).groupby(level=0, axis=1) + axes = _check_plot_works(grouped.boxplot, return_type='axes') + self._check_axes_shape(list(axes.values()), axes_num=3, layout=(2, 2)) + + axes = _check_plot_works(grouped.boxplot, subplots=False, + return_type='axes') + self._check_axes_shape(axes, axes_num=1, layout=(1, 1)) + + @slow + def test_grouped_plot_fignums(self): + n = 10 + weight = Series(np.random.normal(166, 20, size=n)) + height = Series(np.random.normal(60, 10, size=n)) + with tm.RNGContext(42): + gender = tm.choice(['male', 'female'], size=n) + df = DataFrame({'height': height, 'weight': weight, 'gender': gender}) + gb = df.groupby('gender') + + res = gb.plot() + self.assertEqual(len(self.plt.get_fignums()), 2) + self.assertEqual(len(res), 2) + tm.close() + + res = gb.boxplot(return_type='axes') + self.assertEqual(len(self.plt.get_fignums()), 1) + self.assertEqual(len(res), 2) + tm.close() + + # now works with GH 5610 as gender is excluded + res = df.groupby('gender').hist() + tm.close() + + @slow + def test_grouped_hist_legacy(self): + df = DataFrame(randn(500, 2), columns=['A', 'B']) + df['C'] = np.random.randint(0, 4, 500) + df['D'] = ['X'] * 500 + + axes = plotting.grouped_hist(df.A, by=df.C) + self._check_axes_shape(axes, axes_num=4, layout=(2, 2)) + + tm.close() + axes = df.hist(by=df.C) + self._check_axes_shape(axes, axes_num=4, layout=(2, 2)) + + tm.close() + # group by a key with single value + axes = df.hist(by='D', rot=30) + self._check_axes_shape(axes, axes_num=1, layout=(1, 1)) + self._check_ticks_props(axes, xrot=30) + + tm.close() + # make sure kwargs to hist are handled + xf, yf = 20, 18 + xrot, yrot = 30, 40 + axes = plotting.grouped_hist(df.A, by=df.C, normed=True, + cumulative=True, bins=4, + xlabelsize=xf, xrot=xrot, ylabelsize=yf, yrot=yrot) + # height of last bin (index 5) must be 1.0 + for ax in axes.ravel(): + height = ax.get_children()[5].get_height() + self.assertAlmostEqual(height, 1.0) + self._check_ticks_props(axes, xlabelsize=xf, xrot=xrot, + ylabelsize=yf, yrot=yrot) + + tm.close() + axes = plotting.grouped_hist(df.A, by=df.C, log=True) + # scale of y must be 'log' + self._check_ax_scales(axes, yaxis='log') + + tm.close() + # propagate attr exception from matplotlib.Axes.hist + with tm.assertRaises(AttributeError): + plotting.grouped_hist(df.A, by=df.C, foo='bar') + + with tm.assert_produces_warning(FutureWarning): + df.hist(by='C', figsize='default') + + @slow + def test_grouped_hist_legacy2(self): + n = 10 + weight = Series(np.random.normal(166, 20, size=n)) + height = Series(np.random.normal(60, 10, size=n)) + with tm.RNGContext(42): + gender_int = tm.choice([0, 1], size=n) + df_int = DataFrame({'height': height, 'weight': weight, + 'gender': gender_int}) + gb = df_int.groupby('gender') + axes = gb.hist() + self.assertEqual(len(axes), 2) + self.assertEqual(len(self.plt.get_fignums()), 2) + tm.close() + + @slow + def test_grouped_box_return_type(self): + df = self.hist_df + + # old style: return_type=None + result = df.boxplot(by='gender') + self.assertIsInstance(result, np.ndarray) + self._check_box_return_type(result, None, + expected_keys=['height', 'weight', 'category']) + + # now for groupby + with tm.assert_produces_warning(FutureWarning): + result = df.groupby('gender').boxplot() + self._check_box_return_type(result, 'dict', expected_keys=['Male', 'Female']) + + columns2 = 'X B C D A G Y N Q O'.split() + df2 = DataFrame(random.randn(50, 10), columns=columns2) + categories2 = 'A B C D E F G H I J'.split() + df2['category'] = categories2 * 5 + + for t in ['dict', 'axes', 'both']: + returned = df.groupby('classroom').boxplot(return_type=t) + self._check_box_return_type(returned, t, expected_keys=['A', 'B', 'C']) + + returned = df.boxplot(by='classroom', return_type=t) + self._check_box_return_type(returned, t, + expected_keys=['height', 'weight', 'category']) + + returned = df2.groupby('category').boxplot(return_type=t) + self._check_box_return_type(returned, t, expected_keys=categories2) + + returned = df2.boxplot(by='category', return_type=t) + self._check_box_return_type(returned, t, expected_keys=columns2) + + @slow + def test_grouped_box_layout(self): + df = self.hist_df + + self.assertRaises(ValueError, df.boxplot, column=['weight', 'height'], + by=df.gender, layout=(1, 1)) + self.assertRaises(ValueError, df.boxplot, column=['height', 'weight', 'category'], + layout=(2, 1), return_type='dict') + self.assertRaises(ValueError, df.boxplot, column=['weight', 'height'], + by=df.gender, layout=(-1, -1)) + + box = _check_plot_works(df.groupby('gender').boxplot, column='height', + return_type='dict') + self._check_axes_shape(self.plt.gcf().axes, axes_num=2, layout=(1, 2)) + + box = _check_plot_works(df.groupby('category').boxplot, column='height', + return_type='dict') + self._check_axes_shape(self.plt.gcf().axes, axes_num=4, layout=(2, 2)) + + # GH 6769 + box = _check_plot_works(df.groupby('classroom').boxplot, + column='height', return_type='dict') + self._check_axes_shape(self.plt.gcf().axes, axes_num=3, layout=(2, 2)) + + # GH 5897 + axes = df.boxplot(column=['height', 'weight', 'category'], by='gender', + return_type='axes') + self._check_axes_shape(self.plt.gcf().axes, axes_num=3, layout=(2, 2)) + for ax in [axes['height']]: + self._check_visible(ax.get_xticklabels(), visible=False) + self._check_visible([ax.xaxis.get_label()], visible=False) + for ax in [axes['weight'], axes['category']]: + self._check_visible(ax.get_xticklabels()) + self._check_visible([ax.xaxis.get_label()]) + + box = df.groupby('classroom').boxplot( + column=['height', 'weight', 'category'], return_type='dict') + self._check_axes_shape(self.plt.gcf().axes, axes_num=3, layout=(2, 2)) + + box = _check_plot_works(df.groupby('category').boxplot, column='height', + layout=(3, 2), return_type='dict') + self._check_axes_shape(self.plt.gcf().axes, axes_num=4, layout=(3, 2)) + box = _check_plot_works(df.groupby('category').boxplot, column='height', + layout=(3, -1), return_type='dict') + self._check_axes_shape(self.plt.gcf().axes, axes_num=4, layout=(3, 2)) + + box = df.boxplot(column=['height', 'weight', 'category'], by='gender', + layout=(4, 1)) + self._check_axes_shape(self.plt.gcf().axes, axes_num=3, layout=(4, 1)) + + box = df.boxplot(column=['height', 'weight', 'category'], by='gender', + layout=(-1, 1)) + self._check_axes_shape(self.plt.gcf().axes, axes_num=3, layout=(3, 1)) + + box = df.groupby('classroom').boxplot( + column=['height', 'weight', 'category'], layout=(1, 4), + return_type='dict') + self._check_axes_shape(self.plt.gcf().axes, axes_num=3, layout=(1, 4)) + + box = df.groupby('classroom').boxplot( + column=['height', 'weight', 'category'], layout=(1, -1), + return_type='dict') + self._check_axes_shape(self.plt.gcf().axes, axes_num=3, layout=(1, 3)) + + @slow + def test_grouped_box_multiple_axes(self): + # GH 6970, GH 7069 + df = self.hist_df + + # check warning to ignore sharex / sharey + # this check should be done in the first function which + # passes multiple axes to plot, hist or boxplot + # location should be changed if other test is added + # which has earlier alphabetical order + with tm.assert_produces_warning(UserWarning): + fig, axes = self.plt.subplots(2, 2) + df.groupby('category').boxplot(column='height', return_type='axes', ax=axes) + self._check_axes_shape(self.plt.gcf().axes, axes_num=4, layout=(2, 2)) + + fig, axes = self.plt.subplots(2, 3) + with warnings.catch_warnings(): + warnings.simplefilter('ignore') + returned = df.boxplot(column=['height', 'weight', 'category'], + by='gender', return_type='axes', ax=axes[0]) + returned = np.array(list(returned.values())) + self._check_axes_shape(returned, axes_num=3, layout=(1, 3)) + self.assert_numpy_array_equal(returned, axes[0]) + self.assertIs(returned[0].figure, fig) + + # draw on second row + with warnings.catch_warnings(): + warnings.simplefilter('ignore') + returned = df.groupby('classroom').boxplot( + column=['height', 'weight', 'category'], + return_type='axes', ax=axes[1]) + returned = np.array(list(returned.values())) + self._check_axes_shape(returned, axes_num=3, layout=(1, 3)) + self.assert_numpy_array_equal(returned, axes[1]) + self.assertIs(returned[0].figure, fig) + + with tm.assertRaises(ValueError): + fig, axes = self.plt.subplots(2, 3) + # pass different number of axes from required + axes = df.groupby('classroom').boxplot(ax=axes) + + @slow + def test_grouped_hist_layout(self): + df = self.hist_df + self.assertRaises(ValueError, df.hist, column='weight', by=df.gender, + layout=(1, 1)) + self.assertRaises(ValueError, df.hist, column='height', by=df.category, + layout=(1, 3)) + self.assertRaises(ValueError, df.hist, column='height', by=df.category, + layout=(-1, -1)) + + axes = _check_plot_works(df.hist, column='height', by=df.gender, + layout=(2, 1)) + self._check_axes_shape(axes, axes_num=2, layout=(2, 1)) + + axes = _check_plot_works(df.hist, column='height', by=df.gender, + layout=(2, -1)) + self._check_axes_shape(axes, axes_num=2, layout=(2, 1)) + + axes = df.hist(column='height', by=df.category, layout=(4, 1)) + self._check_axes_shape(axes, axes_num=4, layout=(4, 1)) + + axes = df.hist(column='height', by=df.category, layout=(-1, 1)) + self._check_axes_shape(axes, axes_num=4, layout=(4, 1)) + + axes = df.hist(column='height', by=df.category, layout=(4, 2), figsize=(12, 8)) + self._check_axes_shape(axes, axes_num=4, layout=(4, 2), figsize=(12, 8)) + tm.close() + + # GH 6769 + axes = _check_plot_works(df.hist, column='height', by='classroom', layout=(2, 2)) + self._check_axes_shape(axes, axes_num=3, layout=(2, 2)) + + # without column + axes = _check_plot_works(df.hist, by='classroom') + self._check_axes_shape(axes, axes_num=3, layout=(2, 2)) + + axes = df.hist(by='gender', layout=(3, 5)) + self._check_axes_shape(axes, axes_num=2, layout=(3, 5)) + + axes = df.hist(column=['height', 'weight', 'category']) + self._check_axes_shape(axes, axes_num=3, layout=(2, 2)) + + @slow + def test_grouped_hist_multiple_axes(self): + # GH 6970, GH 7069 + df = self.hist_df + + fig, axes = self.plt.subplots(2, 3) + returned = df.hist(column=['height', 'weight', 'category'], ax=axes[0]) + self._check_axes_shape(returned, axes_num=3, layout=(1, 3)) + self.assert_numpy_array_equal(returned, axes[0]) + self.assertIs(returned[0].figure, fig) + returned = df.hist(by='classroom', ax=axes[1]) + self._check_axes_shape(returned, axes_num=3, layout=(1, 3)) + self.assert_numpy_array_equal(returned, axes[1]) + self.assertIs(returned[0].figure, fig) + + with tm.assertRaises(ValueError): + fig, axes = self.plt.subplots(2, 3) + # pass different number of axes from required + axes = df.hist(column='height', ax=axes) + + @slow + def test_axis_share_x(self): + df = self.hist_df + # GH4089 + ax1, ax2 = df.hist(column='height', by=df.gender, sharex=True) + + # share x + self.assertTrue(ax1._shared_x_axes.joined(ax1, ax2)) + self.assertTrue(ax2._shared_x_axes.joined(ax1, ax2)) + + # don't share y + self.assertFalse(ax1._shared_y_axes.joined(ax1, ax2)) + self.assertFalse(ax2._shared_y_axes.joined(ax1, ax2)) + + @slow + def test_axis_share_y(self): + df = self.hist_df + ax1, ax2 = df.hist(column='height', by=df.gender, sharey=True) + + # share y + self.assertTrue(ax1._shared_y_axes.joined(ax1, ax2)) + self.assertTrue(ax2._shared_y_axes.joined(ax1, ax2)) + + # don't share x + self.assertFalse(ax1._shared_x_axes.joined(ax1, ax2)) + self.assertFalse(ax2._shared_x_axes.joined(ax1, ax2)) + + @slow + def test_axis_share_xy(self): + df = self.hist_df + ax1, ax2 = df.hist(column='height', by=df.gender, sharex=True, + sharey=True) + + # share both x and y + self.assertTrue(ax1._shared_x_axes.joined(ax1, ax2)) + self.assertTrue(ax2._shared_x_axes.joined(ax1, ax2)) + + self.assertTrue(ax1._shared_y_axes.joined(ax1, ax2)) + self.assertTrue(ax2._shared_y_axes.joined(ax1, ax2)) + + +if __name__ == '__main__': + nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'], + exit=False) diff --git a/pandas/tests/test_groupby.py b/pandas/tests/test_groupby.py index 576c5c6be890d..feb3c10a729ae 100644 --- a/pandas/tests/test_groupby.py +++ b/pandas/tests/test_groupby.py @@ -549,7 +549,7 @@ def func(dataf): return dataf["val2"] - dataf["val2"].mean() result = df1.groupby("val1", squeeze=True).apply(func) - tm.assert_isinstance(result,Series) + tm.assertIsInstance(result,Series) df2 = DataFrame([{"val1": 1, "val2" : 20}, {"val1":1, "val2": 19}, {"val1":1, "val2": 27}, {"val1":1, "val2": 12}]) @@ -557,12 +557,12 @@ def func(dataf): return dataf["val2"] - dataf["val2"].mean() result = df2.groupby("val1", squeeze=True).apply(func) - tm.assert_isinstance(result,Series) + tm.assertIsInstance(result,Series) # GH3596, return a consistent type (regression in 0.11 from 0.10.1) df = DataFrame([[1,1],[1,1]],columns=['X','Y']) result = df.groupby('X',squeeze=False).count() - tm.assert_isinstance(result,DataFrame) + tm.assertIsInstance(result,DataFrame) # GH5592 # inconcistent return type @@ -601,7 +601,7 @@ def f(grp): return grp.iloc[0] result = df.groupby('A').apply(f)[['C']] e = df.groupby('A').first()[['C']] - e.loc['Pony'] = np.nan + e.loc['Pony'] = pd.NaT assert_frame_equal(result,e) # scalar outputs @@ -670,7 +670,7 @@ def test_agg_period_index(self): prng = period_range('2012-1-1', freq='M', periods=3) df = DataFrame(np.random.randn(3, 2), index=prng) rs = df.groupby(level=0).sum() - tm.assert_isinstance(rs.index, PeriodIndex) + tm.assertIsInstance(rs.index, PeriodIndex) # GH 3579 index = period_range(start='1999-01', periods=5, freq='M') @@ -912,7 +912,7 @@ def test_aggregate_item_by_item(self): def aggfun(ser): return ser.size result = DataFrame().groupby(self.df.A).agg(aggfun) - tm.assert_isinstance(result, DataFrame) + tm.assertIsInstance(result, DataFrame) self.assertEqual(len(result), 0) def test_agg_item_by_item_raise_typeerror(self): @@ -1642,22 +1642,22 @@ def test_as_index_series_return_frame(self): result = grouped['C'].agg(np.sum) expected = grouped.agg(np.sum).ix[:, ['A', 'C']] - tm.assert_isinstance(result, DataFrame) + tm.assertIsInstance(result, DataFrame) assert_frame_equal(result, expected) result2 = grouped2['C'].agg(np.sum) expected2 = grouped2.agg(np.sum).ix[:, ['A', 'B', 'C']] - tm.assert_isinstance(result2, DataFrame) + tm.assertIsInstance(result2, DataFrame) assert_frame_equal(result2, expected2) result = grouped['C'].sum() expected = grouped.sum().ix[:, ['A', 'C']] - tm.assert_isinstance(result, DataFrame) + tm.assertIsInstance(result, DataFrame) assert_frame_equal(result, expected) result2 = grouped2['C'].sum() expected2 = grouped2.sum().ix[:, ['A', 'B', 'C']] - tm.assert_isinstance(result2, DataFrame) + tm.assertIsInstance(result2, DataFrame) assert_frame_equal(result2, expected2) # corner case @@ -2023,7 +2023,7 @@ def test_wrap_aggregated_output_multindex(self): keys = [np.array([0, 0, 1]), np.array([0, 0, 1])] agged = df.groupby(keys).agg(np.mean) - tm.assert_isinstance(agged.columns, MultiIndex) + tm.assertIsInstance(agged.columns, MultiIndex) def aggfun(ser): if ser.name == ('foo', 'one'): @@ -2181,7 +2181,7 @@ def f(piece): grouped = ts.groupby(lambda x: x.month) result = grouped.apply(f) - tm.assert_isinstance(result, DataFrame) + tm.assertIsInstance(result, DataFrame) self.assertTrue(result.index.equals(ts.index)) def test_apply_series_yield_constant(self): @@ -2779,11 +2779,11 @@ def convert_force_pure(x): result = grouped.agg(convert_fast) self.assertEqual(result.dtype, np.object_) - tm.assert_isinstance(result[0], Decimal) + tm.assertIsInstance(result[0], Decimal) result = grouped.agg(convert_force_pure) self.assertEqual(result.dtype, np.object_) - tm.assert_isinstance(result[0], Decimal) + tm.assertIsInstance(result[0], Decimal) def test_fast_apply(self): # make sure that fast apply is correctly called @@ -3225,7 +3225,7 @@ def g(group): result = self.df.groupby('A')['C'].apply(f) expected = self.df.groupby('A')['C'].apply(g) - tm.assert_isinstance(result, Series) + tm.assertIsInstance(result, Series) assert_series_equal(result, expected) def test_getitem_list_of_columns(self): @@ -3413,7 +3413,8 @@ def test_groupby_sort_categorical(self): col = 'range' assert_frame_equal(result_sort, df.groupby(col, sort=True).first()) - assert_frame_equal(result_nosort, df.groupby(col, sort=False).first()) + # when categories is ordered, group is ordered by category's order + assert_frame_equal(result_sort, df.groupby(col, sort=False).first()) df['range'] = Categorical(df['range'],ordered=False) index = Index(['(0, 2.5]', '(2.5, 5]', '(5, 7.5]', '(7.5, 10]'], dtype='object') @@ -3431,6 +3432,55 @@ def test_groupby_sort_categorical(self): assert_frame_equal(result_sort, df.groupby(col, sort=True).first()) assert_frame_equal(result_nosort, df.groupby(col, sort=False).first()) + def test_groupby_sort_categorical_datetimelike(self): + # GH10505 + + # use same data as test_groupby_sort_categorical, which category is + # corresponding to datetime.month + df = DataFrame({'dt': [datetime(2011, 7, 1), datetime(2011, 7, 1), + datetime(2011, 2, 1), datetime(2011, 5, 1), + datetime(2011, 2, 1), datetime(2011, 1, 1), + datetime(2011, 5, 1)], + 'foo': [10, 8, 5, 6, 4, 1, 7], + 'bar': [10, 20, 30, 40, 50, 60, 70]}, + columns=['dt', 'foo', 'bar']) + + # ordered=True + df['dt'] = Categorical(df['dt'], ordered=True) + index = [datetime(2011, 1, 1), datetime(2011, 2, 1), + datetime(2011, 5, 1), datetime(2011, 7, 1)] + result_sort = DataFrame([[1, 60], [5, 30], [6, 40], [10, 10]], columns=['foo', 'bar']) + result_sort.index = CategoricalIndex(index, name='dt', ordered=True) + + index = [datetime(2011, 7, 1), datetime(2011, 2, 1), + datetime(2011, 5, 1), datetime(2011, 1, 1)] + result_nosort = DataFrame([[10, 10], [5, 30], [6, 40], [1, 60]], + columns=['foo', 'bar']) + result_nosort.index = CategoricalIndex(index, categories=index, + name='dt', ordered=True) + + col = 'dt' + assert_frame_equal(result_sort, df.groupby(col, sort=True).first()) + # when categories is ordered, group is ordered by category's order + assert_frame_equal(result_sort, df.groupby(col, sort=False).first()) + + # ordered = False + df['dt'] = Categorical(df['dt'], ordered=False) + index = [datetime(2011, 1, 1), datetime(2011, 2, 1), + datetime(2011, 5, 1), datetime(2011, 7, 1)] + result_sort = DataFrame([[1, 60], [5, 30], [6, 40], [10, 10]], columns=['foo', 'bar']) + result_sort.index = CategoricalIndex(index, name='dt') + + index = [datetime(2011, 7, 1), datetime(2011, 2, 1), + datetime(2011, 5, 1), datetime(2011, 1, 1)] + result_nosort = DataFrame([[10, 10], [5, 30], [6, 40], [1, 60]], + columns=['foo', 'bar']) + result_nosort.index = CategoricalIndex(index, categories=index, name='dt') + + col = 'dt' + assert_frame_equal(result_sort, df.groupby(col, sort=True).first()) + assert_frame_equal(result_nosort, df.groupby(col, sort=False).first()) + def test_groupby_sort_multiindex_series(self): # series multiindex groupby sort argument was not being passed through _compress_group_index @@ -3453,7 +3503,7 @@ def test_groupby_categorical(self): levels = ['foo', 'bar', 'baz', 'qux'] codes = np.random.randint(0, 4, size=100) - cats = Categorical.from_codes(codes, levels, name='myfactor', ordered=True) + cats = Categorical.from_codes(codes, levels, ordered=True) data = DataFrame(np.random.randn(100, 4)) @@ -3461,10 +3511,8 @@ def test_groupby_categorical(self): expected = data.groupby(np.asarray(cats)).mean() expected = expected.reindex(levels) - expected.index.name = 'myfactor' assert_frame_equal(result, expected) - self.assertEqual(result.index.name, cats.name) grouped = data.groupby(cats) desc_result = grouped.describe() @@ -3473,35 +3521,52 @@ def test_groupby_categorical(self): ord_labels = np.asarray(cats).take(idx) ord_data = data.take(idx) expected = ord_data.groupby(ord_labels, sort=False).describe() - expected.index.names = ['myfactor', None] + expected.index.names = [None, None] assert_frame_equal(desc_result, expected) + # GH 10460 + expc = Categorical.from_codes(np.arange(4).repeat(8), levels, ordered=True) + exp = CategoricalIndex(expc) + self.assert_index_equal(desc_result.index.get_level_values(0), exp) + exp = Index(['count', 'mean', 'std', 'min', '25%', '50%', '75%', 'max'] * 4) + self.assert_index_equal(desc_result.index.get_level_values(1), exp) + def test_groupby_datetime_categorical(self): # GH9049: ensure backward compatibility levels = pd.date_range('2014-01-01', periods=4) codes = np.random.randint(0, 4, size=100) - cats = Categorical.from_codes(codes, levels, name='myfactor', ordered=True) + cats = Categorical.from_codes(codes, levels, ordered=True) data = DataFrame(np.random.randn(100, 4)) result = data.groupby(cats).mean() expected = data.groupby(np.asarray(cats)).mean() expected = expected.reindex(levels) - expected.index = CategoricalIndex(expected.index,categories=expected.index,name='myfactor',ordered=True) + expected.index = CategoricalIndex(expected.index, categories=expected.index, + ordered=True) assert_frame_equal(result, expected) - self.assertEqual(result.index.name, cats.name) grouped = data.groupby(cats) desc_result = grouped.describe() idx = cats.codes.argsort() - ord_labels = np.asarray(cats).take(idx) + ord_labels = cats.take_nd(idx) ord_data = data.take(idx) - expected = ord_data.groupby(ord_labels, sort=False).describe() - expected.index.names = ['myfactor', None] + expected = ord_data.groupby(ord_labels).describe() + expected.index.names = [None, None] assert_frame_equal(desc_result, expected) + tm.assert_index_equal(desc_result.index, expected.index) + tm.assert_index_equal(desc_result.index.get_level_values(0), expected.index.get_level_values(0)) + + # GH 10460 + expc = Categorical.from_codes(np.arange(4).repeat(8), levels, ordered=True) + exp = CategoricalIndex(expc) + self.assert_index_equal(desc_result.index.get_level_values(0), exp) + exp = Index(['count', 'mean', 'std', 'min', '25%', '50%', '75%', 'max'] * 4) + self.assert_index_equal(desc_result.index.get_level_values(1), exp) + def test_groupby_categorical_index(self): @@ -3534,7 +3599,7 @@ def test_groupby_groups_datetimeindex(self): # it works! groups = grouped.groups - tm.assert_isinstance(list(groups.keys())[0], datetime) + tm.assertIsInstance(list(groups.keys())[0], datetime) def test_groupby_groups_datetimeindex_tz(self): # GH 3950 @@ -3670,7 +3735,7 @@ def test_groupby_categorical_no_compress(self): result = data.groupby("b").mean() result = result["a"].values exp = np.array([1,2,4,np.nan]) - self.assert_numpy_array_equivalent(result, exp) + self.assert_numpy_array_equal(result, exp) def test_groupby_non_arithmetic_agg_types(self): # GH9311, GH6620 @@ -4412,6 +4477,32 @@ def test_filter_maintains_ordering(self): expected = s.iloc[[1, 2, 4, 7]] assert_series_equal(actual, expected) + def test_filter_multiple_timestamp(self): + # GH 10114 + df = DataFrame({'A' : np.arange(5,dtype='int64'), + 'B' : ['foo','bar','foo','bar','bar'], + 'C' : Timestamp('20130101') }) + + grouped = df.groupby(['B', 'C']) + + result = grouped['A'].filter(lambda x: True) + assert_series_equal(df['A'], result) + + result = grouped['A'].transform(len) + expected = Series([2, 3, 2, 3, 3], name='A') + assert_series_equal(result, expected) + + result = grouped.filter(lambda x: True) + assert_frame_equal(df, result) + + result = grouped.transform('sum') + expected = DataFrame({'A' : [2, 8, 2, 8, 8]}) + assert_frame_equal(result, expected) + + result = grouped.transform(len) + expected = DataFrame({'A' : [2, 3, 2, 3, 3]}) + assert_frame_equal(result, expected) + def test_filter_and_transform_with_non_unique_int_index(self): # GH4620 index = [1, 1, 1, 2, 1, 1, 0, 1] @@ -4793,7 +4884,7 @@ def test_groupby_whitelist(self): 'fillna', 'mad', 'any', 'all', - 'irow', 'take', + 'take', 'idxmax', 'idxmin', 'shift', 'tshift', 'ffill', 'bfill', @@ -4814,7 +4905,7 @@ def test_groupby_whitelist(self): 'fillna', 'mad', 'any', 'all', - 'irow', 'take', + 'take', 'idxmax', 'idxmin', 'shift', 'tshift', 'ffill', 'bfill', @@ -4839,6 +4930,20 @@ def test_groupby_whitelist(self): 'mad', 'std', 'var', 'sem'] AGG_FUNCTIONS_WITH_SKIPNA = ['skew', 'mad'] + def test_groupby_whitelist_deprecations(self): + from string import ascii_lowercase + letters = np.array(list(ascii_lowercase)) + N = 10 + random_letters = letters.take(np.random.randint(0, 26, N)) + df = DataFrame({'floats': N / 10 * Series(np.random.random(N)), + 'letters': Series(random_letters)}) + + # 10711 deprecated + with tm.assert_produces_warning(FutureWarning): + df.groupby('letters').irow(0) + with tm.assert_produces_warning(FutureWarning): + df.groupby('letters').floats.irow(0) + def test_regression_whitelist_methods(self) : # GH6944 @@ -4909,16 +5014,17 @@ def test_tab_completion(self): grp = self.mframe.groupby(level='second') results = set([v for v in dir(grp) if not v.startswith('_')]) expected = set(['A','B','C', - 'agg','aggregate','apply','boxplot','filter','first','get_group', - 'groups','hist','indices','last','max','mean','median', - 'min','name','ngroups','nth','ohlc','plot', 'prod', - 'size', 'std', 'sum', 'transform', 'var', 'sem', 'count', 'head', - 'describe', 'cummax', 'quantile', 'rank', 'cumprod', 'tail', - 'resample', 'cummin', 'fillna', 'cumsum', 'cumcount', - 'all', 'shift', 'skew', 'bfill', 'irow', 'ffill', - 'take', 'tshift', 'pct_change', 'any', 'mad', 'corr', 'corrwith', - 'cov', 'dtypes', 'diff', 'idxmax', 'idxmin' - ]) + 'agg','aggregate','apply','boxplot','filter','first','get_group', + 'groups','hist','indices','last','max','mean','median', + 'min','name','ngroups','nth','ohlc','plot', 'prod', + 'size', 'std', 'sum', 'transform', 'var', 'sem', 'count', 'head', + 'irow', + 'describe', 'cummax', 'quantile', 'rank', 'cumprod', 'tail', + 'resample', 'cummin', 'fillna', 'cumsum', 'cumcount', + 'all', 'shift', 'skew', 'bfill', 'ffill', + 'take', 'tshift', 'pct_change', 'any', 'mad', 'corr', 'corrwith', + 'cov', 'dtypes', 'diff', 'idxmax', 'idxmin' + ]) self.assertEqual(results, expected) def test_lexsort_indexer(self): diff --git a/pandas/tests/test_index.py b/pandas/tests/test_index.py index f422c3b49b691..35de75c6cdf02 100644 --- a/pandas/tests/test_index.py +++ b/pandas/tests/test_index.py @@ -10,7 +10,6 @@ import os import numpy as np -from numpy.testing import assert_array_equal from pandas import (period_range, date_range, Categorical, Series, Index, Float64Index, Int64Index, MultiIndex, @@ -101,7 +100,7 @@ def test_reindex_base(self): expected = np.arange(idx.size) actual = idx.get_indexer(idx) - assert_array_equal(expected, actual) + tm.assert_numpy_array_equal(expected, actual) with tm.assertRaisesRegexp(ValueError, 'Invalid fill method'): idx.get_indexer(idx, method='invalid') @@ -133,6 +132,15 @@ def test_str(self): self.assertTrue("'foo'" in str(idx)) self.assertTrue(idx.__class__.__name__ in str(idx)) + def test_dtype_str(self): + for idx in self.indices.values(): + dtype = idx.dtype_str + self.assertIsInstance(dtype, compat.string_types) + if isinstance(idx, PeriodIndex): + self.assertEqual(dtype, 'period') + else: + self.assertEqual(dtype, str(idx.dtype)) + def test_repr_max_seq_item_setting(self): # GH10182 idx = self.create_index() @@ -207,10 +215,19 @@ def test_duplicates(self): if not len(ind): continue + if isinstance(ind, MultiIndex): + continue idx = self._holder([ind[0]]*5) self.assertFalse(idx.is_unique) self.assertTrue(idx.has_duplicates) + # GH 10115 + # preserve names + idx.name = 'foo' + result = idx.drop_duplicates() + self.assertEqual(result.name, 'foo') + self.assert_index_equal(result, Index([ind[0]],name='foo')) + def test_sort(self): for ind in self.indices.values(): self.assertRaises(TypeError, ind.sort) @@ -239,7 +256,7 @@ def test_argsort(self): result = ind.argsort() expected = np.array(ind).argsort() - self.assert_numpy_array_equal(result, expected) + tm.assert_numpy_array_equal(result, expected) def test_pickle(self): for ind in self.indices.values(): @@ -259,6 +276,11 @@ def test_take(self): expected = ind[indexer] self.assertTrue(result.equals(expected)) + if not isinstance(ind, (DatetimeIndex, PeriodIndex, TimedeltaIndex)): + # GH 10791 + with tm.assertRaises(AttributeError): + ind.freq + def test_setops_errorcases(self): for name, idx in compat.iteritems(self.indices): # # non-iterable input @@ -349,7 +371,7 @@ def test_difference_base(self): pass elif isinstance(idx, (DatetimeIndex, TimedeltaIndex)): self.assertEqual(result.__class__, answer.__class__) - self.assert_numpy_array_equal(result.asi8, answer.asi8) + tm.assert_numpy_array_equal(result.asi8, answer.asi8) else: result = first.difference(case) self.assertTrue(tm.equalContents(result, answer)) @@ -388,6 +410,99 @@ def test_symmetric_diff(self): with tm.assertRaisesRegexp(TypeError, msg): result = first.sym_diff([1, 2, 3]) + def test_insert_base(self): + + for name, idx in compat.iteritems(self.indices): + result = idx[1:4] + + if not len(idx): + continue + + #test 0th element + self.assertTrue(idx[0:4].equals( + result.insert(0, idx[0]))) + + def test_delete_base(self): + + for name, idx in compat.iteritems(self.indices): + + if not len(idx): + continue + + expected = idx[1:] + result = idx.delete(0) + self.assertTrue(result.equals(expected)) + self.assertEqual(result.name, expected.name) + + expected = idx[:-1] + result = idx.delete(-1) + self.assertTrue(result.equals(expected)) + self.assertEqual(result.name, expected.name) + + with tm.assertRaises((IndexError, ValueError)): + # either depending on numpy version + result = idx.delete(len(idx)) + + def test_equals_op(self): + # GH9947, GH10637 + index_a = self.create_index() + if isinstance(index_a, PeriodIndex): + return + + n = len(index_a) + index_b = index_a[0:-1] + index_c = index_a[0:-1].append(index_a[-2:-1]) + index_d = index_a[0:1] + with tm.assertRaisesRegexp(ValueError, "Lengths must match"): + index_a == index_b + expected1 = np.array([True] * n) + expected2 = np.array([True] * (n - 1) + [False]) + tm.assert_numpy_array_equal(index_a == index_a, expected1) + tm.assert_numpy_array_equal(index_a == index_c, expected2) + + # test comparisons with numpy arrays + array_a = np.array(index_a) + array_b = np.array(index_a[0:-1]) + array_c = np.array(index_a[0:-1].append(index_a[-2:-1])) + array_d = np.array(index_a[0:1]) + with tm.assertRaisesRegexp(ValueError, "Lengths must match"): + index_a == array_b + tm.assert_numpy_array_equal(index_a == array_a, expected1) + tm.assert_numpy_array_equal(index_a == array_c, expected2) + + # test comparisons with Series + series_a = Series(array_a) + series_b = Series(array_b) + series_c = Series(array_c) + series_d = Series(array_d) + with tm.assertRaisesRegexp(ValueError, "Lengths must match"): + index_a == series_b + tm.assert_numpy_array_equal(index_a == series_a, expected1) + tm.assert_numpy_array_equal(index_a == series_c, expected2) + + # cases where length is 1 for one of them + with tm.assertRaisesRegexp(ValueError, "Lengths must match"): + index_a == index_d + with tm.assertRaisesRegexp(ValueError, "Lengths must match"): + index_a == series_d + with tm.assertRaisesRegexp(ValueError, "Lengths must match"): + index_a == array_d + with tm.assertRaisesRegexp(ValueError, "Series lengths must match"): + series_a == series_d + with tm.assertRaisesRegexp(ValueError, "Lengths must match"): + series_a == array_d + + # comparing with a scalar should broadcast; note that we are excluding + # MultiIndex because in this case each item in the index is a tuple of + # length 2, and therefore is considered an array of length 2 in the + # comparison instead of a scalar + if not isinstance(index_a, MultiIndex): + expected3 = np.array([False] * (len(index_a) - 2) + [True, False]) + # assuming the 2nd to last item is unique in the data + item = index_a[-2] + tm.assert_numpy_array_equal(index_a == item, expected3) + tm.assert_numpy_array_equal(series_a == item, expected3) + class TestIndex(Base, tm.TestCase): _holder = Index @@ -416,7 +531,7 @@ def create_index(self): def test_new_axis(self): new_index = self.dateIndex[None, :] self.assertEqual(new_index.ndim, 2) - tm.assert_isinstance(new_index, np.ndarray) + tm.assertIsInstance(new_index, np.ndarray) def test_copy_and_deepcopy(self): super(TestIndex, self).test_copy_and_deepcopy() @@ -433,14 +548,14 @@ def test_constructor(self): arr = np.array(self.strIndex) index = Index(arr) tm.assert_contains_all(arr, index) - self.assert_numpy_array_equal(self.strIndex, index) + tm.assert_numpy_array_equal(self.strIndex, index) # copy arr = np.array(self.strIndex) index = Index(arr, copy=True, name='name') - tm.assert_isinstance(index, Index) + tm.assertIsInstance(index, Index) self.assertEqual(index.name, 'name') - assert_array_equal(arr, index) + tm.assert_numpy_array_equal(arr, index) arr[0] = "SOMEBIGLONGSTRING" self.assertNotEqual(index[0], "SOMEBIGLONGSTRING") @@ -452,6 +567,15 @@ def test_constructor_corner(self): # corner case self.assertRaises(TypeError, Index, 0) + def test_consruction_list_mixed_tuples(self): + # 10697 + # if we are constructing from a mixed list of tuples, make sure that we + # are independent of the sorting order + idx1 = Index([('A',1),'B']) + self.assertIsInstance(idx1, Index) and self.assertNotInstance(idx1, MultiIndex) + idx2 = Index(['B',('A',1)]) + self.assertIsInstance(idx2, Index) and self.assertNotInstance(idx2, MultiIndex) + def test_constructor_from_series(self): expected = DatetimeIndex([Timestamp('20110101'),Timestamp('20120101'),Timestamp('20130101')]) @@ -497,8 +621,8 @@ def __array__(self, dtype=None): def test_index_ctor_infer_periodindex(self): xp = period_range('2012-1-1', freq='M', periods=3) rs = Index(xp) - assert_array_equal(rs, xp) - tm.assert_isinstance(rs, PeriodIndex) + tm.assert_numpy_array_equal(rs, xp) + tm.assertIsInstance(rs, PeriodIndex) def test_constructor_simple_new(self): idx = Index([1, 2, 3, 4, 5], name='int') @@ -655,7 +779,7 @@ def test_asof(self): self.assertEqual(self.dateIndex.asof(d + timedelta(1)), d) d = self.dateIndex[0].to_datetime() - tm.assert_isinstance(self.dateIndex.asof(d), Timestamp) + tm.assertIsInstance(self.dateIndex.asof(d), Timestamp) def test_asof_datetime_partial(self): idx = pd.date_range('2010-01-01', periods=2, freq='m') @@ -688,7 +812,7 @@ def _check(op): index_result = op(index, element) self.assertIsInstance(index_result, np.ndarray) - self.assert_numpy_array_equal(arr_result, index_result) + tm.assert_numpy_array_equal(arr_result, index_result) _check(operator.eq) _check(operator.ne) @@ -746,10 +870,10 @@ def test_shift(self): self.assertIs(shifted, self.dateIndex) shifted = self.dateIndex.shift(5, timedelta(1)) - self.assert_numpy_array_equal(shifted, self.dateIndex + timedelta(5)) + tm.assert_numpy_array_equal(shifted, self.dateIndex + timedelta(5)) shifted = self.dateIndex.shift(1, 'B') - self.assert_numpy_array_equal(shifted, self.dateIndex + offsets.BDay()) + tm.assert_numpy_array_equal(shifted, self.dateIndex + offsets.BDay()) shifted.name = 'shifted' self.assertEqual(shifted.name, shifted.shift(1, 'D').name) @@ -1013,7 +1137,7 @@ def test_format(self): # windows has different precision on datetime.datetime.now (it doesn't include us # since the default for Timestamp shows these but Index formating does not # we are skipping - if not is_platform_windows: + if not is_platform_windows(): formatted = index.format() expected = [str(index[0])] self.assertEqual(formatted, expected) @@ -1096,17 +1220,37 @@ def test_get_indexer(self): r2 = idx2.get_indexer(idx1[::-1], method='backfill') assert_almost_equal(r2, e1[::-1]) + def test_get_indexer_invalid(self): + # GH10411 + idx = Index(np.arange(10)) + + with tm.assertRaisesRegexp(ValueError, 'tolerance argument'): + idx.get_indexer([1, 0], tolerance=1) + + with tm.assertRaisesRegexp(ValueError, 'limit argument'): + idx.get_indexer([1, 0], limit=1) + def test_get_indexer_nearest(self): idx = Index(np.arange(10)) all_methods = ['pad', 'backfill', 'nearest'] for method in all_methods: actual = idx.get_indexer([0, 5, 9], method=method) - self.assert_array_equal(actual, [0, 5, 9]) + tm.assert_numpy_array_equal(actual, [0, 5, 9]) + + actual = idx.get_indexer([0, 5, 9], method=method, tolerance=0) + tm.assert_numpy_array_equal(actual, [0, 5, 9]) for method, expected in zip(all_methods, [[0, 1, 8], [1, 2, 9], [0, 2, 9]]): actual = idx.get_indexer([0.2, 1.8, 8.5], method=method) - self.assert_array_equal(actual, expected) + tm.assert_numpy_array_equal(actual, expected) + + actual = idx.get_indexer([0.2, 1.8, 8.5], method=method, tolerance=1) + tm.assert_numpy_array_equal(actual, expected) + + for method, expected in zip(all_methods, [[0, -1, -1], [-1, 2, -1], [0, 2, -1]]): + actual = idx.get_indexer([0.2, 1.8, 8.5], method=method, tolerance=0.2) + tm.assert_numpy_array_equal(actual, expected) with tm.assertRaisesRegexp(ValueError, 'limit argument'): idx.get_indexer([1, 0], method='nearest', limit=1) @@ -1117,40 +1261,59 @@ def test_get_indexer_nearest_decreasing(self): all_methods = ['pad', 'backfill', 'nearest'] for method in all_methods: actual = idx.get_indexer([0, 5, 9], method=method) - self.assert_array_equal(actual, [9, 4, 0]) + tm.assert_numpy_array_equal(actual, [9, 4, 0]) for method, expected in zip(all_methods, [[8, 7, 0], [9, 8, 1], [9, 7, 0]]): actual = idx.get_indexer([0.2, 1.8, 8.5], method=method) - self.assert_array_equal(actual, expected) + tm.assert_numpy_array_equal(actual, expected) def test_get_indexer_strings(self): idx = pd.Index(['b', 'c']) actual = idx.get_indexer(['a', 'b', 'c', 'd'], method='pad') expected = [-1, 0, 1, 1] - self.assert_array_equal(actual, expected) + tm.assert_numpy_array_equal(actual, expected) actual = idx.get_indexer(['a', 'b', 'c', 'd'], method='backfill') expected = [0, 0, 1, -1] - self.assert_array_equal(actual, expected) + tm.assert_numpy_array_equal(actual, expected) with tm.assertRaises(TypeError): idx.get_indexer(['a', 'b', 'c', 'd'], method='nearest') + with tm.assertRaises(TypeError): + idx.get_indexer(['a', 'b', 'c', 'd'], method='pad', tolerance=2) + def test_get_loc(self): idx = pd.Index([0, 1, 2]) all_methods = [None, 'pad', 'backfill', 'nearest'] for method in all_methods: self.assertEqual(idx.get_loc(1, method=method), 1) + if method is not None: + self.assertEqual(idx.get_loc(1, method=method, tolerance=0), 1) with tm.assertRaises(TypeError): idx.get_loc([1, 2], method=method) for method, loc in [('pad', 1), ('backfill', 2), ('nearest', 1)]: self.assertEqual(idx.get_loc(1.1, method), loc) + for method, loc in [('pad', 1), ('backfill', 2), ('nearest', 1)]: + self.assertEqual(idx.get_loc(1.1, method, tolerance=1), loc) + + for method in ['pad', 'backfill', 'nearest']: + with tm.assertRaises(KeyError): + idx.get_loc(1.1, method, tolerance=0.05) + + with tm.assertRaisesRegexp(ValueError, 'must be numeric'): + idx.get_loc(1.1, 'nearest', tolerance='invalid') + with tm.assertRaisesRegexp(ValueError, 'tolerance .* valid if'): + idx.get_loc(1.1, tolerance=1) + idx = pd.Index(['a', 'c']) with tm.assertRaises(TypeError): idx.get_loc('a', method='nearest') + with tm.assertRaises(TypeError): + idx.get_loc('a', method='pad', tolerance='invalid') def test_slice_locs(self): for dtype in [int, float]: @@ -1331,7 +1494,7 @@ def test_isin(self): idx = Index(['qux', 'baz', 'foo', 'bar']) result = idx.isin(values) expected = np.array([False, False, True, True]) - self.assert_numpy_array_equal(result, expected) + tm.assert_numpy_array_equal(result, expected) # empty, return dtype bool idx = Index([]) @@ -1340,20 +1503,20 @@ def test_isin(self): self.assertEqual(result.dtype, np.bool_) def test_isin_nan(self): - self.assert_numpy_array_equal( + tm.assert_numpy_array_equal( Index(['a', np.nan]).isin([np.nan]), [False, True]) - self.assert_numpy_array_equal( + tm.assert_numpy_array_equal( Index(['a', pd.NaT]).isin([pd.NaT]), [False, True]) - self.assert_numpy_array_equal( + tm.assert_numpy_array_equal( Index(['a', np.nan]).isin([float('nan')]), [False, False]) - self.assert_numpy_array_equal( + tm.assert_numpy_array_equal( Index(['a', np.nan]).isin([pd.NaT]), [False, False]) # Float64Index overrides isin, so must be checked separately - self.assert_numpy_array_equal( + tm.assert_numpy_array_equal( Float64Index([1.0, np.nan]).isin([np.nan]), [False, True]) - self.assert_numpy_array_equal( + tm.assert_numpy_array_equal( Float64Index([1.0, np.nan]).isin([float('nan')]), [False, True]) - self.assert_numpy_array_equal( + tm.assert_numpy_array_equal( Float64Index([1.0, np.nan]).isin([pd.NaT]), [False, True]) def test_isin_level_kwarg(self): @@ -1361,8 +1524,8 @@ def check_idx(idx): values = idx.tolist()[-2:] + ['nonexisting'] expected = np.array([False, False, True, True]) - self.assert_numpy_array_equal(expected, idx.isin(values, level=0)) - self.assert_numpy_array_equal(expected, idx.isin(values, level=-1)) + tm.assert_numpy_array_equal(expected, idx.isin(values, level=0)) + tm.assert_numpy_array_equal(expected, idx.isin(values, level=-1)) self.assertRaises(IndexError, idx.isin, values, level=1) self.assertRaises(IndexError, idx.isin, values, level=10) @@ -1372,7 +1535,7 @@ def check_idx(idx): self.assertRaises(KeyError, idx.isin, values, level='foobar') idx.name = 'foobar' - self.assert_numpy_array_equal(expected, + tm.assert_numpy_array_equal(expected, idx.isin(values, level='foobar')) self.assertRaises(KeyError, idx.isin, values, level='xyzzy') @@ -1388,7 +1551,7 @@ def test_boolean_cmp(self): idx = Index(values) res = (idx == values) - self.assert_numpy_array_equal(res,np.array([True,True,True,True],dtype=bool)) + tm.assert_numpy_array_equal(res,np.array([True,True,True,True],dtype=bool)) def test_get_level_values(self): result = self.strIndex.get_level_values(0) @@ -1438,7 +1601,7 @@ def test_str_attribute(self): # test boolean case, should return np.array instead of boolean Index idx = Index(['a1', 'a2', 'b1', 'b2']) expected = np.array([True, True, False, False]) - self.assert_array_equal(idx.str.startswith('a'), expected) + tm.assert_numpy_array_equal(idx.str.startswith('a'), expected) self.assertIsInstance(idx.str.startswith('a'), np.ndarray) s = Series(range(4), index=idx) expected = Series(range(2), index=['a1', 'a2']) @@ -1540,23 +1703,26 @@ def test_groupby(self): exp = {1: [0, 1], 2: [2, 3, 4]} tm.assert_dict_equal(groups, exp) - def test_equals_op(self): - # For issue #9785 + def test_equals_op_multiindex(self): + # GH9785 + # test comparisons of multiindex + from pandas.compat import StringIO + df = pd.read_csv(StringIO('a,b,c\n1,2,3\n4,5,6'), index_col=[0, 1]) + tm.assert_numpy_array_equal(df.index == df.index, np.array([True, True])) + + mi1 = MultiIndex.from_tuples([(1, 2), (4, 5)]) + tm.assert_numpy_array_equal(df.index == mi1, np.array([True, True])) + mi2 = MultiIndex.from_tuples([(1, 2), (4, 6)]) + tm.assert_numpy_array_equal(df.index == mi2, np.array([True, False])) + mi3 = MultiIndex.from_tuples([(1, 2), (4, 5), (8, 9)]) + with tm.assertRaisesRegexp(ValueError, "Lengths must match"): + df.index == mi3 + index_a = Index(['foo', 'bar', 'baz']) - index_b = Index(['foo', 'bar', 'baz', 'qux']) - # Testing Numpy Results Equivelent - assert_array_equal( - index_a.equals(index_a), - index_a == index_a - ) - assert_array_equal( - index_a.equals(index_b), - index_a == index_b, - ) - assert_array_equal( - index_b.equals(index_a), - index_b == index_a, - ) + with tm.assertRaisesRegexp(ValueError, "Lengths must match"): + df.index == index_a + tm.assert_numpy_array_equal(index_a == mi3, np.array([False, False, False])) + class TestCategoricalIndex(Base, tm.TestCase): _holder = CategoricalIndex @@ -1586,39 +1752,39 @@ def test_construction(self): # empty result = CategoricalIndex(categories=categories) self.assertTrue(result.categories.equals(Index(categories))) - self.assert_numpy_array_equal(result.codes,np.array([],dtype='int8')) + tm.assert_numpy_array_equal(result.codes, np.array([],dtype='int8')) self.assertFalse(result.ordered) # passing categories result = CategoricalIndex(list('aabbca'),categories=categories) self.assertTrue(result.categories.equals(Index(categories))) - self.assert_numpy_array_equal(result.codes,np.array([0,0,1,1,2,0],dtype='int8')) + tm.assert_numpy_array_equal(result.codes,np.array([0,0,1,1,2,0],dtype='int8')) c = pd.Categorical(list('aabbca')) result = CategoricalIndex(c) self.assertTrue(result.categories.equals(Index(list('abc')))) - self.assert_numpy_array_equal(result.codes,np.array([0,0,1,1,2,0],dtype='int8')) + tm.assert_numpy_array_equal(result.codes,np.array([0,0,1,1,2,0],dtype='int8')) self.assertFalse(result.ordered) result = CategoricalIndex(c,categories=categories) self.assertTrue(result.categories.equals(Index(categories))) - self.assert_numpy_array_equal(result.codes,np.array([0,0,1,1,2,0],dtype='int8')) + tm.assert_numpy_array_equal(result.codes,np.array([0,0,1,1,2,0],dtype='int8')) self.assertFalse(result.ordered) ci = CategoricalIndex(c,categories=list('abcd')) result = CategoricalIndex(ci) self.assertTrue(result.categories.equals(Index(categories))) - self.assert_numpy_array_equal(result.codes,np.array([0,0,1,1,2,0],dtype='int8')) + tm.assert_numpy_array_equal(result.codes,np.array([0,0,1,1,2,0],dtype='int8')) self.assertFalse(result.ordered) result = CategoricalIndex(ci, categories=list('ab')) self.assertTrue(result.categories.equals(Index(list('ab')))) - self.assert_numpy_array_equal(result.codes,np.array([0,0,1,1,-1,0],dtype='int8')) + tm.assert_numpy_array_equal(result.codes,np.array([0,0,1,1,-1,0],dtype='int8')) self.assertFalse(result.ordered) result = CategoricalIndex(ci, categories=list('ab'), ordered=True) self.assertTrue(result.categories.equals(Index(list('ab')))) - self.assert_numpy_array_equal(result.codes,np.array([0,0,1,1,-1,0],dtype='int8')) + tm.assert_numpy_array_equal(result.codes,np.array([0,0,1,1,-1,0],dtype='int8')) self.assertTrue(result.ordered) # turn me to an Index @@ -1811,7 +1977,7 @@ def test_reindex_base(self): expected = np.array([4,0,1,5,2,3]) actual = idx.get_indexer(idx) - assert_array_equal(expected, actual) + tm.assert_numpy_array_equal(expected, actual) with tm.assertRaisesRegexp(ValueError, 'Invalid fill method'): idx.get_indexer(idx, method='invalid') @@ -1826,14 +1992,17 @@ def test_reindexing(self): expected = oidx.get_indexer_non_unique(finder)[0] actual = ci.get_indexer(finder) - assert_array_equal(expected, actual) + tm.assert_numpy_array_equal(expected, actual) def test_duplicates(self): - idx = CategoricalIndex([0, 0, 0]) + idx = CategoricalIndex([0, 0, 0], name='foo') self.assertFalse(idx.is_unique) self.assertTrue(idx.has_duplicates) + expected = CategoricalIndex([0], name='foo') + self.assert_index_equal(idx.drop_duplicates(), expected) + def test_get_indexer(self): idx1 = CategoricalIndex(list('aabcde'),categories=list('edabc')) @@ -1870,13 +2039,13 @@ def test_repr_roundtrip(self): def test_isin(self): ci = CategoricalIndex(list('aabca') + [np.nan],categories=['c','a','b',np.nan]) - self.assert_numpy_array_equal(ci.isin(['c']),np.array([False,False,False,True,False,False])) - self.assert_numpy_array_equal(ci.isin(['c','a','b']),np.array([True]*5 + [False])) - self.assert_numpy_array_equal(ci.isin(['c','a','b',np.nan]),np.array([True]*6)) + tm.assert_numpy_array_equal(ci.isin(['c']),np.array([False,False,False,True,False,False])) + tm.assert_numpy_array_equal(ci.isin(['c','a','b']),np.array([True]*5 + [False])) + tm.assert_numpy_array_equal(ci.isin(['c','a','b',np.nan]),np.array([True]*6)) # mismatched categorical -> coerced to ndarray so doesn't matter - self.assert_numpy_array_equal(ci.isin(ci.set_categories(list('abcdefghi'))),np.array([True]*6)) - self.assert_numpy_array_equal(ci.isin(ci.set_categories(list('defghi'))),np.array([False]*5 + [True])) + tm.assert_numpy_array_equal(ci.isin(ci.set_categories(list('abcdefghi'))),np.array([True]*6)) + tm.assert_numpy_array_equal(ci.isin(ci.set_categories(list('defghi'))),np.array([False]*5 + [True])) def test_identical(self): @@ -1908,7 +2077,8 @@ def test_equals(self): self.assertTrue((ci1 == ci1.values).all()) # invalid comparisons - self.assertRaises(TypeError, lambda : ci1 == Index(['a','b','c'])) + with tm.assertRaisesRegexp(ValueError, "Lengths must match"): + ci1 == Index(['a','b','c']) self.assertRaises(TypeError, lambda : ci1 == ci2) self.assertRaises(TypeError, lambda : ci1 == Categorical(ci1.values, ordered=False)) self.assertRaises(TypeError, lambda : ci1 == Categorical(ci1.values, categories=list('abc'))) @@ -2024,7 +2194,7 @@ def setUp(self): self.setup_indices() def create_index(self): - return Float64Index(np.arange(5,dtype='float64')) + return Float64Index(np.arange(5, dtype='float64')) def test_repr_roundtrip(self): for ind in (self.mixed, self.float): @@ -2124,23 +2294,31 @@ def test_equals(self): def test_get_indexer(self): idx = Float64Index([0.0, 1.0, 2.0]) - self.assert_array_equal(idx.get_indexer(idx), [0, 1, 2]) + tm.assert_numpy_array_equal(idx.get_indexer(idx), [0, 1, 2]) target = [-0.1, 0.5, 1.1] - self.assert_array_equal(idx.get_indexer(target, 'pad'), [-1, 0, 1]) - self.assert_array_equal(idx.get_indexer(target, 'backfill'), [0, 1, 2]) - self.assert_array_equal(idx.get_indexer(target, 'nearest'), [0, 1, 1]) + tm.assert_numpy_array_equal(idx.get_indexer(target, 'pad'), [-1, 0, 1]) + tm.assert_numpy_array_equal(idx.get_indexer(target, 'backfill'), [0, 1, 2]) + tm.assert_numpy_array_equal(idx.get_indexer(target, 'nearest'), [0, 1, 1]) def test_get_loc(self): idx = Float64Index([0.0, 1.0, 2.0]) for method in [None, 'pad', 'backfill', 'nearest']: self.assertEqual(idx.get_loc(1, method), 1) + if method is not None: + self.assertEqual(idx.get_loc(1, method, tolerance=0), 1) for method, loc in [('pad', 1), ('backfill', 2), ('nearest', 1)]: self.assertEqual(idx.get_loc(1.1, method), loc) + self.assertEqual(idx.get_loc(1.1, method, tolerance=0.9), loc) self.assertRaises(KeyError, idx.get_loc, 'foo') self.assertRaises(KeyError, idx.get_loc, 1.5) + self.assertRaises(KeyError, idx.get_loc, 1.5, + method='pad', tolerance=0.1) + + with tm.assertRaisesRegexp(ValueError, 'must be numeric'): + idx.get_loc(1.4, method='nearest', tolerance='foo') def test_get_loc_na(self): idx = Float64Index([np.nan, 1, 2]) @@ -2149,6 +2327,16 @@ def test_get_loc_na(self): idx = Float64Index([np.nan, 1, np.nan]) self.assertEqual(idx.get_loc(1), 1) + + # representable by slice [0:2:2] + # self.assertRaises(KeyError, idx.slice_locs, np.nan) + sliced = idx.slice_locs(np.nan) + self.assertTrue(isinstance(sliced, tuple)) + self.assertEqual(sliced, (0, 3)) + + # not representable by slice + idx = Float64Index([np.nan, 1, np.nan, np.nan]) + self.assertEqual(idx.get_loc(1), 1) self.assertRaises(KeyError, idx.slice_locs, np.nan) def test_contains_nans(self): @@ -2167,16 +2355,16 @@ def test_doesnt_contain_all_the_things(self): def test_nan_multiple_containment(self): i = Float64Index([1.0, np.nan]) - np.testing.assert_array_equal(i.isin([1.0]), np.array([True, False])) - np.testing.assert_array_equal(i.isin([2.0, np.pi]), - np.array([False, False])) - np.testing.assert_array_equal(i.isin([np.nan]), - np.array([False, True])) - np.testing.assert_array_equal(i.isin([1.0, np.nan]), - np.array([True, True])) + tm.assert_numpy_array_equal(i.isin([1.0]), np.array([True, False])) + tm.assert_numpy_array_equal(i.isin([2.0, np.pi]), + np.array([False, False])) + tm.assert_numpy_array_equal(i.isin([np.nan]), + np.array([False, True])) + tm.assert_numpy_array_equal(i.isin([1.0, np.nan]), + np.array([True, True])) i = Float64Index([1.0, 2.0]) - np.testing.assert_array_equal(i.isin([np.nan]), - np.array([False, False])) + tm.assert_numpy_array_equal(i.isin([np.nan]), + np.array([False, False])) def test_astype_from_object(self): index = Index([1.0, np.nan, 0.2], dtype='object') @@ -2195,7 +2383,7 @@ def setUp(self): self.setup_indices() def create_index(self): - return Int64Index(np.arange(5,dtype='int64')) + return Int64Index(np.arange(5, dtype='int64')) def test_too_many_names(self): def testit(): @@ -2206,11 +2394,11 @@ def test_constructor(self): # pass list, coerce fine index = Int64Index([-5, 0, 1, 2]) expected = np.array([-5, 0, 1, 2], dtype=np.int64) - self.assert_numpy_array_equal(index, expected) + tm.assert_numpy_array_equal(index, expected) # from iterable index = Int64Index(iter([-5, 0, 1, 2])) - self.assert_numpy_array_equal(index, expected) + tm.assert_numpy_array_equal(index, expected) # scalar raise Exception self.assertRaises(TypeError, Int64Index, 5) @@ -2218,7 +2406,7 @@ def test_constructor(self): # copy arr = self.index.values new_index = Int64Index(arr, copy=True) - self.assert_numpy_array_equal(new_index, self.index) + tm.assert_numpy_array_equal(new_index, self.index) val = arr[0] + 3000 # this should not change index arr[0] = val @@ -2260,11 +2448,11 @@ def test_view(self): def test_coerce_list(self): # coerce things arr = Index([1, 2, 3, 4]) - tm.assert_isinstance(arr, Int64Index) + tm.assertIsInstance(arr, Int64Index) # but not if explicit dtype passed arr = Index([1, 2, 3, 4], dtype=object) - tm.assert_isinstance(arr, Index) + tm.assertIsInstance(arr, Index) def test_dtype(self): self.assertEqual(self.index.dtype, np.int64) @@ -2331,19 +2519,19 @@ def test_get_indexer(self): target = Int64Index(np.arange(10)) indexer = self.index.get_indexer(target) expected = np.array([0, -1, 1, -1, 2, -1, 3, -1, 4, -1]) - self.assert_numpy_array_equal(indexer, expected) + tm.assert_numpy_array_equal(indexer, expected) def test_get_indexer_pad(self): target = Int64Index(np.arange(10)) indexer = self.index.get_indexer(target, method='pad') expected = np.array([0, 0, 1, 1, 2, 2, 3, 3, 4, 4]) - self.assert_numpy_array_equal(indexer, expected) + tm.assert_numpy_array_equal(indexer, expected) def test_get_indexer_backfill(self): target = Int64Index(np.arange(10)) indexer = self.index.get_indexer(target, method='backfill') expected = np.array([0, 1, 1, 2, 2, 3, 3, 4, 4, 5]) - self.assert_numpy_array_equal(indexer, expected) + tm.assert_numpy_array_equal(indexer, expected) def test_join_outer(self): other = Int64Index([7, 12, 25, 1, 2, 5]) @@ -2362,10 +2550,10 @@ def test_join_outer(self): eridx = np.array([-1, 3, 4, -1, 5, -1, 0, -1, -1, 1, -1, -1, -1, 2], dtype=np.int64) - tm.assert_isinstance(res, Int64Index) + tm.assertIsInstance(res, Int64Index) self.assertTrue(res.equals(eres)) - self.assert_numpy_array_equal(lidx, elidx) - self.assert_numpy_array_equal(ridx, eridx) + tm.assert_numpy_array_equal(lidx, elidx) + tm.assert_numpy_array_equal(ridx, eridx) # monotonic res, lidx, ridx = self.index.join(other_mono, how='outer', @@ -2375,10 +2563,10 @@ def test_join_outer(self): eridx = np.array([-1, 0, 1, -1, 2, -1, 3, -1, -1, 4, -1, -1, -1, 5], dtype=np.int64) - tm.assert_isinstance(res, Int64Index) + tm.assertIsInstance(res, Int64Index) self.assertTrue(res.equals(eres)) - self.assert_numpy_array_equal(lidx, elidx) - self.assert_numpy_array_equal(ridx, eridx) + tm.assert_numpy_array_equal(lidx, elidx) + tm.assert_numpy_array_equal(ridx, eridx) def test_join_inner(self): other = Int64Index([7, 12, 25, 1, 2, 5]) @@ -2398,10 +2586,10 @@ def test_join_inner(self): elidx = np.array([1, 6]) eridx = np.array([4, 1]) - tm.assert_isinstance(res, Int64Index) + tm.assertIsInstance(res, Int64Index) self.assertTrue(res.equals(eres)) - self.assert_numpy_array_equal(lidx, elidx) - self.assert_numpy_array_equal(ridx, eridx) + tm.assert_numpy_array_equal(lidx, elidx) + tm.assert_numpy_array_equal(ridx, eridx) # monotonic res, lidx, ridx = self.index.join(other_mono, how='inner', @@ -2411,10 +2599,10 @@ def test_join_inner(self): self.assertTrue(res.equals(res2)) eridx = np.array([1, 4]) - tm.assert_isinstance(res, Int64Index) + tm.assertIsInstance(res, Int64Index) self.assertTrue(res.equals(eres)) - self.assert_numpy_array_equal(lidx, elidx) - self.assert_numpy_array_equal(ridx, eridx) + tm.assert_numpy_array_equal(lidx, elidx) + tm.assert_numpy_array_equal(ridx, eridx) def test_join_left(self): other = Int64Index([7, 12, 25, 1, 2, 5]) @@ -2427,20 +2615,20 @@ def test_join_left(self): eridx = np.array([-1, 4, -1, -1, -1, -1, 1, -1, -1, -1], dtype=np.int64) - tm.assert_isinstance(res, Int64Index) + tm.assertIsInstance(res, Int64Index) self.assertTrue(res.equals(eres)) self.assertIsNone(lidx) - self.assert_numpy_array_equal(ridx, eridx) + tm.assert_numpy_array_equal(ridx, eridx) # monotonic res, lidx, ridx = self.index.join(other_mono, how='left', return_indexers=True) eridx = np.array([-1, 1, -1, -1, -1, -1, 4, -1, -1, -1], dtype=np.int64) - tm.assert_isinstance(res, Int64Index) + tm.assertIsInstance(res, Int64Index) self.assertTrue(res.equals(eres)) self.assertIsNone(lidx) - self.assert_numpy_array_equal(ridx, eridx) + tm.assert_numpy_array_equal(ridx, eridx) # non-unique """ @@ -2451,8 +2639,8 @@ def test_join_left(self): eridx = np.array([0, 2, 3, -1, -1]) elidx = np.array([0, 1, 2, 3, 4]) self.assertTrue(res.equals(eres)) - self.assert_numpy_array_equal(lidx, elidx) - self.assert_numpy_array_equal(ridx, eridx) + tm.assert_numpy_array_equal(lidx, elidx) + tm.assert_numpy_array_equal(ridx, eridx) """ def test_join_right(self): @@ -2466,9 +2654,9 @@ def test_join_right(self): elidx = np.array([-1, 6, -1, -1, 1, -1], dtype=np.int64) - tm.assert_isinstance(other, Int64Index) + tm.assertIsInstance(other, Int64Index) self.assertTrue(res.equals(eres)) - self.assert_numpy_array_equal(lidx, elidx) + tm.assert_numpy_array_equal(lidx, elidx) self.assertIsNone(ridx) # monotonic @@ -2477,9 +2665,9 @@ def test_join_right(self): eres = other_mono elidx = np.array([-1, 1, -1, -1, 6, -1], dtype=np.int64) - tm.assert_isinstance(other, Int64Index) + tm.assertIsInstance(other, Int64Index) self.assertTrue(res.equals(eres)) - self.assert_numpy_array_equal(lidx, elidx) + tm.assert_numpy_array_equal(lidx, elidx) self.assertIsNone(ridx) # non-unique @@ -2491,8 +2679,8 @@ def test_join_right(self): elidx = np.array([0, 2, 3, -1, -1]) eridx = np.array([0, 1, 2, 3, 4]) self.assertTrue(res.equals(eres)) - self.assert_numpy_array_equal(lidx, elidx) - self.assert_numpy_array_equal(ridx, eridx) + tm.assert_numpy_array_equal(lidx, elidx) + tm.assert_numpy_array_equal(ridx, eridx) idx = Index([1,1,2,5]) idx2 = Index([1,2,5,9,7]) @@ -2538,10 +2726,10 @@ def test_join_non_unique(self): self.assertTrue(joined.equals(exp_joined)) exp_lidx = np.array([2, 2, 3, 3, 0, 0, 1, 1], dtype=np.int64) - self.assert_numpy_array_equal(lidx, exp_lidx) + tm.assert_numpy_array_equal(lidx, exp_lidx) exp_ridx = np.array([2, 3, 2, 3, 0, 1, 0, 1], dtype=np.int64) - self.assert_numpy_array_equal(ridx, exp_ridx) + tm.assert_numpy_array_equal(ridx, exp_ridx) def test_join_self(self): kinds = 'outer', 'inner', 'left', 'right' @@ -2553,12 +2741,12 @@ def test_intersection(self): other = Index([1, 2, 3, 4, 5]) result = self.index.intersection(other) expected = np.sort(np.intersect1d(self.index.values, other.values)) - self.assert_numpy_array_equal(result, expected) + tm.assert_numpy_array_equal(result, expected) result = other.intersection(self.index) expected = np.sort(np.asarray(np.intersect1d(self.index.values, other.values))) - self.assert_numpy_array_equal(result, expected) + tm.assert_numpy_array_equal(result, expected) def test_intersect_str_dates(self): dt_dates = [datetime(2012, 2, 9), datetime(2012, 2, 22)] @@ -2576,11 +2764,11 @@ def test_union_noncomparable(self): other = Index([now + timedelta(i) for i in range(4)], dtype=object) result = self.index.union(other) expected = np.concatenate((self.index, other)) - self.assert_numpy_array_equal(result, expected) + tm.assert_numpy_array_equal(result, expected) result = other.union(self.index) expected = np.concatenate((other, self.index)) - self.assert_numpy_array_equal(result, expected) + tm.assert_numpy_array_equal(result, expected) def test_cant_or_shouldnt_cast(self): # can't @@ -2685,19 +2873,11 @@ def setUp(self): self.setup_indices() def create_index(self): - return date_range('20130101',periods=5) + return date_range('20130101', periods=5) def test_pickle_compat_construction(self): pass - def test_numeric_compat(self): - super(TestDatetimeIndex, self).test_numeric_compat() - - if not compat.PY3_2: - for f in [lambda : np.timedelta64(1, 'D').astype('m8[ns]') * pd.date_range('2000-01-01', periods=3), - lambda : pd.date_range('2000-01-01', periods=3) * np.timedelta64(1, 'D').astype('m8[ns]') ]: - self.assertRaises(TypeError, f) - def test_get_loc(self): idx = pd.date_range('2000-01-01', periods=3) @@ -2705,10 +2885,28 @@ def test_get_loc(self): self.assertEqual(idx.get_loc(idx[1], method), 1) self.assertEqual(idx.get_loc(idx[1].to_pydatetime(), method), 1) self.assertEqual(idx.get_loc(str(idx[1]), method), 1) + if method is not None: + self.assertEqual(idx.get_loc(idx[1], method, + tolerance=pd.Timedelta('0 days')), + 1) self.assertEqual(idx.get_loc('2000-01-01', method='nearest'), 0) self.assertEqual(idx.get_loc('2000-01-01T12', method='nearest'), 1) + self.assertEqual(idx.get_loc('2000-01-01T12', method='nearest', + tolerance='1 day'), 1) + self.assertEqual(idx.get_loc('2000-01-01T12', method='nearest', + tolerance=pd.Timedelta('1D')), 1) + self.assertEqual(idx.get_loc('2000-01-01T12', method='nearest', + tolerance=np.timedelta64(1, 'D')), 1) + self.assertEqual(idx.get_loc('2000-01-01T12', method='nearest', + tolerance=timedelta(1)), 1) + with tm.assertRaisesRegexp(ValueError, 'must be convertible'): + idx.get_loc('2000-01-01T12', method='nearest', tolerance='foo') + with tm.assertRaises(KeyError): + idx.get_loc('2000-01-01T03', method='nearest', + tolerance='2 hours') + self.assertEqual(idx.get_loc('2000', method='nearest'), slice(0, 3)) self.assertEqual(idx.get_loc('2000-01', method='nearest'), slice(0, 3)) @@ -2732,19 +2930,24 @@ def test_get_loc(self): # time indexing idx = pd.date_range('2000-01-01', periods=24, freq='H') - assert_array_equal(idx.get_loc(time(12)), [12]) - assert_array_equal(idx.get_loc(time(12, 30)), []) + tm.assert_numpy_array_equal(idx.get_loc(time(12)), [12]) + tm.assert_numpy_array_equal(idx.get_loc(time(12, 30)), []) with tm.assertRaises(NotImplementedError): idx.get_loc(time(12, 30), method='pad') def test_get_indexer(self): idx = pd.date_range('2000-01-01', periods=3) - self.assert_array_equal(idx.get_indexer(idx), [0, 1, 2]) + tm.assert_numpy_array_equal(idx.get_indexer(idx), [0, 1, 2]) target = idx[0] + pd.to_timedelta(['-1 hour', '12 hours', '1 day 1 hour']) - self.assert_array_equal(idx.get_indexer(target, 'pad'), [-1, 0, 1]) - self.assert_array_equal(idx.get_indexer(target, 'backfill'), [0, 1, 2]) - self.assert_array_equal(idx.get_indexer(target, 'nearest'), [0, 1, 1]) + tm.assert_numpy_array_equal(idx.get_indexer(target, 'pad'), [-1, 0, 1]) + tm.assert_numpy_array_equal(idx.get_indexer(target, 'backfill'), [0, 1, 2]) + tm.assert_numpy_array_equal(idx.get_indexer(target, 'nearest'), [0, 1, 1]) + tm.assert_numpy_array_equal( + idx.get_indexer(target, 'nearest', tolerance=pd.Timedelta('1 hour')), + [0, -1, 1]) + with tm.assertRaises(ValueError): + idx.get_indexer(idx[[0]], method='nearest', tolerance='foo') def test_roundtrip_pickle_with_tz(self): @@ -2774,7 +2977,7 @@ def test_time_loc(self): # GH8667 ts = pd.Series(np.random.randn(n), index=idx) i = np.arange(start, n, step) - tm.assert_array_equal(ts.index.get_loc(key), i) + tm.assert_numpy_array_equal(ts.index.get_loc(key), i) tm.assert_series_equal(ts[key], ts.iloc[i]) left, right = ts.copy(), ts.copy() @@ -2827,6 +3030,9 @@ def test_union(self): result = first.union(case) self.assertTrue(tm.equalContents(result, everything)) + def test_nat(self): + self.assertIs(DatetimeIndex([np.nan])[0], pd.NaT) + class TestPeriodIndex(DatetimeLike, tm.TestCase): _holder = PeriodIndex @@ -2852,18 +3058,40 @@ def test_get_loc(self): self.assertEqual(idx.get_loc(idx[1].to_timestamp().to_pydatetime(), method), 1) self.assertEqual(idx.get_loc(str(idx[1]), method), 1) + idx = pd.period_range('2000-01-01', periods=5)[::2] + self.assertEqual(idx.get_loc('2000-01-02T12', method='nearest', + tolerance='1 day'), 1) + self.assertEqual(idx.get_loc('2000-01-02T12', method='nearest', + tolerance=pd.Timedelta('1D')), 1) + self.assertEqual(idx.get_loc('2000-01-02T12', method='nearest', + tolerance=np.timedelta64(1, 'D')), 1) + self.assertEqual(idx.get_loc('2000-01-02T12', method='nearest', + tolerance=timedelta(1)), 1) + with tm.assertRaisesRegexp(ValueError, 'must be convertible'): + idx.get_loc('2000-01-10', method='nearest', tolerance='foo') + with tm.assertRaisesRegexp(ValueError, 'different freq'): + idx.get_loc('2000-01-10', method='nearest', tolerance='1 hour') + with tm.assertRaises(KeyError): + idx.get_loc('2000-01-10', method='nearest', tolerance='1 day') + def test_get_indexer(self): idx = pd.period_range('2000-01-01', periods=3).asfreq('H', how='start') - self.assert_array_equal(idx.get_indexer(idx), [0, 1, 2]) + tm.assert_numpy_array_equal(idx.get_indexer(idx), [0, 1, 2]) target = pd.PeriodIndex(['1999-12-31T23', '2000-01-01T12', '2000-01-02T01'], freq='H') - self.assert_array_equal(idx.get_indexer(target, 'pad'), [-1, 0, 1]) - self.assert_array_equal(idx.get_indexer(target, 'backfill'), [0, 1, 2]) - self.assert_array_equal(idx.get_indexer(target, 'nearest'), [0, 1, 1]) + tm.assert_numpy_array_equal(idx.get_indexer(target, 'pad'), [-1, 0, 1]) + tm.assert_numpy_array_equal(idx.get_indexer(target, 'backfill'), [0, 1, 2]) + tm.assert_numpy_array_equal(idx.get_indexer(target, 'nearest'), [0, 1, 1]) + tm.assert_numpy_array_equal( + idx.get_indexer(target, 'nearest', tolerance='1 hour'), + [0, -1, 1]) with self.assertRaisesRegexp(ValueError, 'different freq'): - idx.asfreq('D').get_indexer(idx) + idx.get_indexer(target, 'nearest', tolerance='1 minute') + + tm.assert_numpy_array_equal( + idx.get_indexer(target, 'nearest', tolerance='1 day'), [0, 1, 1]) def test_repeat(self): # GH10183 @@ -2883,7 +3111,7 @@ def setUp(self): self.setup_indices() def create_index(self): - return pd.to_timedelta(range(5),unit='d') + pd.offsets.Hour(1) + return pd.to_timedelta(range(5), unit='d') + pd.offsets.Hour(1) def test_get_loc(self): idx = pd.to_timedelta(['0 days', '1 days', '2 days']) @@ -2893,17 +3121,28 @@ def test_get_loc(self): self.assertEqual(idx.get_loc(idx[1].to_pytimedelta(), method), 1) self.assertEqual(idx.get_loc(str(idx[1]), method), 1) + self.assertEqual(idx.get_loc(idx[1], 'pad', tolerance=pd.Timedelta(0)), 1) + self.assertEqual(idx.get_loc(idx[1], 'pad', tolerance=np.timedelta64(0, 's')), 1) + self.assertEqual(idx.get_loc(idx[1], 'pad', tolerance=timedelta(0)), 1) + + with tm.assertRaisesRegexp(ValueError, 'must be convertible'): + idx.get_loc(idx[1], method='nearest', tolerance='foo') + for method, loc in [('pad', 1), ('backfill', 2), ('nearest', 1)]: self.assertEqual(idx.get_loc('1 day 1 hour', method), loc) def test_get_indexer(self): idx = pd.to_timedelta(['0 days', '1 days', '2 days']) - self.assert_array_equal(idx.get_indexer(idx), [0, 1, 2]) + tm.assert_numpy_array_equal(idx.get_indexer(idx), [0, 1, 2]) target = pd.to_timedelta(['-1 hour', '12 hours', '1 day 1 hour']) - self.assert_array_equal(idx.get_indexer(target, 'pad'), [-1, 0, 1]) - self.assert_array_equal(idx.get_indexer(target, 'backfill'), [0, 1, 2]) - self.assert_array_equal(idx.get_indexer(target, 'nearest'), [0, 1, 1]) + tm.assert_numpy_array_equal(idx.get_indexer(target, 'pad'), [-1, 0, 1]) + tm.assert_numpy_array_equal(idx.get_indexer(target, 'backfill'), [0, 1, 2]) + tm.assert_numpy_array_equal(idx.get_indexer(target, 'nearest'), [0, 1, 1]) + tm.assert_numpy_array_equal( + idx.get_indexer(target, 'nearest', + tolerance=pd.Timedelta('1 hour')), + [0, -1, 1]) def test_numeric_compat(self): @@ -3240,7 +3479,10 @@ def test_inplace_mutation_resets_values(self): # make sure label setting works too labels2 = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]] - exp_values = np.array([(long(1), 'a')] * 6, dtype=object) + exp_values = np.empty((6, ), dtype=object) + exp_values[:] = [(long(1), 'a')] * 6 + # must be 1d array of tuples + self.assertEqual(exp_values.shape, (6, )) new_values = mi2.set_labels(labels2).values # not inplace shouldn't change assert_almost_equal(mi2._tuples, vals2) @@ -3335,7 +3577,7 @@ def test_constructor_single_level(self): single_level = MultiIndex(levels=[['foo', 'bar', 'baz', 'qux']], labels=[[0, 1, 2, 3]], names=['first']) - tm.assert_isinstance(single_level, Index) + tm.assertIsInstance(single_level, Index) self.assertNotIsInstance(single_level, MultiIndex) self.assertEqual(single_level.name, 'first') @@ -3483,7 +3725,7 @@ def test_from_product(self): ('buz', 'a'), ('buz', 'b'), ('buz', 'c')] expected = MultiIndex.from_tuples(tuples, names=names) - assert_array_equal(result, expected) + tm.assert_numpy_array_equal(result, expected) self.assertEqual(result.names, names) def test_from_product_datetimeindex(self): @@ -3493,7 +3735,7 @@ def test_from_product_datetimeindex(self): (1, pd.Timestamp('2000-01-02')), (2, pd.Timestamp('2000-01-01')), (2, pd.Timestamp('2000-01-02'))]) - assert_array_equal(mi.values, etalon) + tm.assert_numpy_array_equal(mi.values, etalon) def test_values_boxed(self): tuples = [(1, pd.Timestamp('2000-01-01')), @@ -3503,9 +3745,9 @@ def test_values_boxed(self): (2, pd.Timestamp('2000-01-02')), (3, pd.Timestamp('2000-01-03'))] mi = pd.MultiIndex.from_tuples(tuples) - assert_array_equal(mi.values, pd.lib.list_to_object_array(tuples)) + tm.assert_numpy_array_equal(mi.values, pd.lib.list_to_object_array(tuples)) # Check that code branches for boxed values produce identical results - assert_array_equal(mi.values[:4], mi[:4].values) + tm.assert_numpy_array_equal(mi.values[:4], mi[:4].values) def test_append(self): result = self.index[:3].append(self.index[3:]) @@ -3522,41 +3764,51 @@ def test_append(self): def test_get_level_values(self): result = self.index.get_level_values(0) expected = ['foo', 'foo', 'bar', 'baz', 'qux', 'qux'] - self.assert_numpy_array_equal(result, expected) + tm.assert_numpy_array_equal(result, expected) self.assertEqual(result.name, 'first') result = self.index.get_level_values('first') expected = self.index.get_level_values(0) - self.assert_numpy_array_equal(result, expected) + tm.assert_numpy_array_equal(result, expected) + + # GH 10460 + index = MultiIndex(levels=[CategoricalIndex(['A', 'B']), + CategoricalIndex([1, 2, 3])], + labels=[np.array([0, 0, 0, 1, 1, 1]), + np.array([0, 1, 2, 0, 1, 2])]) + exp = CategoricalIndex(['A', 'A', 'A', 'B', 'B', 'B']) + self.assert_index_equal(index.get_level_values(0), exp) + exp = CategoricalIndex([1, 2 ,3, 1, 2, 3]) + self.assert_index_equal(index.get_level_values(1), exp) def test_get_level_values_na(self): arrays = [['a', 'b', 'b'], [1, np.nan, 2]] index = pd.MultiIndex.from_arrays(arrays) values = index.get_level_values(1) expected = [1, np.nan, 2] - assert_array_equal(values.values.astype(float), expected) + tm.assert_numpy_array_equal(values.values.astype(float), expected) arrays = [['a', 'b', 'b'], [np.nan, np.nan, 2]] index = pd.MultiIndex.from_arrays(arrays) values = index.get_level_values(1) expected = [np.nan, np.nan, 2] - assert_array_equal(values.values.astype(float), expected) + tm.assert_numpy_array_equal(values.values.astype(float), expected) arrays = [[np.nan, np.nan, np.nan], ['a', np.nan, 1]] index = pd.MultiIndex.from_arrays(arrays) values = index.get_level_values(0) expected = [np.nan, np.nan, np.nan] - assert_array_equal(values.values.astype(float), expected) + tm.assert_numpy_array_equal(values.values.astype(float), expected) values = index.get_level_values(1) expected = np.array(['a', np.nan, 1],dtype=object) - assert_array_equal(values.values, expected) + tm.assert_numpy_array_equal(values.values, expected) arrays = [['a', 'b', 'b'], pd.DatetimeIndex([0, 1, pd.NaT])] index = pd.MultiIndex.from_arrays(arrays) values = index.get_level_values(1) expected = pd.DatetimeIndex([0, 1, pd.NaT]) - assert_array_equal(values.values, expected.values) + tm.assert_numpy_array_equal(values.values, expected.values) arrays = [[], []] index = pd.MultiIndex.from_arrays(arrays) @@ -3910,6 +4162,8 @@ def test_get_indexer_nearest(self): midx = MultiIndex.from_tuples([('a', 1), ('b', 2)]) with tm.assertRaises(NotImplementedError): midx.get_indexer(['a'], method='nearest') + with tm.assertRaises(NotImplementedError): + midx.get_indexer(['a'], method='pad', tolerance=2) def test_format(self): self.index.format() @@ -4145,7 +4399,7 @@ def test_difference(self): sortorder=0, names=self.index.names) - tm.assert_isinstance(result, MultiIndex) + tm.assertIsInstance(result, MultiIndex) self.assertTrue(result.equals(expected)) self.assertEqual(result.names, self.index.names) @@ -4206,7 +4460,7 @@ def test_from_tuples(self): def test_argsort(self): result = self.index.argsort() expected = self.index._tuple_index.argsort() - self.assert_numpy_array_equal(result, expected) + tm.assert_numpy_array_equal(result, expected) def test_sortlevel(self): import random @@ -4352,9 +4606,9 @@ def test_insert(self): # key not contained in all levels new_index = self.index.insert(0, ('abc', 'three')) - self.assert_numpy_array_equal(new_index.levels[0], + tm.assert_numpy_array_equal(new_index.levels[0], list(self.index.levels[0]) + ['abc']) - self.assert_numpy_array_equal(new_index.levels[1], + tm.assert_numpy_array_equal(new_index.levels[1], list(self.index.levels[1]) + ['three']) self.assertEqual(new_index[0], ('abc', 'three')) @@ -4430,7 +4684,7 @@ def _check_how(other, how): mask = np.array( [x[1] in exp_level for x in self.index], dtype=bool) exp_values = self.index.values[mask] - self.assert_numpy_array_equal(join_index.values, exp_values) + tm.assert_numpy_array_equal(join_index.values, exp_values) if how in ('outer', 'inner'): join_index2, ridx2, lidx2 = \ @@ -4438,9 +4692,9 @@ def _check_how(other, how): return_indexers=True) self.assertTrue(join_index.equals(join_index2)) - self.assert_numpy_array_equal(lidx, lidx2) - self.assert_numpy_array_equal(ridx, ridx2) - self.assert_numpy_array_equal(join_index2.values, exp_values) + tm.assert_numpy_array_equal(lidx, lidx2) + tm.assert_numpy_array_equal(ridx, ridx2) + tm.assert_numpy_array_equal(join_index2.values, exp_values) def _check_all(other): _check_how(other, 'outer') @@ -4455,7 +4709,7 @@ def _check_all(other): # some corner cases idx = Index(['three', 'one', 'two']) result = idx.join(self.index, level='second') - tm.assert_isinstance(result, MultiIndex) + tm.assertIsInstance(result, MultiIndex) assertRaisesRegexp(TypeError, "Join.*MultiIndex.*ambiguous", self.index.join, self.index, level=1) @@ -4467,13 +4721,44 @@ def test_join_self(self): joined = res.join(res, how=kind) self.assertIs(res, joined) + def test_join_multi(self): + # GH 10665 + midx = pd.MultiIndex.from_product([np.arange(4), np.arange(4)], names=['a', 'b']) + idx = pd.Index([1, 2, 5], name='b') + + # inner + jidx, lidx, ridx = midx.join(idx, how='inner', return_indexers=True) + exp_idx = pd.MultiIndex.from_product([np.arange(4), [1, 2]], names=['a', 'b']) + exp_lidx = np.array([1, 2, 5, 6, 9, 10, 13, 14]) + exp_ridx = np.array([0, 1, 0, 1, 0, 1, 0, 1]) + self.assert_index_equal(jidx, exp_idx) + self.assert_numpy_array_equal(lidx, exp_lidx) + self.assert_numpy_array_equal(ridx, exp_ridx) + # flip + jidx, ridx, lidx = idx.join(midx, how='inner', return_indexers=True) + self.assert_index_equal(jidx, exp_idx) + self.assert_numpy_array_equal(lidx, exp_lidx) + self.assert_numpy_array_equal(ridx, exp_ridx) + + # keep MultiIndex + jidx, lidx, ridx = midx.join(idx, how='left', return_indexers=True) + exp_ridx = np.array([-1, 0, 1, -1, -1, 0, 1, -1, -1, 0, 1, -1, -1, 0, 1, -1]) + self.assert_index_equal(jidx, midx) + self.assertIsNone(lidx) + self.assert_numpy_array_equal(ridx, exp_ridx) + # flip + jidx, ridx, lidx = idx.join(midx, how='right', return_indexers=True) + self.assert_index_equal(jidx, midx) + self.assertIsNone(lidx) + self.assert_numpy_array_equal(ridx, exp_ridx) + def test_reindex(self): result, indexer = self.index.reindex(list(self.index[:4])) - tm.assert_isinstance(result, MultiIndex) + tm.assertIsInstance(result, MultiIndex) self.check_level_names(result, self.index[:4].names) result, indexer = self.index.reindex(list(self.index)) - tm.assert_isinstance(result, MultiIndex) + tm.assertIsInstance(result, MultiIndex) self.assertIsNone(indexer) self.check_level_names(result, self.index.names) @@ -4488,11 +4773,11 @@ def test_reindex_level(self): self.assertTrue(target.equals(exp_index)) exp_indexer = np.array([0, 2, 4]) - self.assert_numpy_array_equal(indexer, exp_indexer) + tm.assert_numpy_array_equal(indexer, exp_indexer) self.assertTrue(target2.equals(exp_index2)) exp_indexer2 = np.array([0, -1, 0, -1, 0, -1]) - self.assert_numpy_array_equal(indexer2, exp_indexer2) + tm.assert_numpy_array_equal(indexer2, exp_indexer2) assertRaisesRegexp(TypeError, "Fill method not supported", self.index.reindex, self.index, method='pad', @@ -4579,17 +4864,17 @@ def check(nlevels, with_nulls): labels = [np.random.choice(n, k * n) for lev in levels] mi = MultiIndex(levels=levels, labels=labels) - for take_last in [False, True]: - left = mi.duplicated(take_last=take_last) - right = pd.lib.duplicated(mi.values, take_last=take_last) - tm.assert_array_equal(left, right) + for keep in ['first', 'last', False]: + left = mi.duplicated(keep=keep) + right = pd.lib.duplicated(mi.values, keep=keep) + tm.assert_numpy_array_equal(left, right) # GH5873 for a in [101, 102]: mi = MultiIndex.from_arrays([[101, a], [3.5, np.nan]]) self.assertFalse(mi.has_duplicates) self.assertEqual(mi.get_duplicates(), []) - self.assert_array_equal(mi.duplicated(), np.zeros(2, dtype='bool')) + tm.assert_numpy_array_equal(mi.duplicated(), np.zeros(2, dtype='bool')) for n in range(1, 6): # 1st level shape for m in range(1, 5): # 2nd level shape @@ -4600,8 +4885,21 @@ def check(nlevels, with_nulls): self.assertEqual(len(mi), (n + 1) * (m + 1)) self.assertFalse(mi.has_duplicates) self.assertEqual(mi.get_duplicates(), []) - self.assert_array_equal(mi.duplicated(), - np.zeros(len(mi), dtype='bool')) + tm.assert_numpy_array_equal(mi.duplicated(), + np.zeros(len(mi), dtype='bool')) + + def test_duplicate_meta_data(self): + # GH 10115 + index = MultiIndex(levels=[[0, 1], [0, 1, 2]], + labels=[[0, 0, 0, 0, 1, 1, 1], + [0, 1, 2, 0, 0, 1, 2]]) + for idx in [index, + index.set_names([None, None]), + index.set_names([None, 'Num']), + index.set_names(['Upper','Num']), + ]: + self.assertTrue(idx.has_duplicates) + self.assertEqual(idx.drop_duplicates().names, idx.names) def test_tolist(self): result = self.index.tolist() @@ -4618,7 +4916,19 @@ def test_repr_roundtrip(self): mi = MultiIndex.from_product([list('ab'),range(3)],names=['first','second']) str(mi) - tm.assert_index_equal(eval(repr(mi)),mi,exact=True) + + if compat.PY3: + tm.assert_index_equal(eval(repr(mi)), mi, exact=True) + else: + result = eval(repr(mi)) + # string coerces to unicode + tm.assert_index_equal(result, mi, exact=False) + self.assertEqual(mi.get_level_values('first').inferred_type, 'string') + self.assertEqual(result.get_level_values('first').inferred_type, 'unicode') + + mi_u = MultiIndex.from_product([list(u'ab'),range(3)],names=['first','second']) + result = eval(repr(mi_u)) + tm.assert_index_equal(result, mi_u, exact=True) # formatting if compat.PY3: @@ -4629,7 +4939,19 @@ def test_repr_roundtrip(self): # long format mi = MultiIndex.from_product([list('abcdefg'),range(10)],names=['first','second']) result = str(mi) - tm.assert_index_equal(eval(repr(mi)),mi,exact=True) + + if compat.PY3: + tm.assert_index_equal(eval(repr(mi)), mi, exact=True) + else: + result = eval(repr(mi)) + # string coerces to unicode + tm.assert_index_equal(result, mi, exact=False) + self.assertEqual(mi.get_level_values('first').inferred_type, 'string') + self.assertEqual(result.get_level_values('first').inferred_type, 'unicode') + + mi = MultiIndex.from_product([list(u'abcdefg'),range(10)],names=['first','second']) + result = eval(repr(mi_u)) + tm.assert_index_equal(result, mi_u, exact=True) def test_str(self): # tested elsewhere @@ -4682,7 +5004,7 @@ def test_isin(self): np.arange(4)]) result = idx.isin(values) expected = np.array([False, False, True, True]) - self.assert_numpy_array_equal(result, expected) + tm.assert_numpy_array_equal(result, expected) # empty, return dtype bool idx = MultiIndex.from_arrays([[], []]) @@ -4692,9 +5014,9 @@ def test_isin(self): def test_isin_nan(self): idx = MultiIndex.from_arrays([['foo', 'bar'], [1.0, np.nan]]) - self.assert_numpy_array_equal(idx.isin([('bar', np.nan)]), + tm.assert_numpy_array_equal(idx.isin([('bar', np.nan)]), [False, False]) - self.assert_numpy_array_equal(idx.isin([('bar', float('nan'))]), + tm.assert_numpy_array_equal(idx.isin([('bar', float('nan'))]), [False, False]) def test_isin_level_kwarg(self): @@ -4705,11 +5027,11 @@ def test_isin_level_kwarg(self): vals_1 = [2, 3, 10] expected = np.array([False, False, True, True]) - self.assert_numpy_array_equal(expected, idx.isin(vals_0, level=0)) - self.assert_numpy_array_equal(expected, idx.isin(vals_0, level=-2)) + tm.assert_numpy_array_equal(expected, idx.isin(vals_0, level=0)) + tm.assert_numpy_array_equal(expected, idx.isin(vals_0, level=-2)) - self.assert_numpy_array_equal(expected, idx.isin(vals_1, level=1)) - self.assert_numpy_array_equal(expected, idx.isin(vals_1, level=-1)) + tm.assert_numpy_array_equal(expected, idx.isin(vals_1, level=1)) + tm.assert_numpy_array_equal(expected, idx.isin(vals_1, level=-1)) self.assertRaises(IndexError, idx.isin, vals_0, level=5) self.assertRaises(IndexError, idx.isin, vals_0, level=-5) @@ -4719,8 +5041,8 @@ def test_isin_level_kwarg(self): self.assertRaises(KeyError, idx.isin, vals_1, level='A') idx.names = ['A', 'B'] - self.assert_numpy_array_equal(expected, idx.isin(vals_0, level='A')) - self.assert_numpy_array_equal(expected, idx.isin(vals_1, level='B')) + tm.assert_numpy_array_equal(expected, idx.isin(vals_0, level='A')) + tm.assert_numpy_array_equal(expected, idx.isin(vals_1, level='B')) self.assertRaises(KeyError, idx.isin, vals_1, level='C') @@ -4788,47 +5110,9 @@ def test_index_name_retained(self): tm.assert_frame_equal(result, df_expected) def test_equals_operator(self): - # For issue #9785 + # GH9785 self.assertTrue((self.index == self.index).all()) - def test_index_compare(self): - # For issue #9785 - index_unequal = Index(['foo', 'bar', 'baz']) - index_equal = Index([ - ('foo', 'one'), ('foo', 'two'), ('bar', 'one'), - ('baz', 'two'), ('qux', 'one'), ('qux', 'two') - ], tupleize_cols=False) - # Testing Numpy Results Equivelent - assert_array_equal( - index_unequal.equals(self.index), - index_unequal == self.index, - err_msg = 'Index compared with MultiIndex failed', - ) - assert_array_equal( - self.index.equals(index_unequal), - self.index == index_unequal, - err_msg = 'MultiIndex compared with Index failed', - ) - assert_array_equal( - self.index.equals(index_equal), - self.index == index_equal, - err_msg = 'MultiIndex compared with Similar Index failed', - ) - assert_array_equal( - index_equal.equals(self.index), - index_equal == self.index, - err_msg = 'Index compared with Similar MultiIndex failed', - ) - # Testing that the result is true for the index_equal case - self.assertTrue( - (self.index == index_equal).all(), - msg='Assert Index compared with Similar MultiIndex match' - ) - self.assertTrue( - (index_equal == self.index).all(), - msg='Assert MultiIndex compared with Similar Index match' - ) - def test_get_combined_index(): from pandas.core.index import _get_combined_index diff --git a/pandas/tests/test_indexing.py b/pandas/tests/test_indexing.py index 710367bf04605..ee16b44f173ec 100644 --- a/pandas/tests/test_indexing.py +++ b/pandas/tests/test_indexing.py @@ -411,6 +411,12 @@ def test_iloc_exceeds_bounds(self): df.iloc[30] self.assertRaises(IndexError, lambda : df.iloc[-30]) + # GH10779 + # single positive/negative indexer exceeding Series bounds should raise an IndexError + with tm.assertRaisesRegexp(IndexError, 'single positional indexer is out-of-bounds'): + s.iloc[30] + self.assertRaises(IndexError, lambda : s.iloc[-30]) + # slices are ok result = df.iloc[:,4:10] # 0 < start < len < stop expected = df.iloc[:,4:] @@ -471,7 +477,6 @@ def check(result,expected): self.assertRaises(IndexError, lambda : dfl.iloc[[4,5,6]]) self.assertRaises(IndexError, lambda : dfl.iloc[:,4]) - def test_iloc_getitem_int(self): # integer @@ -497,6 +502,33 @@ def test_iloc_getitem_list_int(self): self.check_result('array int', 'iloc', np.array([2]), 'ix', { 0 : [4], 1 : [6], 2: [8] }, typs = ['ints']) self.check_result('array int', 'iloc', np.array([0,1,2]), 'indexer', [0,1,2], typs = ['labels','mixed','ts','floats','empty'], fails = IndexError) + def test_iloc_getitem_neg_int_can_reach_first_index(self): + # GH10547 and GH10779 + # negative integers should be able to reach index 0 + df = DataFrame({'A': [2, 3, 5], 'B': [7, 11, 13]}) + s = df['A'] + + expected = df.iloc[0] + result = df.iloc[-3] + assert_series_equal(result, expected) + + expected = df.iloc[[0]] + result = df.iloc[[-3]] + assert_frame_equal(result, expected) + + expected = s.iloc[0] + result = s.iloc[-3] + self.assertEqual(result, expected) + + expected = s.iloc[[0]] + result = s.iloc[[-3]] + assert_series_equal(result, expected) + + # check the length 1 Series case highlighted in GH10547 + expected = pd.Series(['a'], index=['A']) + result = expected.iloc[[-1]] + assert_series_equal(result, expected) + def test_iloc_getitem_dups(self): # no dups in panel (bug?) @@ -559,16 +591,17 @@ def test_iloc_getitem_slice_dups(self): def test_iloc_getitem_multiindex(self): - df = DataFrame(np.random.randn(3, 3), + arr = np.random.randn(3, 3) + df = DataFrame(arr, columns=[[2,2,4],[6,8,10]], index=[[4,4,8],[8,10,12]]) rs = df.iloc[2] - xp = df.irow(2) + xp = Series(arr[2],index=df.columns) assert_series_equal(rs, xp) rs = df.iloc[:,2] - xp = df.icol(2) + xp = Series(arr[:, 2],index=df.index) assert_series_equal(rs, xp) rs = df.iloc[2,2] @@ -813,8 +846,8 @@ def test_chained_getitem_with_lists(self): # GH6394 # Regression in chained getitem indexing with embedded list-like from 0.12 def check(result, expected): - self.assert_numpy_array_equal(result,expected) - tm.assert_isinstance(result, np.ndarray) + tm.assert_numpy_array_equal(result,expected) + tm.assertIsInstance(result, np.ndarray) df = DataFrame({'A': 5*[np.zeros(3)], 'B':5*[np.ones(3)]}) @@ -1072,6 +1105,25 @@ def test_loc_setitem_consistency(self): df['x'] = 1 assert_frame_equal(df,expected) + # .loc[:,column] setting with slice == len of the column + # GH10408 + data = """Level_0,,,Respondent,Respondent,Respondent,OtherCat,OtherCat +Level_1,,,Something,StartDate,EndDate,Yes/No,SomethingElse +Region,Site,RespondentID,,,,, +Region_1,Site_1,3987227376,A,5/25/2015 10:59,5/25/2015 11:22,Yes, +Region_1,Site_1,3980680971,A,5/21/2015 9:40,5/21/2015 9:52,Yes,Yes +Region_1,Site_2,3977723249,A,5/20/2015 8:27,5/20/2015 8:41,Yes, +Region_1,Site_2,3977723089,A,5/20/2015 8:33,5/20/2015 9:09,Yes,No""" + + df = pd.read_csv(StringIO(data),header=[0,1], index_col=[0,1,2]) + df.loc[:,('Respondent','StartDate')] = pd.to_datetime(df.loc[:,('Respondent','StartDate')]) + df.loc[:,('Respondent','EndDate')] = pd.to_datetime(df.loc[:,('Respondent','EndDate')]) + df.loc[:,('Respondent','Duration')] = df.loc[:,('Respondent','EndDate')] - df.loc[:,('Respondent','StartDate')] + + df.loc[:,('Respondent','Duration')] = df.loc[:,('Respondent','Duration')].astype('timedelta64[s]') + expected = Series([1380,720,840,2160.],index=df.index,name=('Respondent','Duration')) + assert_series_equal(df[('Respondent','Duration')],expected) + def test_loc_setitem_frame(self): df = self.frame_labels @@ -2293,6 +2345,7 @@ def f(): index=pd.MultiIndex.from_product([['A','B','C'],['foo']], names=['one','two']) ).sortlevel() + result = s.loc[idx[:,['foo']]] assert_series_equal(result,expected) result = s.loc[idx[:,['foo','bah']]] @@ -2304,9 +2357,9 @@ def f(): df = DataFrame(np.random.randn(5, 6), index=range(5), columns=multi_index) df = df.sortlevel(0, axis=1) + expected = DataFrame(index=range(5),columns=multi_index.reindex([])[0]) result1 = df.loc[:, ([], slice(None))] result2 = df.loc[:, (['foo'], [])] - expected = DataFrame(index=range(5),columns=multi_index.reindex([])[0]) assert_frame_equal(result1, expected) assert_frame_equal(result2, expected) @@ -2331,14 +2384,14 @@ def test_setitem_dtype_upcast(self): assert_frame_equal(df,expected) # GH10280 - df = DataFrame(np.arange(6,dtype='int64').reshape(2, 3), + df = DataFrame(np.arange(6,dtype='int64').reshape(2, 3), index=list('ab'), columns=['foo', 'bar', 'baz']) for val in [3.14, 'wxyz']: left = df.copy() left.loc['a', 'bar'] = val - right = DataFrame([[0, val, 2], [3, 4, 5]], + right = DataFrame([[0, val, 2], [3, 4, 5]], index=list('ab'), columns=['foo', 'bar', 'baz']) @@ -2346,12 +2399,12 @@ def test_setitem_dtype_upcast(self): self.assertTrue(com.is_integer_dtype(left['foo'])) self.assertTrue(com.is_integer_dtype(left['baz'])) - left = DataFrame(np.arange(6,dtype='int64').reshape(2, 3) / 10.0, + left = DataFrame(np.arange(6,dtype='int64').reshape(2, 3) / 10.0, index=list('ab'), columns=['foo', 'bar', 'baz']) left.loc['a', 'bar'] = 'wxyz' - right = DataFrame([[0, 'wxyz', .2], [.3, .4, .5]], + right = DataFrame([[0, 'wxyz', .2], [.3, .4, .5]], index=list('ab'), columns=['foo', 'bar', 'baz']) @@ -2599,6 +2652,44 @@ def test_panel_setitem(self): tm.assert_panel_equal(p, expected) + def test_panel_setitem_with_multiindex(self): + + # 10360 + # failing with a multi-index + arr = np.array([[[1,2,3],[0,0,0]],[[0,0,0],[0,0,0]]],dtype=np.float64) + + # reg index + axes = dict(items=['A', 'B'], major_axis=[0, 1], minor_axis=['X', 'Y' ,'Z']) + p1 = Panel(0., **axes) + p1.iloc[0, 0, :] = [1, 2, 3] + expected = Panel(arr, **axes) + tm.assert_panel_equal(p1, expected) + + # multi-indexes + axes['items'] = pd.MultiIndex.from_tuples([('A','a'), ('B','b')]) + p2 = Panel(0., **axes) + p2.iloc[0, 0, :] = [1, 2, 3] + expected = Panel(arr, **axes) + tm.assert_panel_equal(p2, expected) + + axes['major_axis']=pd.MultiIndex.from_tuples([('A',1),('A',2)]) + p3 = Panel(0., **axes) + p3.iloc[0, 0, :] = [1, 2, 3] + expected = Panel(arr, **axes) + tm.assert_panel_equal(p3, expected) + + axes['minor_axis']=pd.MultiIndex.from_product([['X'],range(3)]) + p4 = Panel(0., **axes) + p4.iloc[0, 0, :] = [1, 2, 3] + expected = Panel(arr, **axes) + tm.assert_panel_equal(p4, expected) + + arr = np.array([[[1,0,0],[2,0,0]],[[0,0,0],[0,0,0]]],dtype=np.float64) + p5 = Panel(0., **axes) + p5.iloc[0, :, 0] = [1, 2] + expected = Panel(arr, **axes) + tm.assert_panel_equal(p5, expected) + def test_panel_assignment(self): # GH3777 @@ -3040,7 +3131,8 @@ def test_astype_assignment(self): assert_frame_equal(df,expected) df = df_orig.copy() - df.iloc[:,0:2] = df.iloc[:,0:2].convert_objects(convert_numeric=True) + df.iloc[:,0:2] = df.iloc[:,0:2].convert_objects(datetime=True, + numeric=True) expected = DataFrame([[1,2,'3','.4',5,6.,'foo']],columns=list('ABCDEFG')) assert_frame_equal(df,expected) @@ -4082,9 +4174,12 @@ def test_slice_indexer(self): def check_iloc_compat(s): # invalid type for iloc (but works with a warning) - self.assert_produces_warning(FutureWarning, lambda : s.iloc[6.0:8]) - self.assert_produces_warning(FutureWarning, lambda : s.iloc[6.0:8.0]) - self.assert_produces_warning(FutureWarning, lambda : s.iloc[6:8.0]) + with self.assert_produces_warning(FutureWarning): + s.iloc[6.0:8] + with self.assert_produces_warning(FutureWarning): + s.iloc[6.0:8.0] + with self.assert_produces_warning(FutureWarning): + s.iloc[6:8.0] def check_slicing_positional(index): @@ -4744,7 +4839,7 @@ def test_coercion_with_setitem(self): expected_series = Series(expected_result) assert_attr_equal('dtype', start_series, expected_series) - self.assert_numpy_array_equivalent( + tm.assert_numpy_array_equal( start_series.values, expected_series.values, strict_nan=True) @@ -4756,7 +4851,7 @@ def test_coercion_with_loc_setitem(self): expected_series = Series(expected_result) assert_attr_equal('dtype', start_series, expected_series) - self.assert_numpy_array_equivalent( + tm.assert_numpy_array_equal( start_series.values, expected_series.values, strict_nan=True) @@ -4768,7 +4863,7 @@ def test_coercion_with_setitem_and_series(self): expected_series = Series(expected_result) assert_attr_equal('dtype', start_series, expected_series) - self.assert_numpy_array_equivalent( + tm.assert_numpy_array_equal( start_series.values, expected_series.values, strict_nan=True) @@ -4780,7 +4875,7 @@ def test_coercion_with_loc_and_series(self): expected_series = Series(expected_result) assert_attr_equal('dtype', start_series, expected_series) - self.assert_numpy_array_equivalent( + tm.assert_numpy_array_equal( start_series.values, expected_series.values, strict_nan=True) @@ -4807,7 +4902,7 @@ def test_coercion_with_loc(self): expected_dataframe = DataFrame({'foo': expected_result}) assert_attr_equal('dtype', start_dataframe['foo'], expected_dataframe['foo']) - self.assert_numpy_array_equivalent( + tm.assert_numpy_array_equal( start_dataframe['foo'].values, expected_dataframe['foo'].values, strict_nan=True) @@ -4819,7 +4914,7 @@ def test_coercion_with_setitem_and_dataframe(self): expected_dataframe = DataFrame({'foo': expected_result}) assert_attr_equal('dtype', start_dataframe['foo'], expected_dataframe['foo']) - self.assert_numpy_array_equivalent( + tm.assert_numpy_array_equal( start_dataframe['foo'].values, expected_dataframe['foo'].values, strict_nan=True) @@ -4831,7 +4926,7 @@ def test_none_coercion_loc_and_dataframe(self): expected_dataframe = DataFrame({'foo': expected_result}) assert_attr_equal('dtype', start_dataframe['foo'], expected_dataframe['foo']) - self.assert_numpy_array_equivalent( + tm.assert_numpy_array_equal( start_dataframe['foo'].values, expected_dataframe['foo'].values, strict_nan=True) @@ -4851,7 +4946,7 @@ def test_none_coercion_mixed_dtypes(self): for column in expected_dataframe.columns: assert_attr_equal('dtype', start_dataframe[column], expected_dataframe[column]) - self.assert_numpy_array_equivalent( + tm.assert_numpy_array_equal( start_dataframe[column].values, expected_dataframe[column].values, strict_nan=True) diff --git a/pandas/tests/test_internals.py b/pandas/tests/test_internals.py index 36585abd1b98f..7c51641b8e5da 100644 --- a/pandas/tests/test_internals.py +++ b/pandas/tests/test_internals.py @@ -1,6 +1,8 @@ # -*- coding: utf-8 -*- # pylint: disable=W0102 +from datetime import datetime, date + import nose import numpy as np @@ -286,6 +288,26 @@ def test_repr(self): pass +class TestDatetimeBlock(tm.TestCase): + _multiprocess_can_split_ = True + + def test_try_coerce_arg(self): + block = create_block('datetime', [0]) + + # coerce None + none_coerced = block._try_coerce_args(block.values, None)[1] + self.assertTrue(pd.Timestamp(none_coerced) is pd.NaT) + + # coerce different types of date bojects + vals = (np.datetime64('2010-10-10'), + datetime(2010, 10, 10), + date(2010, 10, 10)) + for val in vals: + coerced = block._try_coerce_args(block.values, val)[1] + self.assertEqual(np.int64, type(coerced)) + self.assertEqual(pd.Timestamp('2010-10-10'), pd.Timestamp(coerced)) + + class TestBlockManager(tm.TestCase): _multiprocess_can_split_ = True @@ -554,7 +576,7 @@ def _compare(old_mgr, new_mgr): mgr.set('a', np.array(['1'] * N, dtype=np.object_)) mgr.set('b', np.array(['2.'] * N, dtype=np.object_)) mgr.set('foo', np.array(['foo.'] * N, dtype=np.object_)) - new_mgr = mgr.convert(convert_numeric=True) + new_mgr = mgr.convert(numeric=True) self.assertEqual(new_mgr.get('a').dtype, np.int64) self.assertEqual(new_mgr.get('b').dtype, np.float64) self.assertEqual(new_mgr.get('foo').dtype, np.object_) @@ -566,7 +588,7 @@ def _compare(old_mgr, new_mgr): mgr.set('a', np.array(['1'] * N, dtype=np.object_)) mgr.set('b', np.array(['2.'] * N, dtype=np.object_)) mgr.set('foo', np.array(['foo.'] * N, dtype=np.object_)) - new_mgr = mgr.convert(convert_numeric=True) + new_mgr = mgr.convert(numeric=True) self.assertEqual(new_mgr.get('a').dtype, np.int64) self.assertEqual(new_mgr.get('b').dtype, np.float64) self.assertEqual(new_mgr.get('foo').dtype, np.object_) @@ -636,7 +658,9 @@ def test_interleave_non_unique_cols(self): df_unique = df.copy() df_unique.columns = ['x', 'y'] - np.testing.assert_array_equal(df_unique.values, df.values) + self.assertEqual(df_unique.values.shape, df.values.shape) + tm.assert_numpy_array_equal(df_unique.values[0], df.values[0]) + tm.assert_numpy_array_equal(df_unique.values[1], df.values[1]) def test_consolidate(self): pass @@ -753,15 +777,15 @@ def test_equals(self): def test_equals_block_order_different_dtypes(self): # GH 9330 - - mgr_strings = [ + + mgr_strings = [ "a:i8;b:f8", # basic case "a:i8;b:f8;c:c8;d:b", # many types "a:i8;e:dt;f:td;g:string", # more types "a:i8;b:category;c:category2;d:category2", # categories "c:sparse;d:sparse_na;b:f8", # sparse ] - + for mgr_string in mgr_strings: bm = create_mgr(mgr_string) block_perms = itertools.permutations(bm.blocks) @@ -812,6 +836,13 @@ def test_get_slice(self): def assert_slice_ok(mgr, axis, slobj): # import pudb; pudb.set_trace() mat = mgr.as_matrix() + + # we maybe using an ndarray to test slicing and + # might not be the full length of the axis + if isinstance(slobj, np.ndarray): + ax = mgr.axes[axis] + if len(ax) and len(slobj) and len(slobj) != len(ax): + slobj = np.concatenate([slobj, np.zeros(len(ax)-len(slobj),dtype=bool)]) sliced = mgr.get_slice(slobj, axis=axis) mat_slobj = (slice(None),) * axis + (slobj,) assert_almost_equal(mat[mat_slobj], sliced.as_matrix()) @@ -1037,7 +1068,7 @@ def test_slice_iter(self): def test_slice_to_array_conversion(self): def assert_as_array_equals(slc, asarray): - np.testing.assert_array_equal( + tm.assert_numpy_array_equal( BlockPlacement(slc).as_array, np.asarray(asarray)) diff --git a/pandas/tests/test_lib.py b/pandas/tests/test_lib.py index 6d9bea29cf44d..cfc98f5c20360 100644 --- a/pandas/tests/test_lib.py +++ b/pandas/tests/test_lib.py @@ -4,7 +4,7 @@ import numpy as np import pandas as pd -from pandas.lib import isscalar, item_from_zerodim, max_len_string_array +import pandas.lib as lib import pandas.util.testing as tm from pandas.compat import u, PY2 @@ -14,19 +14,19 @@ class TestMisc(tm.TestCase): def test_max_len_string_array(self): arr = a = np.array(['foo', 'b', np.nan], dtype='object') - self.assertTrue(max_len_string_array(arr), 3) + self.assertTrue(lib.max_len_string_array(arr), 3) # unicode arr = a.astype('U').astype(object) - self.assertTrue(max_len_string_array(arr), 3) + self.assertTrue(lib.max_len_string_array(arr), 3) # bytes for python3 arr = a.astype('S').astype(object) - self.assertTrue(max_len_string_array(arr), 3) + self.assertTrue(lib.max_len_string_array(arr), 3) # raises tm.assertRaises(TypeError, - lambda: max_len_string_array(arr.astype('U'))) + lambda: lib.max_len_string_array(arr.astype('U'))) def test_infer_dtype_bytes(self): compare = 'string' if PY2 else 'bytes' @@ -39,68 +39,197 @@ def test_infer_dtype_bytes(self): arr = arr.astype(object) self.assertEqual(pd.lib.infer_dtype(arr), compare) - -class TestIsscalar(tm.TestCase): + def test_maybe_indices_to_slice_left_edge(self): + target = np.arange(100) + + # slice + indices = np.array([], dtype=np.int64) + maybe_slice = lib.maybe_indices_to_slice(indices, len(target)) + self.assertTrue(isinstance(maybe_slice, slice)) + self.assert_numpy_array_equal(target[indices], target[maybe_slice]) + + for end in [1, 2, 5, 20, 99]: + for step in [1, 2, 4]: + indices = np.arange(0, end, step, dtype=np.int64) + maybe_slice = lib.maybe_indices_to_slice(indices, len(target)) + self.assertTrue(isinstance(maybe_slice, slice)) + self.assert_numpy_array_equal(target[indices], target[maybe_slice]) + + # reverse + indices = indices[::-1] + maybe_slice = lib.maybe_indices_to_slice(indices, len(target)) + self.assertTrue(isinstance(maybe_slice, slice)) + self.assert_numpy_array_equal(target[indices], target[maybe_slice]) + + # not slice + for case in [[2, 1, 2, 0], [2, 2, 1, 0], [0, 1, 2, 1], [-2, 0, 2], [2, 0, -2]]: + indices = np.array(case, dtype=np.int64) + maybe_slice = lib.maybe_indices_to_slice(indices, len(target)) + self.assertFalse(isinstance(maybe_slice, slice)) + self.assert_numpy_array_equal(maybe_slice, indices) + self.assert_numpy_array_equal(target[indices], target[maybe_slice]) + + def test_maybe_indices_to_slice_right_edge(self): + target = np.arange(100) + + # slice + for start in [0, 2, 5, 20, 97, 98]: + for step in [1, 2, 4]: + indices = np.arange(start, 99, step, dtype=np.int64) + maybe_slice = lib.maybe_indices_to_slice(indices, len(target)) + self.assertTrue(isinstance(maybe_slice, slice)) + self.assert_numpy_array_equal(target[indices], target[maybe_slice]) + + # reverse + indices = indices[::-1] + maybe_slice = lib.maybe_indices_to_slice(indices, len(target)) + self.assertTrue(isinstance(maybe_slice, slice)) + self.assert_numpy_array_equal(target[indices], target[maybe_slice]) + + # not slice + indices = np.array([97, 98, 99, 100], dtype=np.int64) + maybe_slice = lib.maybe_indices_to_slice(indices, len(target)) + self.assertFalse(isinstance(maybe_slice, slice)) + self.assert_numpy_array_equal(maybe_slice, indices) + with self.assertRaises(IndexError): + target[indices] + with self.assertRaises(IndexError): + target[maybe_slice] + + indices = np.array([100, 99, 98, 97], dtype=np.int64) + maybe_slice = lib.maybe_indices_to_slice(indices, len(target)) + self.assertFalse(isinstance(maybe_slice, slice)) + self.assert_numpy_array_equal(maybe_slice, indices) + with self.assertRaises(IndexError): + target[indices] + with self.assertRaises(IndexError): + target[maybe_slice] + + for case in [[99, 97, 99, 96], [99, 99, 98, 97], [98, 98, 97, 96]]: + indices = np.array(case, dtype=np.int64) + maybe_slice = lib.maybe_indices_to_slice(indices, len(target)) + self.assertFalse(isinstance(maybe_slice, slice)) + self.assert_numpy_array_equal(maybe_slice, indices) + self.assert_numpy_array_equal(target[indices], target[maybe_slice]) + + def test_maybe_indices_to_slice_both_edges(self): + target = np.arange(10) + + # slice + for step in [1, 2, 4, 5, 8, 9]: + indices = np.arange(0, 9, step, dtype=np.int64) + maybe_slice = lib.maybe_indices_to_slice(indices, len(target)) + self.assertTrue(isinstance(maybe_slice, slice)) + self.assert_numpy_array_equal(target[indices], target[maybe_slice]) + + # reverse + indices = indices[::-1] + maybe_slice = lib.maybe_indices_to_slice(indices, len(target)) + self.assertTrue(isinstance(maybe_slice, slice)) + self.assert_numpy_array_equal(target[indices], target[maybe_slice]) + + # not slice + for case in [[4, 2, 0, -2], [2, 2, 1, 0], [0, 1, 2, 1]]: + indices = np.array(case, dtype=np.int64) + maybe_slice = lib.maybe_indices_to_slice(indices, len(target)) + self.assertFalse(isinstance(maybe_slice, slice)) + self.assert_numpy_array_equal(maybe_slice, indices) + self.assert_numpy_array_equal(target[indices], target[maybe_slice]) + + def test_maybe_indices_to_slice_middle(self): + target = np.arange(100) + + # slice + for start, end in [(2, 10), (5, 25), (65, 97)]: + for step in [1, 2, 4, 20]: + indices = np.arange(start, end, step, dtype=np.int64) + maybe_slice = lib.maybe_indices_to_slice(indices, len(target)) + self.assertTrue(isinstance(maybe_slice, slice)) + self.assert_numpy_array_equal(target[indices], target[maybe_slice]) + + # reverse + indices = indices[::-1] + maybe_slice = lib.maybe_indices_to_slice(indices, len(target)) + self.assertTrue(isinstance(maybe_slice, slice)) + self.assert_numpy_array_equal(target[indices], target[maybe_slice]) + + # not slice + for case in [[14, 12, 10, 12], [12, 12, 11, 10], [10, 11, 12, 11]]: + indices = np.array(case, dtype=np.int64) + maybe_slice = lib.maybe_indices_to_slice(indices, len(target)) + self.assertFalse(isinstance(maybe_slice, slice)) + self.assert_numpy_array_equal(maybe_slice, indices) + self.assert_numpy_array_equal(target[indices], target[maybe_slice]) + + +class Testisscalar(tm.TestCase): def test_isscalar_builtin_scalars(self): - self.assertTrue(isscalar(None)) - self.assertTrue(isscalar(True)) - self.assertTrue(isscalar(False)) - self.assertTrue(isscalar(0.)) - self.assertTrue(isscalar(np.nan)) - self.assertTrue(isscalar('foobar')) - self.assertTrue(isscalar(b'foobar')) - self.assertTrue(isscalar(u('efoobar'))) - self.assertTrue(isscalar(datetime(2014, 1, 1))) - self.assertTrue(isscalar(date(2014, 1, 1))) - self.assertTrue(isscalar(time(12, 0))) - self.assertTrue(isscalar(timedelta(hours=1))) - self.assertTrue(isscalar(pd.NaT)) + self.assertTrue(lib.isscalar(None)) + self.assertTrue(lib.isscalar(True)) + self.assertTrue(lib.isscalar(False)) + self.assertTrue(lib.isscalar(0.)) + self.assertTrue(lib.isscalar(np.nan)) + self.assertTrue(lib.isscalar('foobar')) + self.assertTrue(lib.isscalar(b'foobar')) + self.assertTrue(lib.isscalar(u('efoobar'))) + self.assertTrue(lib.isscalar(datetime(2014, 1, 1))) + self.assertTrue(lib.isscalar(date(2014, 1, 1))) + self.assertTrue(lib.isscalar(time(12, 0))) + self.assertTrue(lib.isscalar(timedelta(hours=1))) + self.assertTrue(lib.isscalar(pd.NaT)) def test_isscalar_builtin_nonscalars(self): - self.assertFalse(isscalar({})) - self.assertFalse(isscalar([])) - self.assertFalse(isscalar([1])) - self.assertFalse(isscalar(())) - self.assertFalse(isscalar((1,))) - self.assertFalse(isscalar(slice(None))) - self.assertFalse(isscalar(Ellipsis)) + self.assertFalse(lib.isscalar({})) + self.assertFalse(lib.isscalar([])) + self.assertFalse(lib.isscalar([1])) + self.assertFalse(lib.isscalar(())) + self.assertFalse(lib.isscalar((1,))) + self.assertFalse(lib.isscalar(slice(None))) + self.assertFalse(lib.isscalar(Ellipsis)) def test_isscalar_numpy_array_scalars(self): - self.assertTrue(isscalar(np.int64(1))) - self.assertTrue(isscalar(np.float64(1.))) - self.assertTrue(isscalar(np.int32(1))) - self.assertTrue(isscalar(np.object_('foobar'))) - self.assertTrue(isscalar(np.str_('foobar'))) - self.assertTrue(isscalar(np.unicode_(u('foobar')))) - self.assertTrue(isscalar(np.bytes_(b'foobar'))) - self.assertTrue(isscalar(np.datetime64('2014-01-01'))) - self.assertTrue(isscalar(np.timedelta64(1, 'h'))) + self.assertTrue(lib.isscalar(np.int64(1))) + self.assertTrue(lib.isscalar(np.float64(1.))) + self.assertTrue(lib.isscalar(np.int32(1))) + self.assertTrue(lib.isscalar(np.object_('foobar'))) + self.assertTrue(lib.isscalar(np.str_('foobar'))) + self.assertTrue(lib.isscalar(np.unicode_(u('foobar')))) + self.assertTrue(lib.isscalar(np.bytes_(b'foobar'))) + self.assertTrue(lib.isscalar(np.datetime64('2014-01-01'))) + self.assertTrue(lib.isscalar(np.timedelta64(1, 'h'))) def test_isscalar_numpy_zerodim_arrays(self): for zerodim in [np.array(1), np.array('foobar'), np.array(np.datetime64('2014-01-01')), np.array(np.timedelta64(1, 'h'))]: - self.assertFalse(isscalar(zerodim)) - self.assertTrue(isscalar(item_from_zerodim(zerodim))) + self.assertFalse(lib.isscalar(zerodim)) + self.assertTrue(lib.isscalar(lib.item_from_zerodim(zerodim))) def test_isscalar_numpy_arrays(self): - self.assertFalse(isscalar(np.array([]))) - self.assertFalse(isscalar(np.array([[]]))) - self.assertFalse(isscalar(np.matrix('1; 2'))) + self.assertFalse(lib.isscalar(np.array([]))) + self.assertFalse(lib.isscalar(np.array([[]]))) + self.assertFalse(lib.isscalar(np.matrix('1; 2'))) def test_isscalar_pandas_scalars(self): - self.assertTrue(isscalar(pd.Timestamp('2014-01-01'))) - self.assertTrue(isscalar(pd.Timedelta(hours=1))) - self.assertTrue(isscalar(pd.Period('2014-01-01'))) - - def test_isscalar_pandas_containers(self): - self.assertFalse(isscalar(pd.Series())) - self.assertFalse(isscalar(pd.Series([1]))) - self.assertFalse(isscalar(pd.DataFrame())) - self.assertFalse(isscalar(pd.DataFrame([[1]]))) - self.assertFalse(isscalar(pd.Panel())) - self.assertFalse(isscalar(pd.Panel([[[1]]]))) - self.assertFalse(isscalar(pd.Index([]))) - self.assertFalse(isscalar(pd.Index([1]))) + self.assertTrue(lib.isscalar(pd.Timestamp('2014-01-01'))) + self.assertTrue(lib.isscalar(pd.Timedelta(hours=1))) + self.assertTrue(lib.isscalar(pd.Period('2014-01-01'))) + + def test_lisscalar_pandas_containers(self): + self.assertFalse(lib.isscalar(pd.Series())) + self.assertFalse(lib.isscalar(pd.Series([1]))) + self.assertFalse(lib.isscalar(pd.DataFrame())) + self.assertFalse(lib.isscalar(pd.DataFrame([[1]]))) + self.assertFalse(lib.isscalar(pd.Panel())) + self.assertFalse(lib.isscalar(pd.Panel([[[1]]]))) + self.assertFalse(lib.isscalar(pd.Index([]))) + self.assertFalse(lib.isscalar(pd.Index([1]))) + + +if __name__ == '__main__': + import nose + + nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'], + exit=False) \ No newline at end of file diff --git a/pandas/tests/test_msgpack/test_buffer.py b/pandas/tests/test_msgpack/test_buffer.py index 940b65406103e..43f5e64012885 100644 --- a/pandas/tests/test_msgpack/test_buffer.py +++ b/pandas/tests/test_msgpack/test_buffer.py @@ -7,6 +7,14 @@ def test_unpack_buffer(): from array import array buf = array('b') - buf.fromstring(packb(('foo', 'bar'))) + buf.fromstring(packb((b'foo', b'bar'))) obj = unpackb(buf, use_list=1) assert [b'foo', b'bar'] == obj + + +def test_unpack_bytearray(): + buf = bytearray(packb(('foo', 'bar'))) + obj = unpackb(buf, use_list=1) + assert [b'foo', b'bar'] == obj + expected_type = bytes + assert all(type(s) == expected_type for s in obj) diff --git a/pandas/tests/test_msgpack/test_case.py b/pandas/tests/test_msgpack/test_case.py index e78456b2ddb62..187668b242495 100644 --- a/pandas/tests/test_msgpack/test_case.py +++ b/pandas/tests/test_msgpack/test_case.py @@ -99,3 +99,4 @@ def test_match(): def test_unicode(): assert unpackb(packb('foobar'), use_list=1) == b'foobar' + diff --git a/pandas/tests/test_msgpack/test_extension.py b/pandas/tests/test_msgpack/test_extension.py new file mode 100644 index 0000000000000..3172605c0aae1 --- /dev/null +++ b/pandas/tests/test_msgpack/test_extension.py @@ -0,0 +1,57 @@ +from __future__ import print_function +import array +import pandas.msgpack as msgpack +from pandas.msgpack import ExtType + + +def test_pack_ext_type(): + def p(s): + packer = msgpack.Packer() + packer.pack_ext_type(0x42, s) + return packer.bytes() + assert p(b'A') == b'\xd4\x42A' # fixext 1 + assert p(b'AB') == b'\xd5\x42AB' # fixext 2 + assert p(b'ABCD') == b'\xd6\x42ABCD' # fixext 4 + assert p(b'ABCDEFGH') == b'\xd7\x42ABCDEFGH' # fixext 8 + assert p(b'A'*16) == b'\xd8\x42' + b'A'*16 # fixext 16 + assert p(b'ABC') == b'\xc7\x03\x42ABC' # ext 8 + assert p(b'A'*0x0123) == b'\xc8\x01\x23\x42' + b'A'*0x0123 # ext 16 + assert p(b'A'*0x00012345) == b'\xc9\x00\x01\x23\x45\x42' + b'A'*0x00012345 # ext 32 + + +def test_unpack_ext_type(): + def check(b, expected): + assert msgpack.unpackb(b) == expected + + check(b'\xd4\x42A', ExtType(0x42, b'A')) # fixext 1 + check(b'\xd5\x42AB', ExtType(0x42, b'AB')) # fixext 2 + check(b'\xd6\x42ABCD', ExtType(0x42, b'ABCD')) # fixext 4 + check(b'\xd7\x42ABCDEFGH', ExtType(0x42, b'ABCDEFGH')) # fixext 8 + check(b'\xd8\x42' + b'A'*16, ExtType(0x42, b'A'*16)) # fixext 16 + check(b'\xc7\x03\x42ABC', ExtType(0x42, b'ABC')) # ext 8 + check(b'\xc8\x01\x23\x42' + b'A'*0x0123, + ExtType(0x42, b'A'*0x0123)) # ext 16 + check(b'\xc9\x00\x01\x23\x45\x42' + b'A'*0x00012345, + ExtType(0x42, b'A'*0x00012345)) # ext 32 + + +def test_extension_type(): + def default(obj): + print('default called', obj) + if isinstance(obj, array.array): + typecode = 123 # application specific typecode + data = obj.tostring() + return ExtType(typecode, data) + raise TypeError("Unknwon type object %r" % (obj,)) + + def ext_hook(code, data): + print('ext_hook called', code, data) + assert code == 123 + obj = array.array('d') + obj.fromstring(data) + return obj + + obj = [42, b'hello', array.array('d', [1.1, 2.2, 3.3])] + s = msgpack.packb(obj, default=default) + obj2 = msgpack.unpackb(s, ext_hook=ext_hook) + assert obj == obj2 diff --git a/pandas/tests/test_msgpack/test_format.py b/pandas/tests/test_msgpack/test_format.py index a3a3afd046ce2..706c48436d7d3 100644 --- a/pandas/tests/test_msgpack/test_format.py +++ b/pandas/tests/test_msgpack/test_format.py @@ -7,7 +7,7 @@ def check(src, should, use_list=0): assert unpackb(src, use_list=use_list) == should def testSimpleValue(): - check(b"\x93\xc0\xc2\xc3", + check(b"\x93\xc0\xc2\xc3", (None, False, True,)) def testFixnum(): diff --git a/pandas/tests/test_msgpack/test_limits.py b/pandas/tests/test_msgpack/test_limits.py new file mode 100644 index 0000000000000..d9aa957182d65 --- /dev/null +++ b/pandas/tests/test_msgpack/test_limits.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# coding: utf-8 +from __future__ import absolute_import, division, print_function, unicode_literals +import pandas.util.testing as tm + +from pandas.msgpack import packb, unpackb, Packer, Unpacker, ExtType + +class TestLimits(tm.TestCase): + def test_integer(self): + x = -(2 ** 63) + assert unpackb(packb(x)) == x + self.assertRaises((OverflowError, ValueError), packb, x-1) + x = 2 ** 64 - 1 + assert unpackb(packb(x)) == x + self.assertRaises((OverflowError, ValueError), packb, x+1) + + + def test_array_header(self): + packer = Packer() + packer.pack_array_header(2**32-1) + self.assertRaises((OverflowError, ValueError), + packer.pack_array_header, 2**32) + + + def test_map_header(self): + packer = Packer() + packer.pack_map_header(2**32-1) + self.assertRaises((OverflowError, ValueError), + packer.pack_array_header, 2**32) + + + def test_max_str_len(self): + d = 'x' * 3 + packed = packb(d) + + unpacker = Unpacker(max_str_len=3, encoding='utf-8') + unpacker.feed(packed) + assert unpacker.unpack() == d + + unpacker = Unpacker(max_str_len=2, encoding='utf-8') + unpacker.feed(packed) + self.assertRaises(ValueError, unpacker.unpack) + + + def test_max_bin_len(self): + d = b'x' * 3 + packed = packb(d, use_bin_type=True) + + unpacker = Unpacker(max_bin_len=3) + unpacker.feed(packed) + assert unpacker.unpack() == d + + unpacker = Unpacker(max_bin_len=2) + unpacker.feed(packed) + self.assertRaises(ValueError, unpacker.unpack) + + + def test_max_array_len(self): + d = [1, 2, 3] + packed = packb(d) + + unpacker = Unpacker(max_array_len=3) + unpacker.feed(packed) + assert unpacker.unpack() == d + + unpacker = Unpacker(max_array_len=2) + unpacker.feed(packed) + self.assertRaises(ValueError, unpacker.unpack) + + + def test_max_map_len(self): + d = {1: 2, 3: 4, 5: 6} + packed = packb(d) + + unpacker = Unpacker(max_map_len=3) + unpacker.feed(packed) + assert unpacker.unpack() == d + + unpacker = Unpacker(max_map_len=2) + unpacker.feed(packed) + self.assertRaises(ValueError, unpacker.unpack) + + + def test_max_ext_len(self): + d = ExtType(42, b"abc") + packed = packb(d) + + unpacker = Unpacker(max_ext_len=3) + unpacker.feed(packed) + assert unpacker.unpack() == d + + unpacker = Unpacker(max_ext_len=2) + unpacker.feed(packed) + self.assertRaises(ValueError, unpacker.unpack) diff --git a/pandas/tests/test_msgpack/test_newspec.py b/pandas/tests/test_msgpack/test_newspec.py new file mode 100644 index 0000000000000..8532ab8cfb1a4 --- /dev/null +++ b/pandas/tests/test_msgpack/test_newspec.py @@ -0,0 +1,88 @@ +# coding: utf-8 + +from pandas.msgpack import packb, unpackb, ExtType + + +def test_str8(): + header = b'\xd9' + data = b'x' * 32 + b = packb(data.decode(), use_bin_type=True) + assert len(b) == len(data) + 2 + assert b[0:2] == header + b'\x20' + assert b[2:] == data + assert unpackb(b) == data + + data = b'x' * 255 + b = packb(data.decode(), use_bin_type=True) + assert len(b) == len(data) + 2 + assert b[0:2] == header + b'\xff' + assert b[2:] == data + assert unpackb(b) == data + + +def test_bin8(): + header = b'\xc4' + data = b'' + b = packb(data, use_bin_type=True) + assert len(b) == len(data) + 2 + assert b[0:2] == header + b'\x00' + assert b[2:] == data + assert unpackb(b) == data + + data = b'x' * 255 + b = packb(data, use_bin_type=True) + assert len(b) == len(data) + 2 + assert b[0:2] == header + b'\xff' + assert b[2:] == data + assert unpackb(b) == data + + +def test_bin16(): + header = b'\xc5' + data = b'x' * 256 + b = packb(data, use_bin_type=True) + assert len(b) == len(data) + 3 + assert b[0:1] == header + assert b[1:3] == b'\x01\x00' + assert b[3:] == data + assert unpackb(b) == data + + data = b'x' * 65535 + b = packb(data, use_bin_type=True) + assert len(b) == len(data) + 3 + assert b[0:1] == header + assert b[1:3] == b'\xff\xff' + assert b[3:] == data + assert unpackb(b) == data + + +def test_bin32(): + header = b'\xc6' + data = b'x' * 65536 + b = packb(data, use_bin_type=True) + assert len(b) == len(data) + 5 + assert b[0:1] == header + assert b[1:5] == b'\x00\x01\x00\x00' + assert b[5:] == data + assert unpackb(b) == data + +def test_ext(): + def check(ext, packed): + assert packb(ext) == packed + assert unpackb(packed) == ext + check(ExtType(0x42, b'Z'), b'\xd4\x42Z') # fixext 1 + check(ExtType(0x42, b'ZZ'), b'\xd5\x42ZZ') # fixext 2 + check(ExtType(0x42, b'Z'*4), b'\xd6\x42' + b'Z'*4) # fixext 4 + check(ExtType(0x42, b'Z'*8), b'\xd7\x42' + b'Z'*8) # fixext 8 + check(ExtType(0x42, b'Z'*16), b'\xd8\x42' + b'Z'*16) # fixext 16 + # ext 8 + check(ExtType(0x42, b''), b'\xc7\x00\x42') + check(ExtType(0x42, b'Z'*255), b'\xc7\xff\x42' + b'Z'*255) + # ext 16 + check(ExtType(0x42, b'Z'*256), b'\xc8\x01\x00\x42' + b'Z'*256) + check(ExtType(0x42, b'Z'*0xffff), b'\xc8\xff\xff\x42' + b'Z'*0xffff) + # ext 32 + check(ExtType(0x42, b'Z'*0x10000), b'\xc9\x00\x01\x00\x00\x42' + b'Z'*0x10000) + # needs large memory + #check(ExtType(0x42, b'Z'*0xffffffff), + # b'\xc9\xff\xff\xff\xff\x42' + b'Z'*0xffffffff) diff --git a/pandas/tests/test_msgpack/test_obj.py b/pandas/tests/test_msgpack/test_obj.py index 4a018bc8b87f1..886fec522d4f3 100644 --- a/pandas/tests/test_msgpack/test_obj.py +++ b/pandas/tests/test_msgpack/test_obj.py @@ -44,13 +44,13 @@ def test_decode_pairs_hook(self): assert unpacked[1] == prod_sum def test_only_one_obj_hook(self): - self.assertRaises(ValueError, unpackb, b'', object_hook=lambda x: x, object_pairs_hook=lambda x: x) + self.assertRaises(TypeError, unpackb, b'', object_hook=lambda x: x, object_pairs_hook=lambda x: x) def test_bad_hook(self): def f(): packed = packb([3, 1+2j], default=lambda o: o) unpacked = unpackb(packed, use_list=1) - self.assertRaises(ValueError, f) + self.assertRaises(TypeError, f) def test_array_hook(self): packed = packb([1,2,3]) diff --git a/pandas/tests/test_msgpack/test_read_size.py b/pandas/tests/test_msgpack/test_read_size.py index db3e1deb04f8f..7cbb9c9807201 100644 --- a/pandas/tests/test_msgpack/test_read_size.py +++ b/pandas/tests/test_msgpack/test_read_size.py @@ -63,3 +63,4 @@ def test_incorrect_type_nested_map(): assert 0, 'should raise exception' except UnexpectedTypeException: assert 1, 'okay' + diff --git a/pandas/tests/test_msgpack/test_seq.py b/pandas/tests/test_msgpack/test_seq.py index e5ee68c4cab84..464ff6d0174af 100644 --- a/pandas/tests/test_msgpack/test_seq.py +++ b/pandas/tests/test_msgpack/test_seq.py @@ -1,21 +1,18 @@ #!/usr/bin/env python # coding: utf-8 -from pandas import compat -from pandas.compat import u +import io import pandas.msgpack as msgpack -binarydata = [chr(i) for i in range(256)] -binarydata = "".join(binarydata) -if compat.PY3: - binarydata = binarydata.encode('utf-8') + +binarydata = bytes(bytearray(range(256))) def gen_binary_data(idx): - data = binarydata[:idx % 300] - return data + return binarydata[:idx % 300] + def test_exceeding_unpacker_read_size(): - dumpf = compat.BytesIO() + dumpf = io.BytesIO() packer = msgpack.Packer() @@ -30,7 +27,7 @@ def test_exceeding_unpacker_read_size(): data = gen_binary_data(idx) dumpf.write(packer.pack(data)) - f = compat.BytesIO(dumpf.getvalue()) + f = io.BytesIO(dumpf.getvalue()) dumpf.close() unpacker = msgpack.Unpacker(f, read_size=read_size, use_list=1) diff --git a/pandas/tests/test_msgpack/test_sequnpack.py b/pandas/tests/test_msgpack/test_sequnpack.py index 4c3ad363e5b6e..72ceed0471437 100644 --- a/pandas/tests/test_msgpack/test_sequnpack.py +++ b/pandas/tests/test_msgpack/test_sequnpack.py @@ -82,3 +82,15 @@ def test_readbytes(self): assert unpacker.read_bytes(3) == b'oob' assert unpacker.unpack() == ord(b'a') assert unpacker.unpack() == ord(b'r') + + def test_issue124(self): + unpacker = Unpacker() + unpacker.feed(b'\xa1?\xa1!') + assert tuple(unpacker) == (b'?', b'!') + assert tuple(unpacker) == () + unpacker.feed(b"\xa1?\xa1") + assert tuple(unpacker) == (b'?',) + assert tuple(unpacker) == () + unpacker.feed(b"!") + assert tuple(unpacker) == (b'!',) + assert tuple(unpacker) == () diff --git a/pandas/tests/test_msgpack/test_unpack.py b/pandas/tests/test_msgpack/test_unpack.py new file mode 100644 index 0000000000000..fe840083ae1c2 --- /dev/null +++ b/pandas/tests/test_msgpack/test_unpack.py @@ -0,0 +1,65 @@ +from io import BytesIO +import sys +from pandas.msgpack import Unpacker, packb, OutOfData, ExtType +import pandas.util.testing as tm +import nose + +class TestUnpack(tm.TestCase): + def test_unpack_array_header_from_file(self): + f = BytesIO(packb([1,2,3,4])) + unpacker = Unpacker(f) + assert unpacker.read_array_header() == 4 + assert unpacker.unpack() == 1 + assert unpacker.unpack() == 2 + assert unpacker.unpack() == 3 + assert unpacker.unpack() == 4 + self.assertRaises(OutOfData, unpacker.unpack) + + + def test_unpacker_hook_refcnt(self): + if not hasattr(sys, 'getrefcount'): + raise nose.SkipTest('no sys.getrefcount()') + result = [] + + def hook(x): + result.append(x) + return x + + basecnt = sys.getrefcount(hook) + + up = Unpacker(object_hook=hook, list_hook=hook) + + assert sys.getrefcount(hook) >= basecnt + 2 + + up.feed(packb([{}])) + up.feed(packb([{}])) + assert up.unpack() == [{}] + assert up.unpack() == [{}] + assert result == [{}, [{}], {}, [{}]] + + del up + + assert sys.getrefcount(hook) == basecnt + + + def test_unpacker_ext_hook(self): + + class MyUnpacker(Unpacker): + + def __init__(self): + super(MyUnpacker, self).__init__(ext_hook=self._hook, + encoding='utf-8') + + def _hook(self, code, data): + if code == 1: + return int(data) + else: + return ExtType(code, data) + + unpacker = MyUnpacker() + unpacker.feed(packb({'a': 1}, encoding='utf-8')) + assert unpacker.unpack() == {'a': 1} + unpacker.feed(packb({'a': ExtType(1, b'123')}, encoding='utf-8')) + assert unpacker.unpack() == {'a': 123} + unpacker.feed(packb({'a': ExtType(2, b'321')}, encoding='utf-8')) + assert unpacker.unpack() == {'a': ExtType(2, b'321')} diff --git a/pandas/tests/test_msgpack/test_unpack_raw.py b/pandas/tests/test_msgpack/test_unpack_raw.py index 0e96a79cf190a..c6bf747c8d992 100644 --- a/pandas/tests/test_msgpack/test_unpack_raw.py +++ b/pandas/tests/test_msgpack/test_unpack_raw.py @@ -1,18 +1,19 @@ """Tests for cases where the user seeks to obtain packed msgpack objects""" -from pandas import compat +import io from pandas.msgpack import Unpacker, packb + def test_write_bytes(): unpacker = Unpacker() unpacker.feed(b'abc') - f = compat.BytesIO() + f = io.BytesIO() assert unpacker.unpack(f.write) == ord('a') assert f.getvalue() == b'a' - f = compat.BytesIO() + f = io.BytesIO() assert unpacker.skip(f.write) is None assert f.getvalue() == b'b' - f = compat.BytesIO() + f = io.BytesIO() assert unpacker.skip() is None assert f.getvalue() == b'' @@ -20,9 +21,9 @@ def test_write_bytes(): def test_write_bytes_multi_buffer(): long_val = (5) * 100 expected = packb(long_val) - unpacker = Unpacker(compat.BytesIO(expected), read_size=3, max_buffer_size=3) + unpacker = Unpacker(io.BytesIO(expected), read_size=3, max_buffer_size=3) - f = compat.BytesIO() + f = io.BytesIO() unpacked = unpacker.unpack(f.write) assert unpacked == long_val assert f.getvalue() == expected diff --git a/pandas/tests/test_multilevel.py b/pandas/tests/test_multilevel.py index 9460c6373d0d2..be7ed6c1b268f 100644 --- a/pandas/tests/test_multilevel.py +++ b/pandas/tests/test_multilevel.py @@ -117,26 +117,26 @@ def test_dataframe_constructor(self): multi = DataFrame(np.random.randn(4, 4), index=[np.array(['a', 'a', 'b', 'b']), np.array(['x', 'y', 'x', 'y'])]) - tm.assert_isinstance(multi.index, MultiIndex) + tm.assertIsInstance(multi.index, MultiIndex) self.assertNotIsInstance(multi.columns, MultiIndex) multi = DataFrame(np.random.randn(4, 4), columns=[['a', 'a', 'b', 'b'], ['x', 'y', 'x', 'y']]) - tm.assert_isinstance(multi.columns, MultiIndex) + tm.assertIsInstance(multi.columns, MultiIndex) def test_series_constructor(self): multi = Series(1., index=[np.array(['a', 'a', 'b', 'b']), np.array(['x', 'y', 'x', 'y'])]) - tm.assert_isinstance(multi.index, MultiIndex) + tm.assertIsInstance(multi.index, MultiIndex) multi = Series(1., index=[['a', 'a', 'b', 'b'], ['x', 'y', 'x', 'y']]) - tm.assert_isinstance(multi.index, MultiIndex) + tm.assertIsInstance(multi.index, MultiIndex) multi = Series(lrange(4), index=[['a', 'a', 'b', 'b'], ['x', 'y', 'x', 'y']]) - tm.assert_isinstance(multi.index, MultiIndex) + tm.assertIsInstance(multi.index, MultiIndex) def test_reindex_level(self): # axis=0 @@ -702,7 +702,7 @@ def test_setitem_change_dtype(self): s = dft['foo', 'two'] dft['foo', 'two'] = s > s.median() assert_series_equal(dft['foo', 'two'], s > s.median()) - # tm.assert_isinstance(dft._data.blocks[1].items, MultiIndex) + # tm.assertIsInstance(dft._data.blocks[1].items, MultiIndex) reindexed = dft.reindex(columns=[('foo', 'two')]) assert_series_equal(reindexed['foo', 'two'], s > s.median()) @@ -798,12 +798,12 @@ def test_reset_index_with_drop(self): self.assertEqual(len(deleveled.columns), len(self.ymd.columns)) deleveled = self.series.reset_index() - tm.assert_isinstance(deleveled, DataFrame) + tm.assertIsInstance(deleveled, DataFrame) self.assertEqual(len(deleveled.columns), len(self.series.index.levels) + 1) deleveled = self.series.reset_index(drop=True) - tm.assert_isinstance(deleveled, Series) + tm.assertIsInstance(deleveled, Series) def test_sortlevel_by_name(self): self.frame.index.names = ['first', 'second'] @@ -964,6 +964,44 @@ def test_stack(self): result = self.ymd.unstack(0).stack(-2) expected = self.ymd.unstack(0).stack(0) + # GH10417 + def check(left, right): + assert_series_equal(left, right) + self.assertFalse(left.index.is_unique) + li, ri = left.index, right.index + for i in range(ri.nlevels): + tm.assert_numpy_array_equal(li.levels[i], ri.levels[i]) + tm.assert_numpy_array_equal(li.labels[i], ri.labels[i]) + + df = DataFrame(np.arange(12).reshape(4, 3), + index=list('abab'), + columns=['1st', '2nd', '3rd']) + + mi = MultiIndex(levels=[['a', 'b'], ['1st', '2nd', '3rd']], + labels=[np.tile(np.arange(2).repeat(3), 2), + np.tile(np.arange(3), 4)]) + + left, right = df.stack(), Series(np.arange(12), index=mi) + check(left, right) + + df.columns = ['1st', '2nd', '1st'] + mi = MultiIndex(levels=[['a', 'b'], ['1st', '2nd']], + labels=[np.tile(np.arange(2).repeat(3), 2), + np.tile([0, 1, 0], 4)]) + + left, right = df.stack(), Series(np.arange(12), index=mi) + check(left, right) + + tpls = ('a', 2), ('b', 1), ('a', 1), ('b', 2) + df.index = MultiIndex.from_tuples(tpls) + mi = MultiIndex(levels=[['a', 'b'], [1, 2], ['1st', '2nd']], + labels=[np.tile(np.arange(2).repeat(3), 2), + np.repeat([1, 0, 1], [3, 6, 3]), + np.tile([0, 1, 0], 4)]) + + left, right = df.stack(), Series(np.arange(12), index=mi) + check(left, right) + def test_unstack_odd_failure(self): data = """day,time,smoker,sum,len Fri,Dinner,No,8.25,3. @@ -1325,7 +1363,7 @@ def test_reorder_levels(self): def test_insert_index(self): df = self.ymd[:5].T df[2000, 1, 10] = df[2000, 1, 7] - tm.assert_isinstance(df.columns, MultiIndex) + tm.assertIsInstance(df.columns, MultiIndex) self.assertTrue((df[2000, 1, 10] == df[2000, 1, 7]).all()) def test_alignment(self): @@ -1993,8 +2031,8 @@ def test_indexing_ambiguity_bug_1678(self): columns=columns) result = frame.ix[:, 1] - exp = frame.icol(1) - tm.assert_isinstance(result, Series) + exp = frame.loc[:, ('Ohio', 'Red')] + tm.assertIsInstance(result, Series) assert_series_equal(result, exp) def test_nonunique_assignment_1750(self): @@ -2098,11 +2136,28 @@ def test_duplicated_drop_duplicates(self): tm.assert_index_equal(idx.drop_duplicates(), expected) expected = np.array([True, False, False, False, False, False]) - duplicated = idx.duplicated(take_last=True) + duplicated = idx.duplicated(keep='last') + tm.assert_numpy_array_equal(duplicated, expected) + self.assertTrue(duplicated.dtype == bool) + expected = MultiIndex.from_arrays(([2, 3, 1, 2 ,3], [1, 1, 1, 2, 2])) + tm.assert_index_equal(idx.drop_duplicates(keep='last'), expected) + + expected = np.array([True, False, False, True, False, False]) + duplicated = idx.duplicated(keep=False) + tm.assert_numpy_array_equal(duplicated, expected) + self.assertTrue(duplicated.dtype == bool) + expected = MultiIndex.from_arrays(([2, 3, 2 ,3], [1, 1, 2, 2])) + tm.assert_index_equal(idx.drop_duplicates(keep=False), expected) + + # deprecate take_last + expected = np.array([True, False, False, False, False, False]) + with tm.assert_produces_warning(FutureWarning): + duplicated = idx.duplicated(take_last=True) tm.assert_numpy_array_equal(duplicated, expected) self.assertTrue(duplicated.dtype == bool) expected = MultiIndex.from_arrays(([2, 3, 1, 2 ,3], [1, 1, 1, 2, 2])) - tm.assert_index_equal(idx.drop_duplicates(take_last=True), expected) + with tm.assert_produces_warning(FutureWarning): + tm.assert_index_equal(idx.drop_duplicates(take_last=True), expected) def test_multiindex_set_index(self): # segfault in #3308 diff --git a/pandas/tests/test_panel.py b/pandas/tests/test_panel.py index 529d3ed68e24d..9cdc769dd7d74 100644 --- a/pandas/tests/test_panel.py +++ b/pandas/tests/test_panel.py @@ -821,7 +821,7 @@ def test_set_value(self): # resize res = self.panel.set_value('ItemE', 'foo', 'bar', 1.5) - tm.assert_isinstance(res, Panel) + tm.assertIsInstance(res, Panel) self.assertIsNot(res, self.panel) self.assertEqual(res.get_value('ItemE', 'foo', 'bar'), 1.5) @@ -1119,7 +1119,7 @@ def test_convert_objects(self): # GH 4937 p = Panel(dict(A = dict(a = ['1','1.0']))) expected = Panel(dict(A = dict(a = [1,1.0]))) - result = p.convert_objects(convert_numeric='force') + result = p.convert_objects(numeric=True, coerce=True) assert_panel_equal(result, expected) def test_dtypes(self): diff --git a/pandas/tests/test_panel4d.py b/pandas/tests/test_panel4d.py index 7a72200077225..289f7f134aa27 100644 --- a/pandas/tests/test_panel4d.py +++ b/pandas/tests/test_panel4d.py @@ -584,7 +584,7 @@ def test_set_value(self): # resize res = self.panel4d.set_value('l4', 'ItemE', 'foo', 'bar', 1.5) - tm.assert_isinstance(res, Panel4D) + tm.assertIsInstance(res, Panel4D) self.assertIsNot(res, self.panel4d) self.assertEqual(res.get_value('l4', 'ItemE', 'foo', 'bar'), 1.5) diff --git a/pandas/tests/test_reshape.py b/pandas/tests/test_reshape.py index 346c9e2598985..2961301366188 100644 --- a/pandas/tests/test_reshape.py +++ b/pandas/tests/test_reshape.py @@ -8,13 +8,13 @@ import nose from pandas import DataFrame, Series +from pandas.core.sparse import SparseDataFrame import pandas as pd from numpy import nan import numpy as np from pandas.util.testing import assert_frame_equal -from numpy.testing import assert_array_equal from pandas.core.reshape import (melt, lreshape, get_dummies, wide_to_long) @@ -171,6 +171,33 @@ def test_basic(self): expected.index = list('ABC') assert_frame_equal(get_dummies(s_series_index, sparse=self.sparse), expected) + def test_basic_types(self): + # GH 10531 + s_list = list('abc') + s_series = Series(s_list) + s_df = DataFrame({'a': [0, 1, 0, 1, 2], + 'b': ['A', 'A', 'B', 'C', 'C'], + 'c': [2, 3, 3, 3, 2]}) + + if not self.sparse: + exp_df_type = DataFrame + exp_blk_type = pd.core.internals.FloatBlock + else: + exp_df_type = SparseDataFrame + exp_blk_type = pd.core.internals.SparseBlock + + self.assertEqual(type(get_dummies(s_list, sparse=self.sparse)), exp_df_type) + self.assertEqual(type(get_dummies(s_series, sparse=self.sparse)), exp_df_type) + + r = get_dummies(s_df, sparse=self.sparse, columns=s_df.columns) + self.assertEqual(type(r), exp_df_type) + + r = get_dummies(s_df, sparse=self.sparse, columns=['a']) + self.assertEqual(type(r[['a_0']]._data.blocks[0]), exp_blk_type) + self.assertEqual(type(r[['a_1']]._data.blocks[0]), exp_blk_type) + self.assertEqual(type(r[['a_2']]._data.blocks[0]), exp_blk_type) + + def test_just_na(self): just_na_list = [np.nan] just_na_series = Series(just_na_list) @@ -206,7 +233,7 @@ def test_include_na(self): res_just_na = get_dummies([nan], dummy_na=True, sparse=self.sparse) exp_just_na = DataFrame(Series(1.0,index=[0]),columns=[nan]) - assert_array_equal(res_just_na.values, exp_just_na.values) + tm.assert_numpy_array_equal(res_just_na.values, exp_just_na.values) def test_unicode(self): # See GH 6885 - get_dummies chokes on unicode values import unicodedata diff --git a/pandas/tests/test_rplot.py b/pandas/tests/test_rplot.py index c58f17550a137..e79acfcbc58d8 100644 --- a/pandas/tests/test_rplot.py +++ b/pandas/tests/test_rplot.py @@ -160,7 +160,7 @@ def setUp(self): def test_gradient(self): for index in range(len(self.data)): - row = self.data.irow(index) + row = self.data.iloc[index] r, g, b = self.gradient(self.data, index) r1, g1, b1 = self.gradient.colour1 r2, g2, b2 = self.gradient.colour2 @@ -178,7 +178,7 @@ def setUp(self): def test_gradient2(self): for index in range(len(self.data)): - row = self.data.irow(index) + row = self.data.iloc[index] r, g, b = self.gradient(self.data, index) r1, g1, b1 = self.gradient.colour1 r2, g2, b2 = self.gradient.colour2 diff --git a/pandas/tests/test_series.py b/pandas/tests/test_series.py index ff0d5739588f2..56146df37a27f 100644 --- a/pandas/tests/test_series.py +++ b/pandas/tests/test_series.py @@ -8,6 +8,7 @@ from inspect import getargspec from itertools import product, starmap from distutils.version import LooseVersion +import warnings import nose @@ -35,6 +36,7 @@ from pandas.util.testing import (assert_series_equal, assert_almost_equal, assert_frame_equal, + assert_index_equal, ensure_clean) import pandas.util.testing as tm @@ -81,9 +83,10 @@ def test_dt_namespace_accessor(self): ok_for_base = ['year','month','day','hour','minute','second','weekofyear','week','dayofweek','weekday','dayofyear','quarter','freq','days_in_month','daysinmonth'] ok_for_period = ok_for_base + ['qyear'] + ok_for_period_methods = ['strftime'] ok_for_dt = ok_for_base + ['date','time','microsecond','nanosecond', 'is_month_start', 'is_month_end', 'is_quarter_start', 'is_quarter_end', 'is_year_start', 'is_year_end', 'tz'] - ok_for_dt_methods = ['to_period','to_pydatetime','tz_localize','tz_convert', 'normalize'] + ok_for_dt_methods = ['to_period','to_pydatetime','tz_localize','tz_convert', 'normalize', 'strftime'] ok_for_td = ['days','seconds','microseconds','nanoseconds'] ok_for_td_methods = ['components','to_pytimedelta'] @@ -109,13 +112,12 @@ def compare(s, name): Series(date_range('20130101',periods=5,freq='s')), Series(date_range('20130101 00:00:00',periods=5,freq='ms'))]: for prop in ok_for_dt: - # we test freq below if prop != 'freq': compare(s, prop) for prop in ok_for_dt_methods: - getattr(s.dt,prop) + getattr(s.dt, prop) result = s.dt.to_pydatetime() self.assertIsInstance(result,np.ndarray) @@ -140,13 +142,12 @@ def compare(s, name): Series(timedelta_range('1 day 01:23:45',periods=5,freq='s')), Series(timedelta_range('2 days 01:23:45.012345',periods=5,freq='ms'))]: for prop in ok_for_td: - # we test freq below if prop != 'freq': compare(s, prop) for prop in ok_for_td_methods: - getattr(s.dt,prop) + getattr(s.dt, prop) result = s.dt.components self.assertIsInstance(result,DataFrame) @@ -169,13 +170,14 @@ def compare(s, name): # periodindex for s in [Series(period_range('20130101',periods=5,freq='D'))]: - for prop in ok_for_period: - # we test freq below if prop != 'freq': compare(s, prop) + for prop in ok_for_period_methods: + getattr(s.dt, prop) + freq_result = s.dt.freq self.assertEqual(freq_result, PeriodIndex(s.values).freq) @@ -190,7 +192,7 @@ def get_dir(s): s = Series(period_range('20130101',periods=5,freq='D').asobject) results = get_dir(s) - tm.assert_almost_equal(results,list(sorted(set(ok_for_period)))) + tm.assert_almost_equal(results, list(sorted(set(ok_for_period + ok_for_period_methods)))) # no setting allowed s = Series(date_range('20130101',periods=5,freq='D')) @@ -203,13 +205,68 @@ def f(): s.dt.hour[0] = 5 self.assertRaises(com.SettingWithCopyError, f) + def test_strftime(self): + # GH 10086 + s = Series(date_range('20130101', periods=5)) + result = s.dt.strftime('%Y/%m/%d') + expected = Series(['2013/01/01', '2013/01/02', '2013/01/03', '2013/01/04', '2013/01/05']) + tm.assert_series_equal(result, expected) + + s = Series(date_range('2015-02-03 11:22:33.4567', periods=5)) + result = s.dt.strftime('%Y/%m/%d %H-%M-%S') + expected = Series(['2015/02/03 11-22-33', '2015/02/04 11-22-33', '2015/02/05 11-22-33', + '2015/02/06 11-22-33', '2015/02/07 11-22-33']) + tm.assert_series_equal(result, expected) + + s = Series(period_range('20130101', periods=5)) + result = s.dt.strftime('%Y/%m/%d') + expected = Series(['2013/01/01', '2013/01/02', '2013/01/03', '2013/01/04', '2013/01/05']) + tm.assert_series_equal(result, expected) + + s = Series(period_range('2015-02-03 11:22:33.4567', periods=5, freq='s')) + result = s.dt.strftime('%Y/%m/%d %H-%M-%S') + expected = Series(['2015/02/03 11-22-33', '2015/02/03 11-22-34', '2015/02/03 11-22-35', + '2015/02/03 11-22-36', '2015/02/03 11-22-37']) + tm.assert_series_equal(result, expected) + + s = Series(date_range('20130101', periods=5)) + s.iloc[0] = pd.NaT + result = s.dt.strftime('%Y/%m/%d') + expected = Series(['NaT', '2013/01/02', '2013/01/03', '2013/01/04', '2013/01/05']) + tm.assert_series_equal(result, expected) + + datetime_index = date_range('20150301', periods=5) + result = datetime_index.strftime("%Y/%m/%d") + expected = np.array(['2015/03/01', '2015/03/02', '2015/03/03', '2015/03/04', '2015/03/05'], dtype=object) + self.assert_numpy_array_equal(result, expected) + + period_index = period_range('20150301', periods=5) + result = period_index.strftime("%Y/%m/%d") + expected = np.array(['2015/03/01', '2015/03/02', '2015/03/03', '2015/03/04', '2015/03/05'], dtype=object) + self.assert_numpy_array_equal(result, expected) + + s = Series([datetime(2013, 1, 1, 2, 32, 59), datetime(2013, 1, 2, 14, 32, 1)]) + result = s.dt.strftime('%Y-%m-%d %H:%M:%S') + expected = Series(["2013-01-01 02:32:59", "2013-01-02 14:32:01"]) + tm.assert_series_equal(result, expected) + + s = Series(period_range('20130101', periods=4, freq='H')) + result = s.dt.strftime('%Y/%m/%d %H:%M:%S') + expected = Series(["2013/01/01 00:00:00", "2013/01/01 01:00:00", + "2013/01/01 02:00:00", "2013/01/01 03:00:00"]) + + s = Series(period_range('20130101', periods=4, freq='L')) + result = s.dt.strftime('%Y/%m/%d %H:%M:%S.%l') + expected = Series(["2013/01/01 00:00:00.000", "2013/01/01 00:00:00.001", + "2013/01/01 00:00:00.002", "2013/01/01 00:00:00.003"]) + tm.assert_series_equal(result, expected) + def test_valid_dt_with_missing_values(self): from datetime import date, time # GH 8689 s = Series(date_range('20130101',periods=5,freq='D')) - s_orig = s.copy() s.iloc[2] = pd.NaT for attr in ['microsecond','nanosecond','second','minute','hour','day']: @@ -503,11 +560,6 @@ def test_comparisons(self): s == s2 s2 == s - def test_none_comparison(self): - # bug brought up by #1079 - s = Series(np.random.randn(10), index=lrange(0, 20, 2)) - self.assertRaises(TypeError, s.__eq__, None) - def test_sum_zero(self): arr = np.array([]) self.assertEqual(nanops.nansum(arr), 0) @@ -581,7 +633,6 @@ class TestSeries(tm.TestCase, CheckNameIntegration): def setUp(self): import warnings - warnings.filterwarnings(action='ignore', category=FutureWarning) self.ts = _ts.copy() self.ts.name = 'ts' @@ -696,9 +747,7 @@ def test_constructor_map(self): def test_constructor_categorical(self): cat = pd.Categorical([0, 1, 2, 0, 1, 2], ['a', 'b', 'c'], fastpath=True) - cat.name = 'foo' res = Series(cat) - self.assertEqual(res.name, cat.name) self.assertTrue(res.values.equals(cat)) def test_constructor_maskedarray(self): @@ -781,7 +830,7 @@ def test_constructor_corner(self): df = tm.makeTimeDataFrame() objs = [df, df] s = Series(objs, index=[0, 1]) - tm.assert_isinstance(s, Series) + tm.assertIsInstance(s, Series) def test_constructor_sanitize(self): s = Series(np.array([1., 1., 8.]), dtype='i8') @@ -1069,7 +1118,7 @@ def test_setindex(self): # works series = self.series.copy() series.index = np.arange(len(series)) - tm.assert_isinstance(series.index, Index) + tm.assertIsInstance(series.index, Index) def test_array_finalize(self): pass @@ -1151,14 +1200,28 @@ def test_getitem_get(self): self.assertIsNone(result) def test_iget(self): + s = Series(np.random.randn(10), index=lrange(0, 20, 2)) + + # 10711, deprecated + with tm.assert_produces_warning(FutureWarning): + s.iget(1) + + # 10711, deprecated + with tm.assert_produces_warning(FutureWarning): + s.irow(1) + + # 10711, deprecated + with tm.assert_produces_warning(FutureWarning): + s.iget_value(1) + for i in range(len(s)): - result = s.iget(i) + result = s.iloc[i] exp = s[s.index[i]] assert_almost_equal(result, exp) # pass a slice - result = s.iget(slice(1, 3)) + result = s.iloc[slice(1, 3)] expected = s.ix[2:4] assert_series_equal(result, expected) @@ -1167,13 +1230,13 @@ def test_iget(self): self.assertTrue((s[1:3] == 0).all()) # list of integers - result = s.iget([0, 2, 3, 4, 5]) + result = s.iloc[[0, 2, 3, 4, 5]] expected = s.reindex(s.index[[0, 2, 3, 4, 5]]) assert_series_equal(result, expected) def test_iget_nonunique(self): s = Series([0, 1, 2], index=[0, 1, 0]) - self.assertEqual(s.iget(2), 2) + self.assertEqual(s.iloc[2], 2) def test_getitem_regression(self): s = Series(lrange(5), index=lrange(5)) @@ -1326,7 +1389,7 @@ def test_getitem_setitem_integers(self): def test_getitem_box_float64(self): value = self.ts[5] - tm.assert_isinstance(value, np.float64) + tm.assertIsInstance(value, np.float64) def test_getitem_ambiguous_keyerror(self): s = Series(lrange(10), index=lrange(0, 20, 2)) @@ -1480,6 +1543,18 @@ def test_setitem(self): expected = self.series.append(app) assert_series_equal(s, expected) + # Test for issue #10193 + key = pd.Timestamp('2012-01-01') + series = pd.Series() + series[key] = 47 + expected = pd.Series(47, [key]) + assert_series_equal(series, expected) + + series = pd.Series([], pd.DatetimeIndex([], freq='D')) + series[key] = 47 + expected = pd.Series(47, pd.DatetimeIndex([key], freq='D')) + assert_series_equal(series, expected) + def test_setitem_dtypes(self): # change dtypes @@ -1556,7 +1631,7 @@ def test_reshape_non_2d(self): a = Series([1, 2, 3, 4]) result = a.reshape(2, 2) expected = a.values.reshape(2, 2) - np.testing.assert_array_equal(result, expected) + tm.assert_numpy_array_equal(result, expected) self.assertTrue(type(result) is type(expected)) def test_reshape_2d_return_array(self): @@ -3120,7 +3195,7 @@ def test_operators_timedelta64(self): # scalar Timestamp on rhs maxa = df['A'].max() - tm.assert_isinstance(maxa, Timestamp) + tm.assertIsInstance(maxa, Timestamp) resultb = df['A'] - df['A'].max() self.assertEqual(resultb.dtype, 'timedelta64[ns]') @@ -3211,14 +3286,37 @@ def test_timedeltas_with_DateOffset(self): s + op(5) op(5) + s - # invalid DateOffsets - for do in [ 'Week', 'BDay', 'BQuarterEnd', 'BMonthEnd', 'BYearEnd', - 'BYearBegin','BQuarterBegin', 'BMonthBegin', - 'MonthEnd','YearBegin', 'YearEnd', - 'MonthBegin', 'QuarterBegin' ]: + + def test_timedelta64_operations_with_DateOffset(self): + # GH 10699 + td = Series([timedelta(minutes=5, seconds=3)] * 3) + result = td + pd.offsets.Minute(1) + expected = Series([timedelta(minutes=6, seconds=3)] * 3) + assert_series_equal(result, expected) + + result = td - pd.offsets.Minute(1) + expected = Series([timedelta(minutes=4, seconds=3)] * 3) + assert_series_equal(result, expected) + + result = td + Series([pd.offsets.Minute(1), pd.offsets.Second(3), + pd.offsets.Hour(2)]) + expected = Series([timedelta(minutes=6, seconds=3), + timedelta(minutes=5, seconds=6), + timedelta(hours=2, minutes=5, seconds=3)]) + assert_series_equal(result, expected) + + result = td + pd.offsets.Minute(1) + pd.offsets.Second(12) + expected = Series([timedelta(minutes=6, seconds=15)] * 3) + assert_series_equal(result, expected) + + # valid DateOffsets + for do in [ 'Hour', 'Minute', 'Second', 'Day', 'Micro', + 'Milli', 'Nano' ]: op = getattr(pd.offsets,do) - self.assertRaises(TypeError, s.__add__, op(5)) - self.assertRaises(TypeError, s.__radd__, op(5)) + td + op(5) + op(5) + td + td - op(5) + op(5) - td def test_timedelta64_operations_with_timedeltas(self): @@ -4707,29 +4805,69 @@ def test_axis_alias(self): self.assertEqual(s._get_axis_name('rows'), 'index') def test_drop_duplicates(self): - s = Series([1, 2, 3, 3]) + # check both int and object + for s in [Series([1, 2, 3, 3]), Series(['1', '2', '3', '3'])]: + expected = Series([False, False, False, True]) + assert_series_equal(s.duplicated(), expected) + assert_series_equal(s.drop_duplicates(), s[~expected]) + sc = s.copy() + sc.drop_duplicates(inplace=True) + assert_series_equal(sc, s[~expected]) - result = s.duplicated() - expected = Series([False, False, False, True]) - assert_series_equal(result, expected) + expected = Series([False, False, True, False]) + assert_series_equal(s.duplicated(keep='last'), expected) + assert_series_equal(s.drop_duplicates(keep='last'), s[~expected]) + sc = s.copy() + sc.drop_duplicates(keep='last', inplace=True) + assert_series_equal(sc, s[~expected]) + # deprecate take_last + with tm.assert_produces_warning(FutureWarning): + assert_series_equal(s.duplicated(take_last=True), expected) + with tm.assert_produces_warning(FutureWarning): + assert_series_equal(s.drop_duplicates(take_last=True), s[~expected]) + sc = s.copy() + with tm.assert_produces_warning(FutureWarning): + sc.drop_duplicates(take_last=True, inplace=True) + assert_series_equal(sc, s[~expected]) - result = s.duplicated(take_last=True) - expected = Series([False, False, True, False]) - assert_series_equal(result, expected) + expected = Series([False, False, True, True]) + assert_series_equal(s.duplicated(keep=False), expected) + assert_series_equal(s.drop_duplicates(keep=False), s[~expected]) + sc = s.copy() + sc.drop_duplicates(keep=False, inplace=True) + assert_series_equal(sc, s[~expected]) + + for s in [Series([1, 2, 3, 5, 3, 2, 4]), + Series(['1', '2', '3', '5', '3', '2', '4'])]: + expected = Series([False, False, False, False, True, True, False]) + assert_series_equal(s.duplicated(), expected) + assert_series_equal(s.drop_duplicates(), s[~expected]) + sc = s.copy() + sc.drop_duplicates(inplace=True) + assert_series_equal(sc, s[~expected]) - result = s.drop_duplicates() - expected = s[[True, True, True, False]] - assert_series_equal(result, expected) - sc = s.copy() - sc.drop_duplicates(inplace=True) - assert_series_equal(sc, expected) + expected = Series([False, True, True, False, False, False, False]) + assert_series_equal(s.duplicated(keep='last'), expected) + assert_series_equal(s.drop_duplicates(keep='last'), s[~expected]) + sc = s.copy() + sc.drop_duplicates(keep='last', inplace=True) + assert_series_equal(sc, s[~expected]) + # deprecate take_last + with tm.assert_produces_warning(FutureWarning): + assert_series_equal(s.duplicated(take_last=True), expected) + with tm.assert_produces_warning(FutureWarning): + assert_series_equal(s.drop_duplicates(take_last=True), s[~expected]) + sc = s.copy() + with tm.assert_produces_warning(FutureWarning): + sc.drop_duplicates(take_last=True, inplace=True) + assert_series_equal(sc, s[~expected]) - result = s.drop_duplicates(take_last=True) - expected = s[[True, True, False, True]] - assert_series_equal(result, expected) - sc = s.copy() - sc.drop_duplicates(take_last=True, inplace=True) - assert_series_equal(sc, expected) + expected = Series([False, True, True, False, True, True, False]) + assert_series_equal(s.duplicated(keep=False), expected) + assert_series_equal(s.drop_duplicates(keep=False), s[~expected]) + sc = s.copy() + sc.drop_duplicates(keep=False, inplace=True) + assert_series_equal(sc, s[~expected]) def test_sort(self): ts = self.ts.copy() @@ -4967,6 +5105,11 @@ def test_from_csv(self): self.assertTrue(ts.name is None) self.assertTrue(ts.index.name is None) + # GH10483 + self.ts.to_csv(path, header=True) + ts_h = Series.from_csv(path, header=0) + self.assertTrue(ts_h.name == 'ts') + self.series.to_csv(path) series = Series.from_csv(path) self.assertIsNone(series.name) @@ -4975,6 +5118,10 @@ def test_from_csv(self): self.assertTrue(series.name is None) self.assertTrue(series.index.name is None) + self.series.to_csv(path, header=True) + series_h = Series.from_csv(path, header=0) + self.assertTrue(series_h.name == 'series') + outfile = open(path, 'w') outfile.write('1998-01-01|1.0\n1999-01-01|2.0') outfile.close() @@ -5090,7 +5237,7 @@ def test_clip(self): result = self.ts.clip(-0.5, 0.5) expected = np.clip(self.ts, -0.5, 0.5) assert_series_equal(result, expected) - tm.assert_isinstance(expected, Series) + tm.assertIsInstance(expected, Series) def test_clip_types_and_nulls(self): @@ -5239,6 +5386,25 @@ def test_shift_int(self): expected = ts.astype(float).shift(1) assert_series_equal(shifted, expected) + def test_shift_categorical(self): + # GH 9416 + s = pd.Series(['a', 'b', 'c', 'd'], dtype='category') + + assert_series_equal(s.iloc[:-1], s.shift(1).shift(-1).valid()) + + sp1 = s.shift(1) + assert_index_equal(s.index, sp1.index) + self.assertTrue(np.all(sp1.values.codes[:1] == -1)) + self.assertTrue(np.all(s.values.codes[:-1] == sp1.values.codes[1:])) + + sn2 = s.shift(-2) + assert_index_equal(s.index, sn2.index) + self.assertTrue(np.all(sn2.values.codes[-2:] == -1)) + self.assertTrue(np.all(s.values.codes[2:] == sn2.values.codes[:-2])) + + assert_index_equal(s.values.categories, sp1.values.categories) + assert_index_equal(s.values.categories, sn2.values.categories) + def test_truncate(self): offset = datetools.bday @@ -5741,6 +5907,35 @@ def test_map(self): result = self.ts.map(lambda x: x * 2) self.assert_numpy_array_equal(result, self.ts * 2) + # GH 10324 + a = Series([1, 2, 3, 4]) + b = Series(["even", "odd", "even", "odd"], dtype="category") + c = Series(["even", "odd", "even", "odd"]) + + exp = Series(["odd", "even", "odd", np.nan], dtype="category") + self.assert_series_equal(a.map(b), exp) + exp = Series(["odd", "even", "odd", np.nan]) + self.assert_series_equal(a.map(c), exp) + + a = Series(['a', 'b', 'c', 'd']) + b = Series([1, 2, 3, 4], index=pd.CategoricalIndex(['b', 'c', 'd', 'e'])) + c = Series([1, 2, 3, 4], index=Index(['b', 'c', 'd', 'e'])) + + exp = Series([np.nan, 1, 2, 3]) + self.assert_series_equal(a.map(b), exp) + exp = Series([np.nan, 1, 2, 3]) + self.assert_series_equal(a.map(c), exp) + + a = Series(['a', 'b', 'c', 'd']) + b = Series(['B', 'C', 'D', 'E'], dtype='category', + index=pd.CategoricalIndex(['b', 'c', 'd', 'e'])) + c = Series(['B', 'C', 'D', 'E'], index=Index(['b', 'c', 'd', 'e'])) + + exp = Series([np.nan, 'B', 'C', 'D'], dtype='category') + self.assert_series_equal(a.map(b), exp) + exp = Series([np.nan, 'B', 'C', 'D']) + self.assert_series_equal(a.map(c), exp) + def test_map_compat(self): # related GH 8024 s = Series([True,True,False],index=[1,2,3]) @@ -5786,7 +5981,7 @@ def test_map_decimal(self): result = self.series.map(lambda x: Decimal(str(x))) self.assertEqual(result.dtype, np.object_) - tm.assert_isinstance(result[0], Decimal) + tm.assertIsInstance(result[0], Decimal) def test_map_na_exclusion(self): s = Series([1.5, np.nan, 3, np.nan, 5]) @@ -5862,39 +6057,105 @@ def test_apply_dont_convert_dtype(self): result = s.apply(f, convert_dtype=False) self.assertEqual(result.dtype, object) + # GH 10265 def test_convert_objects(self): + # Tests: All to nans, coerce, true + # Test coercion returns correct type + s = Series(['a', 'b', 'c']) + results = s.convert_objects(datetime=True, coerce=True) + expected = Series([lib.NaT] * 3) + assert_series_equal(results, expected) + + results = s.convert_objects(numeric=True, coerce=True) + expected = Series([np.nan] * 3) + assert_series_equal(results, expected) + + expected = Series([lib.NaT] * 3, dtype=np.dtype('m8[ns]')) + results = s.convert_objects(timedelta=True, coerce=True) + assert_series_equal(results, expected) + + dt = datetime(2001, 1, 1, 0, 0) + td = dt - datetime(2000, 1, 1, 0, 0) + + # Test coercion with mixed types + s = Series(['a', '3.1415', dt, td]) + results = s.convert_objects(datetime=True, coerce=True) + expected = Series([lib.NaT, lib.NaT, dt, lib.NaT]) + assert_series_equal(results, expected) + + results = s.convert_objects(numeric=True, coerce=True) + expected = Series([nan, 3.1415, nan, nan]) + assert_series_equal(results, expected) + + results = s.convert_objects(timedelta=True, coerce=True) + expected = Series([lib.NaT, lib.NaT, lib.NaT, td], + dtype=np.dtype('m8[ns]')) + assert_series_equal(results, expected) + + # Test standard conversion returns original + results = s.convert_objects(datetime=True) + assert_series_equal(results, s) + results = s.convert_objects(numeric=True) + expected = Series([nan, 3.1415, nan, nan]) + assert_series_equal(results, expected) + results = s.convert_objects(timedelta=True) + assert_series_equal(results, s) + + # test pass-through and non-conversion when other types selected + s = Series(['1.0','2.0','3.0']) + results = s.convert_objects(datetime=True, numeric=True, timedelta=True) + expected = Series([1.0,2.0,3.0]) + assert_series_equal(results, expected) + results = s.convert_objects(True,False,True) + assert_series_equal(results, s) + + s = Series([datetime(2001, 1, 1, 0, 0),datetime(2001, 1, 1, 0, 0)], + dtype='O') + results = s.convert_objects(datetime=True, numeric=True, timedelta=True) + expected = Series([datetime(2001, 1, 1, 0, 0),datetime(2001, 1, 1, 0, 0)]) + assert_series_equal(results, expected) + results = s.convert_objects(datetime=False,numeric=True,timedelta=True) + assert_series_equal(results, s) + + td = datetime(2001, 1, 1, 0, 0) - datetime(2000, 1, 1, 0, 0) + s = Series([td, td], dtype='O') + results = s.convert_objects(datetime=True, numeric=True, timedelta=True) + expected = Series([td, td]) + assert_series_equal(results, expected) + results = s.convert_objects(True,True,False) + assert_series_equal(results, s) + s = Series([1., 2, 3], index=['a', 'b', 'c']) - result = s.convert_objects(convert_dates=False, convert_numeric=True) + result = s.convert_objects(numeric=True) assert_series_equal(result, s) # force numeric conversion r = s.copy().astype('O') r['a'] = '1' - result = r.convert_objects(convert_dates=False, convert_numeric=True) + result = r.convert_objects(numeric=True) assert_series_equal(result, s) r = s.copy().astype('O') r['a'] = '1.' - result = r.convert_objects(convert_dates=False, convert_numeric=True) + result = r.convert_objects(numeric=True) assert_series_equal(result, s) r = s.copy().astype('O') r['a'] = 'garbled' + result = r.convert_objects(numeric=True) expected = s.copy() - expected['a'] = np.nan - result = r.convert_objects(convert_dates=False, convert_numeric=True) + expected['a'] = nan assert_series_equal(result, expected) # GH 4119, not converting a mixed type (e.g.floats and object) s = Series([1, 'na', 3, 4]) - result = s.convert_objects(convert_numeric=True) - expected = Series([1, np.nan, 3, 4]) + result = s.convert_objects(datetime=True, numeric=True) + expected = Series([1, nan, 3, 4]) assert_series_equal(result, expected) s = Series([1, '', 3, 4]) - result = s.convert_objects(convert_numeric=True) - expected = Series([1, np.nan, 3, 4]) + result = s.convert_objects(datetime=True, numeric=True) assert_series_equal(result, expected) # dates @@ -5903,38 +6164,34 @@ def test_convert_objects(self): s2 = Series([datetime(2001, 1, 1, 0, 0), datetime(2001, 1, 2, 0, 0), datetime( 2001, 1, 3, 0, 0), 'foo', 1.0, 1, Timestamp('20010104'), '20010105'], dtype='O') - result = s.convert_objects(convert_dates=True, convert_numeric=False) + result = s.convert_objects(datetime=True) expected = Series( [Timestamp('20010101'), Timestamp('20010102'), Timestamp('20010103')], dtype='M8[ns]') assert_series_equal(result, expected) - result = s.convert_objects( - convert_dates='coerce', convert_numeric=False) - result = s.convert_objects( - convert_dates='coerce', convert_numeric=True) + result = s.convert_objects(datetime=True, coerce=True) assert_series_equal(result, expected) expected = Series( [Timestamp( '20010101'), Timestamp('20010102'), Timestamp('20010103'), lib.NaT, lib.NaT, lib.NaT, Timestamp('20010104'), Timestamp('20010105')], dtype='M8[ns]') - result = s2.convert_objects( - convert_dates='coerce', convert_numeric=False) + result = s2.convert_objects(datetime=True, + numeric=False, + timedelta=False, + coerce=True) assert_series_equal(result, expected) - result = s2.convert_objects( - convert_dates='coerce', convert_numeric=True) + result = s2.convert_objects(datetime=True, coerce=True) assert_series_equal(result, expected) - # preserver all-nans (if convert_dates='coerce') s = Series(['foo', 'bar', 1, 1.0], dtype='O') - result = s.convert_objects( - convert_dates='coerce', convert_numeric=False) - assert_series_equal(result, s) + result = s.convert_objects(datetime=True, coerce=True) + expected = Series([lib.NaT]*4) + assert_series_equal(result, expected) # preserver if non-object s = Series([1], dtype='float32') - result = s.convert_objects( - convert_dates='coerce', convert_numeric=False) + result = s.convert_objects(datetime=True, coerce=True) assert_series_equal(result, s) #r = s.copy() @@ -5943,23 +6200,31 @@ def test_convert_objects(self): #self.assertEqual(result.dtype, 'M8[ns]') # dateutil parses some single letters into today's value as a date + expected = Series([lib.NaT]) for x in 'abcdefghijklmnopqrstuvwxyz': s = Series([x]) - result = s.convert_objects(convert_dates='coerce') - assert_series_equal(result, s) + result = s.convert_objects(datetime=True, coerce=True) + assert_series_equal(result, expected) s = Series([x.upper()]) - result = s.convert_objects(convert_dates='coerce') - assert_series_equal(result, s) + result = s.convert_objects(datetime=True, coerce=True) + assert_series_equal(result, expected) + + def test_convert_objects_no_arg_warning(self): + s = Series(['1.0','2']) + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always', DeprecationWarning) + s.convert_objects() + self.assertEqual(len(w), 1) def test_convert_objects_preserve_bool(self): s = Series([1, True, 3, 5], dtype=object) - r = s.convert_objects(convert_numeric=True) + r = s.convert_objects(datetime=True, numeric=True) e = Series([1, 1, 3, 5], dtype='i8') tm.assert_series_equal(r, e) def test_convert_objects_preserve_all_bool(self): s = Series([False, True, False, False], dtype=object) - r = s.convert_objects(convert_numeric=True) + r = s.convert_objects(datetime=True, numeric=True) e = Series([False, True, False, False], dtype=bool) tm.assert_series_equal(r, e) @@ -5968,7 +6233,7 @@ def test_apply_args(self): result = s.apply(str.split, args=(',',)) self.assertEqual(result[0], ['foo', 'bar']) - tm.assert_isinstance(result[0], list) + tm.assertIsInstance(result[0], list) def test_align(self): def _check_align(a, b, how='left', fill=None): @@ -6086,6 +6351,38 @@ def test_align_sameindex(self): # self.assertIsNot(a.index, self.ts.index) # self.assertIsNot(b.index, self.ts.index) + def test_align_multiindex(self): + # GH 10665 + + midx = pd.MultiIndex.from_product([range(2), range(3), range(2)], + names=('a', 'b', 'c')) + idx = pd.Index(range(2), name='b') + s1 = pd.Series(np.arange(12,dtype='int64'), index=midx) + s2 = pd.Series(np.arange(2,dtype='int64'), index=idx) + + # these must be the same results (but flipped) + res1l, res1r = s1.align(s2, join='left') + res2l, res2r = s2.align(s1, join='right') + + expl = s1 + tm.assert_series_equal(expl, res1l) + tm.assert_series_equal(expl, res2r) + expr = pd.Series([0, 0, 1, 1, np.nan, np.nan] * 2, index=midx) + tm.assert_series_equal(expr, res1r) + tm.assert_series_equal(expr, res2l) + + res1l, res1r = s1.align(s2, join='right') + res2l, res2r = s2.align(s1, join='left') + + exp_idx = pd.MultiIndex.from_product([range(2), range(2), range(2)], + names=('a', 'b', 'c')) + expl = pd.Series([0, 1, 2, 3, 6, 7, 8, 9], index=exp_idx) + tm.assert_series_equal(expl, res1l) + tm.assert_series_equal(expl, res2r) + expr = pd.Series([0, 0, 1, 1] * 2, index=exp_idx) + tm.assert_series_equal(expr, res1r) + tm.assert_series_equal(expr, res2l) + def test_reindex(self): identity = self.series.reindex(self.series.index) @@ -6200,6 +6497,13 @@ def test_reindex_nearest(self): actual = s.reindex_like(actual, method='nearest') assert_series_equal(expected, actual) + actual = s.reindex_like(actual, method='nearest', tolerance=1) + assert_series_equal(expected, actual) + + actual = s.reindex(target, method='nearest', tolerance=0.2) + expected = Series([0, 1, np.nan, 2], target) + assert_series_equal(expected, actual) + def test_reindex_backfill(self): pass @@ -6937,13 +7241,13 @@ def test_searchsorted_numeric_dtypes_scalar(self): r = s.searchsorted([30]) e = np.array([2]) - tm.assert_array_equal(r, e) + tm.assert_numpy_array_equal(r, e) def test_searchsorted_numeric_dtypes_vector(self): s = Series([1, 2, 90, 1000, 3e9]) r = s.searchsorted([91, 2e6]) e = np.array([3, 4]) - tm.assert_array_equal(r, e) + tm.assert_numpy_array_equal(r, e) def test_search_sorted_datetime64_scalar(self): s = Series(pd.date_range('20120101', periods=10, freq='2D')) @@ -6957,14 +7261,14 @@ def test_search_sorted_datetime64_list(self): v = [pd.Timestamp('20120102'), pd.Timestamp('20120104')] r = s.searchsorted(v) e = np.array([1, 2]) - tm.assert_array_equal(r, e) + tm.assert_numpy_array_equal(r, e) def test_searchsorted_sorter(self): # GH8490 s = Series([3, 1, 2]) r = s.searchsorted([0, 3], sorter=np.argsort(s)) e = np.array([0, 2]) - tm.assert_array_equal(r, e) + tm.assert_numpy_array_equal(r, e) def test_to_frame_expanddim(self): # GH 9762 @@ -7069,7 +7373,7 @@ def test_reset_index(self): rs = s.reset_index(level=[0, 2], drop=True) self.assertTrue(rs.index.equals(Index(index.get_level_values(1)))) - tm.assert_isinstance(rs, Series) + tm.assertIsInstance(rs, Series) def test_set_index_makes_timeseries(self): idx = tm.makeDateIndex(10) diff --git a/pandas/tests/test_strings.py b/pandas/tests/test_strings.py index a66410320e816..6a9ad175f42dd 100644 --- a/pandas/tests/test_strings.py +++ b/pandas/tests/test_strings.py @@ -11,7 +11,6 @@ from numpy import nan as NA import numpy as np -from numpy.testing import assert_array_equal from numpy.random import randint from pandas.compat import range, lrange, u, unichr @@ -49,11 +48,11 @@ def test_iter(self): for s in ds.str: # iter must yield a Series - tm.assert_isinstance(s, Series) + tm.assertIsInstance(s, Series) # indices of each yielded Series should be equal to the index of # the original Series - assert_array_equal(s.index, ds.index) + tm.assert_numpy_array_equal(s.index, ds.index) for el in s: # each element of the series is either a basestring/str or nan @@ -135,7 +134,7 @@ def test_count(self): tm.assert_almost_equal(result, exp) result = Series(values).str.count('f[o]+') - tm.assert_isinstance(result, Series) + tm.assertIsInstance(result, Series) tm.assert_almost_equal(result, exp) # mixed @@ -145,7 +144,7 @@ def test_count(self): tm.assert_almost_equal(rs, xp) rs = Series(mixed).str.count('a') - tm.assert_isinstance(rs, Series) + tm.assertIsInstance(rs, Series) tm.assert_almost_equal(rs, xp) # unicode @@ -156,7 +155,7 @@ def test_count(self): tm.assert_almost_equal(result, exp) result = Series(values).str.count('f[o]+') - tm.assert_isinstance(result, Series) + tm.assertIsInstance(result, Series) tm.assert_almost_equal(result, exp) def test_contains(self): @@ -195,7 +194,7 @@ def test_contains(self): tm.assert_almost_equal(rs, xp) rs = Series(mixed).str.contains('o') - tm.assert_isinstance(rs, Series) + tm.assertIsInstance(rs, Series) tm.assert_almost_equal(rs, xp) # unicode @@ -235,7 +234,7 @@ def test_startswith(self): tm.assert_almost_equal(rs, xp) rs = Series(mixed).str.startswith('f') - tm.assert_isinstance(rs, Series) + tm.assertIsInstance(rs, Series) tm.assert_almost_equal(rs, xp) # unicode @@ -263,7 +262,7 @@ def test_endswith(self): tm.assert_almost_equal(rs, xp) rs = Series(mixed).str.endswith('f') - tm.assert_isinstance(rs, Series) + tm.assertIsInstance(rs, Series) tm.assert_almost_equal(rs, xp) # unicode @@ -315,7 +314,7 @@ def test_lower_upper(self): mixed = mixed.str.upper() rs = Series(mixed).str.lower() xp = ['a', NA, 'b', NA, NA, 'foo', NA, NA, NA] - tm.assert_isinstance(rs, Series) + tm.assertIsInstance(rs, Series) tm.assert_almost_equal(rs, xp) # unicode @@ -392,7 +391,7 @@ def test_replace(self): rs = Series(mixed).str.replace('BAD[_]*', '') xp = ['a', NA, 'b', NA, NA, 'foo', NA, NA, NA] - tm.assert_isinstance(rs, Series) + tm.assertIsInstance(rs, Series) tm.assert_almost_equal(rs, xp) # unicode @@ -429,7 +428,7 @@ def test_repeat(self): rs = Series(mixed).str.repeat(3) xp = ['aaa', NA, 'bbb', NA, NA, 'foofoofoo', NA, NA, NA] - tm.assert_isinstance(rs, Series) + tm.assertIsInstance(rs, Series) tm.assert_almost_equal(rs, xp) # unicode @@ -462,7 +461,7 @@ def test_deprecated_match(self): with tm.assert_produces_warning(): rs = Series(mixed).str.match('.*(BAD[_]+).*(BAD)') xp = [('BAD_', 'BAD'), NA, ('BAD_', 'BAD'), NA, NA, [], NA, NA, NA] - tm.assert_isinstance(rs, Series) + tm.assertIsInstance(rs, Series) tm.assert_almost_equal(rs, xp) # unicode @@ -495,7 +494,7 @@ def test_match(self): with tm.assert_produces_warning(): rs = Series(mixed).str.match('.*(BAD[_]+).*(BAD)', as_indexer=True) xp = [True, NA, True, NA, NA, False, NA, NA, NA] - tm.assert_isinstance(rs, Series) + tm.assertIsInstance(rs, Series) tm.assert_almost_equal(rs, xp) # unicode @@ -561,7 +560,7 @@ def test_extract(self): s_or_idx = klass(['A1', 'A2']) result = s_or_idx.str.extract(r'(?PA)\d') tm.assert_equal(result.name, 'uno') - tm.assert_array_equal(result, klass(['A', 'A'])) + tm.assert_numpy_array_equal(result, klass(['A', 'A'])) s = Series(['A1', 'B2', 'C3']) # one group, no matches @@ -747,20 +746,18 @@ def test_isnumeric(self): # 0x2605: ★ not number # 0x1378: ፸ ETHIOPIC NUMBER SEVENTY # 0xFF13: 3 Em 3 - values = ['A', '3', unichr(0x00bc), unichr(0x2605), - unichr(0x1378), unichr(0xFF13), 'four'] + values = ['A', '3', u'¼', u'★', u'፸', u'3', 'four'] s = Series(values) numeric_e = [False, True, True, False, True, True, False] decimal_e = [False, True, False, False, False, True, False] tm.assert_series_equal(s.str.isnumeric(), Series(numeric_e)) tm.assert_series_equal(s.str.isdecimal(), Series(decimal_e)) - unicodes = [u('A'), u('3'), unichr(0x00bc), unichr(0x2605), - unichr(0x1378), unichr(0xFF13), u('four')] + + unicodes = [u'A', u'3', u'¼', u'★', u'፸', u'3', u'four'] self.assertEqual(s.str.isnumeric().tolist(), [v.isnumeric() for v in unicodes]) self.assertEqual(s.str.isdecimal().tolist(), [v.isdecimal() for v in unicodes]) - values = ['A', np.nan, unichr(0x00bc), unichr(0x2605), - np.nan, unichr(0xFF13), 'four'] + values = ['A', np.nan, u'¼', u'★', np.nan, u'3', 'four'] s = Series(values) numeric_e = [False, np.nan, True, False, np.nan, True, False] decimal_e = [False, np.nan, False, False, np.nan, True, False] @@ -798,7 +795,7 @@ def test_join(self): rs = Series(mixed).str.split('_').str.join('_') xp = Series(['a_b', NA, 'asdf_cas_asdf', NA, NA, 'foo', NA, NA, NA]) - tm.assert_isinstance(rs, Series) + tm.assertIsInstance(rs, Series) tm.assert_almost_equal(rs, xp) # unicode @@ -821,7 +818,7 @@ def test_len(self): rs = Series(mixed).str.len() xp = Series([3, NA, 13, NA, NA, 3, NA, NA, NA]) - tm.assert_isinstance(rs, Series) + tm.assertIsInstance(rs, Series) tm.assert_almost_equal(rs, xp) # unicode @@ -846,7 +843,7 @@ def test_findall(self): rs = Series(mixed).str.findall('BAD[_]*') xp = Series([['BAD__', 'BAD'], NA, [], NA, NA, ['BAD'], NA, NA, NA]) - tm.assert_isinstance(rs, Series) + tm.assertIsInstance(rs, Series) tm.assert_almost_equal(rs, xp) # unicode @@ -920,34 +917,34 @@ def test_index(self): s = klass(['ABCDEFG', 'BCDEFEF', 'DEFGHIJEF', 'EFGHEF']) result = s.str.index('EF') - tm.assert_array_equal(result, klass([4, 3, 1, 0])) + tm.assert_numpy_array_equal(result, klass([4, 3, 1, 0])) expected = np.array([v.index('EF') for v in s.values]) - tm.assert_array_equal(result.values, expected) + tm.assert_numpy_array_equal(result.values, expected) result = s.str.rindex('EF') - tm.assert_array_equal(result, klass([4, 5, 7, 4])) + tm.assert_numpy_array_equal(result, klass([4, 5, 7, 4])) expected = np.array([v.rindex('EF') for v in s.values]) - tm.assert_array_equal(result.values, expected) + tm.assert_numpy_array_equal(result.values, expected) result = s.str.index('EF', 3) - tm.assert_array_equal(result, klass([4, 3, 7, 4])) + tm.assert_numpy_array_equal(result, klass([4, 3, 7, 4])) expected = np.array([v.index('EF', 3) for v in s.values]) - tm.assert_array_equal(result.values, expected) + tm.assert_numpy_array_equal(result.values, expected) result = s.str.rindex('EF', 3) - tm.assert_array_equal(result, klass([4, 5, 7, 4])) + tm.assert_numpy_array_equal(result, klass([4, 5, 7, 4])) expected = np.array([v.rindex('EF', 3) for v in s.values]) - tm.assert_array_equal(result.values, expected) + tm.assert_numpy_array_equal(result.values, expected) result = s.str.index('E', 4, 8) - tm.assert_array_equal(result, klass([4, 5, 7, 4])) + tm.assert_numpy_array_equal(result, klass([4, 5, 7, 4])) expected = np.array([v.index('E', 4, 8) for v in s.values]) - tm.assert_array_equal(result.values, expected) + tm.assert_numpy_array_equal(result.values, expected) result = s.str.rindex('E', 0, 5) - tm.assert_array_equal(result, klass([4, 3, 1, 4])) + tm.assert_numpy_array_equal(result, klass([4, 3, 1, 4])) expected = np.array([v.rindex('E', 0, 5) for v in s.values]) - tm.assert_array_equal(result.values, expected) + tm.assert_numpy_array_equal(result.values, expected) with tm.assertRaisesRegexp(ValueError, "substring not found"): result = s.str.index('DE') @@ -958,9 +955,9 @@ def test_index(self): # test with nan s = Series(['abcb', 'ab', 'bcbe', np.nan]) result = s.str.index('b') - tm.assert_array_equal(result, Series([1, 1, 0, np.nan])) + tm.assert_numpy_array_equal(result, Series([1, 1, 0, np.nan])) result = s.str.rindex('b') - tm.assert_array_equal(result, Series([3, 1, 2, np.nan])) + tm.assert_numpy_array_equal(result, Series([3, 1, 2, np.nan])) def test_pad(self): values = Series(['a', 'b', NA, 'c', NA, 'eeeeee']) @@ -984,7 +981,7 @@ def test_pad(self): rs = Series(mixed).str.pad(5, side='left') xp = Series([' a', NA, ' b', NA, NA, ' ee', NA, NA, NA]) - tm.assert_isinstance(rs, Series) + tm.assertIsInstance(rs, Series) tm.assert_almost_equal(rs, xp) mixed = Series(['a', NA, 'b', True, datetime.today(), @@ -993,7 +990,7 @@ def test_pad(self): rs = Series(mixed).str.pad(5, side='right') xp = Series(['a ', NA, 'b ', NA, NA, 'ee ', NA, NA, NA]) - tm.assert_isinstance(rs, Series) + tm.assertIsInstance(rs, Series) tm.assert_almost_equal(rs, xp) mixed = Series(['a', NA, 'b', True, datetime.today(), @@ -1002,7 +999,7 @@ def test_pad(self): rs = Series(mixed).str.pad(5, side='both') xp = Series([' a ', NA, ' b ', NA, NA, ' ee ', NA, NA, NA]) - tm.assert_isinstance(rs, Series) + tm.assertIsInstance(rs, Series) tm.assert_almost_equal(rs, xp) # unicode @@ -1056,17 +1053,17 @@ def test_translate(self): table = str.maketrans('abc', 'cde') result = s.str.translate(table) expected = klass(['cdedefg', 'cdee', 'edddfg', 'edefggg']) - tm.assert_array_equal(result, expected) + tm.assert_numpy_array_equal(result, expected) # use of deletechars is python 2 only if not compat.PY3: result = s.str.translate(table, deletechars='fg') expected = klass(['cdede', 'cdee', 'eddd', 'ede']) - tm.assert_array_equal(result, expected) + tm.assert_numpy_array_equal(result, expected) result = s.str.translate(None, deletechars='fg') expected = klass(['abcde', 'abcc', 'cddd', 'cde']) - tm.assert_array_equal(result, expected) + tm.assert_numpy_array_equal(result, expected) else: with tm.assertRaisesRegexp(ValueError, "deletechars is not a valid argument"): result = s.str.translate(table, deletechars='fg') @@ -1075,7 +1072,7 @@ def test_translate(self): s = Series(['a', 'b', 'c', 1.2]) expected = Series(['c', 'd', 'e', np.nan]) result = s.str.translate(table) - tm.assert_array_equal(result, expected) + tm.assert_numpy_array_equal(result, expected) def test_center_ljust_rjust(self): values = Series(['a', 'b', NA, 'c', NA, 'eeeeee']) @@ -1099,19 +1096,19 @@ def test_center_ljust_rjust(self): rs = Series(mixed).str.center(5) xp = Series([' a ', NA, ' b ', NA, NA, ' c ', ' eee ', NA, NA, NA]) - tm.assert_isinstance(rs, Series) + tm.assertIsInstance(rs, Series) tm.assert_almost_equal(rs, xp) rs = Series(mixed).str.ljust(5) xp = Series(['a ', NA, 'b ', NA, NA, 'c ', 'eee ', NA, NA, NA]) - tm.assert_isinstance(rs, Series) + tm.assertIsInstance(rs, Series) tm.assert_almost_equal(rs, xp) rs = Series(mixed).str.rjust(5) xp = Series([' a', NA, ' b', NA, NA, ' c', ' eee', NA, NA, NA]) - tm.assert_isinstance(rs, Series) + tm.assertIsInstance(rs, Series) tm.assert_almost_equal(rs, xp) # unicode @@ -1216,11 +1213,11 @@ def test_split(self): result = mixed.str.split('_') exp = Series([['a', 'b', 'c'], NA, ['d', 'e', 'f'], NA, NA, NA, NA, NA]) - tm.assert_isinstance(result, Series) + tm.assertIsInstance(result, Series) tm.assert_almost_equal(result, exp) result = mixed.str.split('_', expand=False) - tm.assert_isinstance(result, Series) + tm.assertIsInstance(result, Series) tm.assert_almost_equal(result, exp) # unicode @@ -1263,11 +1260,11 @@ def test_rsplit(self): result = mixed.str.rsplit('_') exp = Series([['a', 'b', 'c'], NA, ['d', 'e', 'f'], NA, NA, NA, NA, NA]) - tm.assert_isinstance(result, Series) + tm.assertIsInstance(result, Series) tm.assert_almost_equal(result, exp) result = mixed.str.rsplit('_', expand=False) - tm.assert_isinstance(result, Series) + tm.assertIsInstance(result, Series) tm.assert_almost_equal(result, exp) # unicode @@ -1614,7 +1611,7 @@ def test_slice(self): xp = Series(['foo', NA, 'bar', NA, NA, NA, NA, NA]) - tm.assert_isinstance(rs, Series) + tm.assertIsInstance(rs, Series) tm.assert_almost_equal(rs, xp) rs = Series(mixed).str.slice(2, 5, -1) @@ -1692,21 +1689,21 @@ def test_strip_lstrip_rstrip_mixed(self): xp = Series(['aa', NA, 'bb', NA, NA, NA, NA, NA]) - tm.assert_isinstance(rs, Series) + tm.assertIsInstance(rs, Series) tm.assert_almost_equal(rs, xp) rs = Series(mixed).str.lstrip() xp = Series(['aa ', NA, 'bb \t\n', NA, NA, NA, NA, NA]) - tm.assert_isinstance(rs, Series) + tm.assertIsInstance(rs, Series) tm.assert_almost_equal(rs, xp) rs = Series(mixed).str.rstrip() xp = Series([' aa', NA, ' bb', NA, NA, NA, NA, NA]) - tm.assert_isinstance(rs, Series) + tm.assertIsInstance(rs, Series) tm.assert_almost_equal(rs, xp) def test_strip_lstrip_rstrip_unicode(self): @@ -1799,7 +1796,7 @@ def test_get(self): xp = Series(['b', NA, 'd', NA, NA, NA, NA, NA]) - tm.assert_isinstance(rs, Series) + tm.assertIsInstance(rs, Series) tm.assert_almost_equal(rs, xp) # unicode @@ -1950,33 +1947,16 @@ def test_encode_decode_errors(self): tm.assert_series_equal(result, exp) def test_normalize(self): - def unistr(codes): - # build unicode string from unichr - # we cannot use six.u() here because it escapes unicode - return ''.join([unichr(c) for c in codes]) - - values = ['ABC', # ASCII - unistr([0xFF21, 0xFF22, 0xFF23]), # ABC - unistr([0xFF11, 0xFF12, 0xFF13]), # 123 - np.nan, - unistr([0xFF71, 0xFF72, 0xFF74])] # アイエ + values = ['ABC', u'ABC', u'123', np.nan, u'アイエ'] s = Series(values, index=['a', 'b', 'c', 'd', 'e']) - normed = [compat.u_safe('ABC'), - compat.u_safe('ABC'), - compat.u_safe('123'), - np.nan, - unistr([0x30A2, 0x30A4, 0x30A8])] # アイエ + normed = [u'ABC', u'ABC', u'123', np.nan, u'アイエ'] expected = Series(normed, index=['a', 'b', 'c', 'd', 'e']) result = s.str.normalize('NFKC') tm.assert_series_equal(result, expected) - expected = Series([compat.u_safe('ABC'), - unistr([0xFF21, 0xFF22, 0xFF23]), # ABC - unistr([0xFF11, 0xFF12, 0xFF13]), # 123 - np.nan, - unistr([0xFF71, 0xFF72, 0xFF74])], # アイエ + expected = Series([u'ABC', u'ABC', u'123', np.nan, u'アイエ'], index=['a', 'b', 'c', 'd', 'e']) result = s.str.normalize('NFC') @@ -1985,12 +1965,8 @@ def unistr(codes): with tm.assertRaisesRegexp(ValueError, "invalid normalization form"): s.str.normalize('xxx') - s = Index([unistr([0xFF21, 0xFF22, 0xFF23]), # ABC - unistr([0xFF11, 0xFF12, 0xFF13]), # 123 - unistr([0xFF71, 0xFF72, 0xFF74])]) # アイエ - expected = Index([compat.u_safe('ABC'), - compat.u_safe('123'), - unistr([0x30A2, 0x30A4, 0x30A8])]) + s = Index([u'ABC', u'123', u'アイエ']) + expected = Index([u'ABC', u'123', u'アイエ']) result = s.str.normalize('NFKC') tm.assert_index_equal(result, expected) diff --git a/pandas/tests/test_testing.py b/pandas/tests/test_testing.py index cc0a0ea5662db..466ad3f220020 100644 --- a/pandas/tests/test_testing.py +++ b/pandas/tests/test_testing.py @@ -7,15 +7,17 @@ import numpy as np import sys from pandas import Series, DataFrame +import pandas.util.testing as tm from pandas.util.testing import ( - assert_almost_equal, assertRaisesRegexp, raise_with_traceback, - assert_series_equal, assert_frame_equal, - RNGContext + assert_almost_equal, assertRaisesRegexp, raise_with_traceback, + assert_index_equal, assert_series_equal, assert_frame_equal, + assert_numpy_array_equal, assert_isinstance, RNGContext ) +from pandas.compat import is_platform_windows # let's get meta. -class TestAssertAlmostEqual(unittest.TestCase): +class TestAssertAlmostEqual(tm.TestCase): _multiprocess_can_split_ = True def _assert_almost_equal_both(self, a, b, **kwargs): @@ -112,7 +114,8 @@ def test_assert_almost_equal_inf(self): self._assert_not_almost_equal_both(np.inf, 0) -class TestUtilTesting(unittest.TestCase): + +class TestUtilTesting(tm.TestCase): _multiprocess_can_split_ = True def test_raise_with_traceback(self): @@ -130,7 +133,280 @@ def test_raise_with_traceback(self): _, _, traceback = sys.exc_info() raise_with_traceback(e, traceback) -class TestAssertSeriesEqual(unittest.TestCase): + +class TestAssertNumpyArrayEqual(tm.TestCase): + + def test_numpy_array_equal_message(self): + + if is_platform_windows(): + raise nose.SkipTest("windows has incomparable line-endings and uses L on the shape") + + expected = """numpy array are different + +numpy array shapes are different +\\[left\\]: \\(2,\\) +\\[right\\]: \\(3,\\)""" + with assertRaisesRegexp(AssertionError, expected): + assert_numpy_array_equal(np.array([1, 2]), np.array([3, 4, 5])) + + with assertRaisesRegexp(AssertionError, expected): + assert_almost_equal(np.array([1, 2]), np.array([3, 4, 5])) + + # scalar comparison + expected = """: 1 != 2""" + with assertRaisesRegexp(AssertionError, expected): + assert_numpy_array_equal(1, 2) + expected = """expected 2\\.00000 but got 1\\.00000, with decimal 5""" + with assertRaisesRegexp(AssertionError, expected): + assert_almost_equal(1, 2) + + # array / scalar array comparison + expected = """(numpy array|Iterable) are different + +First object is iterable, second isn't +\\[left\\]: \\[1\\] +\\[right\\]: 1""" + with assertRaisesRegexp(AssertionError, expected): + assert_numpy_array_equal(np.array([1]), 1) + with assertRaisesRegexp(AssertionError, expected): + assert_almost_equal(np.array([1]), 1) + + # scalar / array comparison + expected = """(numpy array|Iterable) are different + +Second object is iterable, first isn't +\\[left\\]: 1 +\\[right\\]: \\[1\\]""" + with assertRaisesRegexp(AssertionError, expected): + assert_numpy_array_equal(1, np.array([1])) + with assertRaisesRegexp(AssertionError, expected): + assert_almost_equal(1, np.array([1])) + + expected = """numpy array are different + +numpy array values are different \\(66\\.66667 %\\) +\\[left\\]: \\[nan, 2\\.0, 3\\.0\\] +\\[right\\]: \\[1\\.0, nan, 3\\.0\\]""" + with assertRaisesRegexp(AssertionError, expected): + assert_numpy_array_equal(np.array([np.nan, 2, 3]), np.array([1, np.nan, 3])) + with assertRaisesRegexp(AssertionError, expected): + assert_almost_equal(np.array([np.nan, 2, 3]), np.array([1, np.nan, 3])) + + expected = """numpy array are different + +numpy array values are different \\(50\\.0 %\\) +\\[left\\]: \\[1, 2\\] +\\[right\\]: \\[1, 3\\]""" + with assertRaisesRegexp(AssertionError, expected): + assert_numpy_array_equal(np.array([1, 2]), np.array([1, 3])) + with assertRaisesRegexp(AssertionError, expected): + assert_almost_equal(np.array([1, 2]), np.array([1, 3])) + + + expected = """numpy array are different + +numpy array values are different \\(50\\.0 %\\) +\\[left\\]: \\[1\\.1, 2\\.000001\\] +\\[right\\]: \\[1\\.1, 2.0\\]""" + with assertRaisesRegexp(AssertionError, expected): + assert_numpy_array_equal(np.array([1.1, 2.000001]), np.array([1.1, 2.0])) + + # must pass + assert_almost_equal(np.array([1.1, 2.000001]), np.array([1.1, 2.0])) + + expected = """numpy array are different + +numpy array values are different \\(16\\.66667 %\\) +\\[left\\]: \\[\\[1, 2\\], \\[3, 4\\], \\[5, 6\\]\\] +\\[right\\]: \\[\\[1, 3\\], \\[3, 4\\], \\[5, 6\\]\\]""" + with assertRaisesRegexp(AssertionError, expected): + assert_numpy_array_equal(np.array([[1, 2], [3, 4], [5, 6]]), + np.array([[1, 3], [3, 4], [5, 6]])) + with assertRaisesRegexp(AssertionError, expected): + assert_almost_equal(np.array([[1, 2], [3, 4], [5, 6]]), + np.array([[1, 3], [3, 4], [5, 6]])) + + expected = """numpy array are different + +numpy array values are different \\(25\\.0 %\\) +\\[left\\]: \\[\\[1, 2\\], \\[3, 4\\]\\] +\\[right\\]: \\[\\[1, 3\\], \\[3, 4\\]\\]""" + with assertRaisesRegexp(AssertionError, expected): + assert_numpy_array_equal(np.array([[1, 2], [3, 4]]), + np.array([[1, 3], [3, 4]])) + with assertRaisesRegexp(AssertionError, expected): + assert_almost_equal(np.array([[1, 2], [3, 4]]), + np.array([[1, 3], [3, 4]])) + + # allow to overwrite message + expected = """Index are different + +Index shapes are different +\\[left\\]: \\(2,\\) +\\[right\\]: \\(3,\\)""" + with assertRaisesRegexp(AssertionError, expected): + assert_numpy_array_equal(np.array([1, 2]), np.array([3, 4, 5]), + obj='Index') + with assertRaisesRegexp(AssertionError, expected): + assert_almost_equal(np.array([1, 2]), np.array([3, 4, 5]), + obj='Index') + + def test_assert_almost_equal_iterable_message(self): + + expected = """Iterable are different + +Iterable length are different +\\[left\\]: 2 +\\[right\\]: 3""" + with assertRaisesRegexp(AssertionError, expected): + assert_almost_equal([1, 2], [3, 4, 5]) + + expected = """Iterable are different + +Iterable values are different \\(50\\.0 %\\) +\\[left\\]: \\[1, 2\\] +\\[right\\]: \\[1, 3\\]""" + with assertRaisesRegexp(AssertionError, expected): + assert_almost_equal([1, 2], [1, 3]) + + +class TestAssertIndexEqual(unittest.TestCase): + _multiprocess_can_split_ = True + + def test_index_equal_message(self): + + expected = """Index are different + +Index levels are different +\\[left\\]: 1, Int64Index\\(\\[1, 2, 3\\], dtype='int64'\\) +\\[right\\]: 2, MultiIndex\\(levels=\\[\\[u?'A', u?'B'\\], \\[1, 2, 3, 4\\]\\], + labels=\\[\\[0, 0, 1, 1\\], \\[0, 1, 2, 3\\]\\]\\)""" + idx1 = pd.Index([1, 2, 3]) + idx2 = pd.MultiIndex.from_tuples([('A', 1), ('A', 2), ('B', 3), ('B', 4)]) + with assertRaisesRegexp(AssertionError, expected): + assert_index_equal(idx1, idx2) + with assertRaisesRegexp(AssertionError, expected): + assert_index_equal(idx1, idx2, exact=False) + + + expected = """MultiIndex level \\[1\\] are different + +MultiIndex level \\[1\\] values are different \\(25\\.0 %\\) +\\[left\\]: Int64Index\\(\\[2, 2, 3, 4\\], dtype='int64'\\) +\\[right\\]: Int64Index\\(\\[1, 2, 3, 4\\], dtype='int64'\\)""" + idx1 = pd.MultiIndex.from_tuples([('A', 2), ('A', 2), ('B', 3), ('B', 4)]) + idx2 = pd.MultiIndex.from_tuples([('A', 1), ('A', 2), ('B', 3), ('B', 4)]) + with assertRaisesRegexp(AssertionError, expected): + assert_index_equal(idx1, idx2) + with assertRaisesRegexp(AssertionError, expected): + assert_index_equal(idx1, idx2, check_exact=False) + + expected = """Index are different + +Index length are different +\\[left\\]: 3, Int64Index\\(\\[1, 2, 3\\], dtype='int64'\\) +\\[right\\]: 4, Int64Index\\(\\[1, 2, 3, 4\\], dtype='int64'\\)""" + idx1 = pd.Index([1, 2, 3]) + idx2 = pd.Index([1, 2, 3, 4]) + with assertRaisesRegexp(AssertionError, expected): + assert_index_equal(idx1, idx2) + with assertRaisesRegexp(AssertionError, expected): + assert_index_equal(idx1, idx2, check_exact=False) + + expected = """Index are different + +Index classes are different +\\[left\\]: Int64Index\\(\\[1, 2, 3\\], dtype='int64'\\) +\\[right\\]: Float64Index\\(\\[1\\.0, 2\\.0, 3\\.0\\], dtype='float64'\\)""" + idx1 = pd.Index([1, 2, 3]) + idx2 = pd.Index([1, 2, 3.0]) + with assertRaisesRegexp(AssertionError, expected): + assert_index_equal(idx1, idx2, exact=True) + with assertRaisesRegexp(AssertionError, expected): + assert_index_equal(idx1, idx2, exact=True, check_exact=False) + + expected = """Index are different + +Index values are different \\(33\\.33333 %\\) +\\[left\\]: Float64Index\\(\\[1.0, 2.0, 3.0], dtype='float64'\\) +\\[right\\]: Float64Index\\(\\[1.0, 2.0, 3.0000000001\\], dtype='float64'\\)""" + idx1 = pd.Index([1, 2, 3.]) + idx2 = pd.Index([1, 2, 3.0000000001]) + with assertRaisesRegexp(AssertionError, expected): + assert_index_equal(idx1, idx2) + + # must success + assert_index_equal(idx1, idx2, check_exact=False) + + expected = """Index are different + +Index values are different \\(33\\.33333 %\\) +\\[left\\]: Float64Index\\(\\[1.0, 2.0, 3.0], dtype='float64'\\) +\\[right\\]: Float64Index\\(\\[1.0, 2.0, 3.0001\\], dtype='float64'\\)""" + idx1 = pd.Index([1, 2, 3.]) + idx2 = pd.Index([1, 2, 3.0001]) + with assertRaisesRegexp(AssertionError, expected): + assert_index_equal(idx1, idx2) + with assertRaisesRegexp(AssertionError, expected): + assert_index_equal(idx1, idx2, check_exact=False) + # must success + assert_index_equal(idx1, idx2, check_exact=False, check_less_precise=True) + + expected = """Index are different + +Index values are different \\(33\\.33333 %\\) +\\[left\\]: Int64Index\\(\\[1, 2, 3\\], dtype='int64'\\) +\\[right\\]: Int64Index\\(\\[1, 2, 4\\], dtype='int64'\\)""" + idx1 = pd.Index([1, 2, 3]) + idx2 = pd.Index([1, 2, 4]) + with assertRaisesRegexp(AssertionError, expected): + assert_index_equal(idx1, idx2) + with assertRaisesRegexp(AssertionError, expected): + assert_index_equal(idx1, idx2, check_less_precise=True) + + expected = """MultiIndex level \\[1\\] are different + +MultiIndex level \\[1\\] values are different \\(25\\.0 %\\) +\\[left\\]: Int64Index\\(\\[2, 2, 3, 4\\], dtype='int64'\\) +\\[right\\]: Int64Index\\(\\[1, 2, 3, 4\\], dtype='int64'\\)""" + idx1 = pd.MultiIndex.from_tuples([('A', 2), ('A', 2), ('B', 3), ('B', 4)]) + idx2 = pd.MultiIndex.from_tuples([('A', 1), ('A', 2), ('B', 3), ('B', 4)]) + with assertRaisesRegexp(AssertionError, expected): + assert_index_equal(idx1, idx2) + with assertRaisesRegexp(AssertionError, expected): + assert_index_equal(idx1, idx2, check_exact=False) + + def test_index_equal_metadata_message(self): + + expected = """Index are different + +Attribute "names" are different +\\[left\\]: \\[None\\] +\\[right\\]: \\[u?'x'\\]""" + idx1 = pd.Index([1, 2, 3]) + idx2 = pd.Index([1, 2, 3], name='x') + with assertRaisesRegexp(AssertionError, expected): + assert_index_equal(idx1, idx2) + + # same name, should pass + assert_index_equal(pd.Index([1, 2, 3], name=np.nan), + pd.Index([1, 2, 3], name=np.nan)) + assert_index_equal(pd.Index([1, 2, 3], name=pd.NaT), + pd.Index([1, 2, 3], name=pd.NaT)) + + + expected = """Index are different + +Attribute "names" are different +\\[left\\]: \\[nan\\] +\\[right\\]: \\[NaT\\]""" + idx1 = pd.Index([1, 2, 3], name=np.nan) + idx2 = pd.Index([1, 2, 3], name=pd.NaT) + with assertRaisesRegexp(AssertionError, expected): + assert_index_equal(idx1, idx2) + + +class TestAssertSeriesEqual(tm.TestCase): _multiprocess_can_split_ = True def _assert_equal(self, x, y, **kwargs): @@ -189,8 +465,30 @@ def test_multiindex_dtype(self): {'a':[1.0,2.0],'b':[2.1,1.5],'c':['l1','l2']}, index=['a','b']) self._assert_not_equal(df1.c, df2.c, check_index_type=True) + def test_series_equal_message(self): + + expected = """Series are different + +Series length are different +\\[left\\]: 3, Int64Index\\(\\[0, 1, 2\\], dtype='int64'\\) +\\[right\\]: 4, Int64Index\\(\\[0, 1, 2, 3\\], dtype='int64'\\)""" + with assertRaisesRegexp(AssertionError, expected): + assert_series_equal(pd.Series([1, 2, 3]), pd.Series([1, 2, 3, 4])) -class TestAssertFrameEqual(unittest.TestCase): + + expected = """Series are different + +Series values are different \\(33\\.33333 %\\) +\\[left\\]: \\[1, 2, 3\\] +\\[right\\]: \\[1, 2, 4\\]""" + with assertRaisesRegexp(AssertionError, expected): + assert_series_equal(pd.Series([1, 2, 3]), pd.Series([1, 2, 4])) + with assertRaisesRegexp(AssertionError, expected): + assert_series_equal(pd.Series([1, 2, 3]), pd.Series([1, 2, 4]), + check_less_precise=True) + + +class TestAssertFrameEqual(tm.TestCase): _multiprocess_can_split_ = True def _assert_equal(self, x, y, **kwargs): @@ -221,7 +519,66 @@ def test_empty_dtypes(self): df2=pd.DataFrame(columns=["col1","col2"]) self._assert_equal(df1, df2, check_dtype=False) self._assert_not_equal(df1, df2, check_dtype=True) - + + def test_frame_equal_message(self): + + expected = """DataFrame are different + +DataFrame shape \\(number of rows\\) are different +\\[left\\]: 3, Int64Index\\(\\[0, 1, 2\\], dtype='int64'\\) +\\[right\\]: 4, Int64Index\\(\\[0, 1, 2, 3\\], dtype='int64'\\)""" + with assertRaisesRegexp(AssertionError, expected): + assert_frame_equal(pd.DataFrame({'A':[1, 2, 3]}), + pd.DataFrame({'A':[1, 2, 3, 4]})) + + + expected = """DataFrame are different + +DataFrame shape \\(number of columns\\) are different +\\[left\\]: 2, Index\\(\\[u?'A', u?'B'\\], dtype='object'\\) +\\[right\\]: 1, Index\\(\\[u?'A'\\], dtype='object'\\)""" + with assertRaisesRegexp(AssertionError, expected): + assert_frame_equal(pd.DataFrame({'A':[1, 2, 3], 'B':[4, 5, 6]}), + pd.DataFrame({'A':[1, 2, 3]})) + + + expected = """DataFrame\\.index are different + +DataFrame\\.index values are different \\(33\\.33333 %\\) +\\[left\\]: Index\\(\\[u?'a', u?'b', u?'c'\\], dtype='object'\\) +\\[right\\]: Index\\(\\[u?'a', u?'b', u?'d'\\], dtype='object'\\)""" + with assertRaisesRegexp(AssertionError, expected): + assert_frame_equal(pd.DataFrame({'A':[1, 2, 3], 'B':[4, 5, 6]}, + index=['a', 'b', 'c']), + pd.DataFrame({'A':[1, 2, 3], 'B':[4, 5, 6]}, + index=['a', 'b', 'd'])) + + expected = """DataFrame\\.columns are different + +DataFrame\\.columns values are different \\(50\\.0 %\\) +\\[left\\]: Index\\(\\[u?'A', u?'B'\\], dtype='object'\\) +\\[right\\]: Index\\(\\[u?'A', u?'b'\\], dtype='object'\\)""" + with assertRaisesRegexp(AssertionError, expected): + assert_frame_equal(pd.DataFrame({'A':[1, 2, 3], 'B':[4, 5, 6]}, + index=['a', 'b', 'c']), + pd.DataFrame({'A':[1, 2, 3], 'b':[4, 5, 6]}, + index=['a', 'b', 'c'])) + + + expected = """DataFrame\\.iloc\\[:, 1\\] are different + +DataFrame\\.iloc\\[:, 1\\] values are different \\(33\\.33333 %\\) +\\[left\\]: \\[4, 5, 6\\] +\\[right\\]: \\[4, 5, 7\\]""" + with assertRaisesRegexp(AssertionError, expected): + assert_frame_equal(pd.DataFrame({'A':[1, 2, 3], 'B':[4, 5, 6]}), + pd.DataFrame({'A':[1, 2, 3], 'B':[4, 5, 7]})) + + with assertRaisesRegexp(AssertionError, expected): + assert_frame_equal(pd.DataFrame({'A':[1, 2, 3], 'B':[4, 5, 6]}), + pd.DataFrame({'A':[1, 2, 3], 'B':[4, 5, 7]}), + by_blocks=True) + class TestRNGContext(unittest.TestCase): @@ -233,3 +590,43 @@ def test_RNGContext(self): with RNGContext(1): self.assertEqual(np.random.randn(), expected1) self.assertEqual(np.random.randn(), expected0) + + + +class TestDeprecatedTests(tm.TestCase): + + def test_warning(self): + + with tm.assert_produces_warning(FutureWarning): + self.assertEquals(1, 1) + + with tm.assert_produces_warning(FutureWarning): + self.assertNotEquals(1, 2) + + with tm.assert_produces_warning(FutureWarning): + self.assert_(True) + + with tm.assert_produces_warning(FutureWarning): + self.assertAlmostEquals(1.0, 1.0000000001) + + with tm.assert_produces_warning(FutureWarning): + self.assertNotAlmostEquals(1, 2) + + with tm.assert_produces_warning(FutureWarning): + tm.assert_isinstance(Series([1, 2]), Series, msg='xxx') + + +class TestLocale(tm.TestCase): + + def test_locale(self): + if sys.platform == 'win32': + raise nose.SkipTest("skipping on win platforms as locale not available") + + #GH9744 + locales = tm.get_locales() + self.assertTrue(len(locales) >= 1) + + +if __name__ == '__main__': + nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'], + exit=False) diff --git a/pandas/tests/test_tseries.py b/pandas/tests/test_tseries.py index 035b3ac07342d..6dd43539eeabf 100644 --- a/pandas/tests/test_tseries.py +++ b/pandas/tests/test_tseries.py @@ -9,7 +9,8 @@ import pandas.lib as lib import pandas._period as period import pandas.algos as algos -from pandas.tseries.holiday import Holiday, SA, next_monday +from pandas.tseries.holiday import Holiday, SA, next_monday,USMartinLutherKingJr,USMemorialDay,AbstractHolidayCalendar +import datetime from pandas import DateOffset @@ -275,10 +276,18 @@ def test_duplicated_with_nas(): expected = [False, False, False, True, False, True] assert(np.array_equal(result, expected)) - result = lib.duplicated(keys, take_last=True) + result = lib.duplicated(keys, keep='first') + expected = [False, False, False, True, False, True] + assert(np.array_equal(result, expected)) + + result = lib.duplicated(keys, keep='last') expected = [True, False, True, False, False, False] assert(np.array_equal(result, expected)) + result = lib.duplicated(keys, keep=False) + expected = [True, False, True, True, False, True] + assert(np.array_equal(result, expected)) + keys = np.empty(8, dtype=object) for i, t in enumerate(zip([0, 0, nan, nan] * 2, [0, nan, 0, nan] * 2)): keys[i] = t @@ -289,10 +298,14 @@ def test_duplicated_with_nas(): expected = falses + trues assert(np.array_equal(result, expected)) - result = lib.duplicated(keys, take_last=True) + result = lib.duplicated(keys, keep='last') expected = trues + falses assert(np.array_equal(result, expected)) + result = lib.duplicated(keys, keep=False) + expected = trues + trues + assert(np.array_equal(result, expected)) + def test_maybe_booleans_to_slice(): arr = np.array([0, 0, 1, 1, 1, 0, 1], dtype=np.uint8) @@ -363,9 +376,9 @@ def test_get_reverse_indexer(): def test_pad_backfill_object_segfault(): - from datetime import datetime + old = np.array([], dtype='O') - new = np.array([datetime(2010, 12, 31)], dtype='O') + new = np.array([datetime.datetime(2010, 12, 31)], dtype='O') result = algos.pad_object(old, new) expected = np.array([-1], dtype=np.int64) @@ -629,13 +642,13 @@ def test_unicode(self): pass def test_datetime(self): - import datetime + dates = [datetime.datetime(2012, 1, x) for x in range(1, 20)] index = Index(dates) self.assertEqual(index.inferred_type, 'datetime64') def test_date(self): - import datetime + dates = [datetime.date(2012, 1, x) for x in range(1, 20)] index = Index(dates) self.assertEqual(index.inferred_type, 'date') @@ -739,6 +752,29 @@ def test_get_period_field_raises_on_out_of_range(self): def test_get_period_field_array_raises_on_out_of_range(self): self.assertRaises(ValueError, period.get_period_field_arr, -1, np.empty(1), 0) +class TestFederalHolidayCalendar(tm.TestCase): + + # Test for issue 10278 + def test_no_mlk_before_1984(self): + class MLKCalendar(AbstractHolidayCalendar): + rules=[USMartinLutherKingJr] + holidays = MLKCalendar().holidays(start='1984', end='1988').to_pydatetime().tolist() + # Testing to make sure holiday is not incorrectly observed before 1986 + self.assertEqual(holidays, [datetime.datetime(1986, 1, 20, 0, 0), datetime.datetime(1987, 1, 19, 0, 0)]) + + def test_memorial_day(self): + class MemorialDay(AbstractHolidayCalendar): + rules=[USMemorialDay] + holidays = MemorialDay().holidays(start='1971', end='1980').to_pydatetime().tolist() + # Fixes 5/31 error and checked manually against wikipedia + self.assertEqual(holidays, [datetime.datetime(1971, 5, 31, 0, 0), datetime.datetime(1972, 5, 29, 0, 0), + datetime.datetime(1973, 5, 28, 0, 0), datetime.datetime(1974, 5, 27, 0, 0), + datetime.datetime(1975, 5, 26, 0, 0), datetime.datetime(1976, 5, 31, 0, 0), + datetime.datetime(1977, 5, 30, 0, 0), datetime.datetime(1978, 5, 29, 0, 0), + datetime.datetime(1979, 5, 28, 0, 0)]) + + + class TestHolidayConflictingArguments(tm.TestCase): diff --git a/pandas/tests/test_util.py b/pandas/tests/test_util.py index 38f058358b37f..fb334cf9912f3 100644 --- a/pandas/tests/test_util.py +++ b/pandas/tests/test_util.py @@ -61,33 +61,6 @@ def f4(new=None): pass -class TestTesting(tm.TestCase): - - def test_warning(self): - - with tm.assert_produces_warning(FutureWarning): - self.assertEquals(1, 1) - - with tm.assert_produces_warning(FutureWarning): - self.assertNotEquals(1, 2) - - with tm.assert_produces_warning(FutureWarning): - self.assert_(True) - - with tm.assert_produces_warning(FutureWarning): - self.assertAlmostEquals(1.0, 1.0000000001) - - with tm.assert_produces_warning(FutureWarning): - self.assertNotAlmostEquals(1, 2) - - def test_locale(self): - if sys.platform == 'win32': - raise nose.SkipTest("skipping on win platforms as locale not available") - - #GH9744 - locales = pandas.util.testing.get_locales() - self.assertTrue(len(locales) >= 1) - def test_rands(): r = tm.rands(10) assert(len(r) == 10) diff --git a/pandas/tools/merge.py b/pandas/tools/merge.py index c7c578232cd0f..a8b0d37b55bfe 100644 --- a/pandas/tools/merge.py +++ b/pandas/tools/merge.py @@ -1,7 +1,6 @@ """ SQL-style merge routines """ -import types import numpy as np from pandas.compat import range, long, lrange, lzip, zip, map, filter @@ -17,11 +16,9 @@ concatenate_block_managers) from pandas.util.decorators import Appender, Substitution from pandas.core.common import ABCSeries -from pandas.io.parsers import TextFileReader import pandas.core.common as com -import pandas.lib as lib import pandas.algos as algos import pandas.hashtable as _hash @@ -220,6 +217,9 @@ def _maybe_add_join_keys(self, result, left_indexer, right_indexer): if left_indexer is not None and right_indexer is not None: if name in self.left: + if len(self.left) == 0: + continue + na_indexer = (left_indexer == -1).nonzero()[0] if len(na_indexer) == 0: continue @@ -229,6 +229,9 @@ def _maybe_add_join_keys(self, result, left_indexer, right_indexer): na_indexer, com.take_1d(self.right_join_keys[i], right_na_indexer)) elif name in self.right: + if len(self.right) == 0: + continue + na_indexer = (right_indexer == -1).nonzero()[0] if len(na_indexer) == 0: continue @@ -273,9 +276,17 @@ def _get_join_info(self): sort=self.sort, how=self.how) if self.right_index: - join_index = self.left.index.take(left_indexer) + if len(self.left) > 0: + join_index = self.left.index.take(left_indexer) + else: + join_index = self.right.index.take(right_indexer) + left_indexer = np.array([-1] * len(join_index)) elif self.left_index: - join_index = self.right.index.take(right_indexer) + if len(self.right) > 0: + join_index = self.right.index.take(right_indexer) + else: + join_index = self.left.index.take(left_indexer) + right_indexer = np.array([-1] * len(join_index)) else: join_index = Index(np.arange(len(left_indexer))) @@ -402,19 +413,14 @@ def _validate_specification(self): if self.left_on is None: raise MergeError('Must pass left_on or left_index=True') else: - if not self.left.columns.is_unique: - raise MergeError("Left data columns not unique: %s" - % repr(self.left.columns)) - - if not self.right.columns.is_unique: - raise MergeError("Right data columns not unique: %s" - % repr(self.right.columns)) - # use the common columns common_cols = self.left.columns.intersection( self.right.columns) if len(common_cols) == 0: raise MergeError('No common columns to perform merge on') + if not common_cols.is_unique: + raise MergeError("Data columns not unique: %s" + % repr(common_cols)) self.left_on = self.right_on = common_cols elif self.on is not None: if self.left_on is not None or self.right_on is not None: @@ -780,9 +786,14 @@ def __init__(self, objs, axis=0, join='outer', join_axes=None, if keys is None: keys = sorted(objs) objs = [objs[k] for k in keys] + else: + objs = list(objs) + + if len(objs) == 0: + raise ValueError('No objects to concatenate') if keys is None: - objs = [obj for obj in objs if obj is not None ] + objs = [obj for obj in objs if obj is not None] else: # #1649 clean_keys = [] diff --git a/pandas/tools/plotting.py b/pandas/tools/plotting.py index 35893b9de8e75..c16e2686c5a3a 100644 --- a/pandas/tools/plotting.py +++ b/pandas/tools/plotting.py @@ -134,6 +134,32 @@ def random_color(column): else: raise ValueError("color_type must be either 'default' or 'random'") + if isinstance(colors, compat.string_types): + import matplotlib.colors + conv = matplotlib.colors.ColorConverter() + def _maybe_valid_colors(colors): + try: + [conv.to_rgba(c) for c in colors] + return True + except ValueError: + return False + + # check whether the string can be convertable to single color + maybe_single_color = _maybe_valid_colors([colors]) + # check whether each character can be convertable to colors + maybe_color_cycle = _maybe_valid_colors(list(colors)) + if maybe_single_color and maybe_color_cycle and len(colors) > 1: + msg = ("'{0}' can be parsed as both single color and " + "color cycle. Specify each color using a list " + "like ['{0}'] or {1}") + raise ValueError(msg.format(colors, list(colors))) + elif maybe_single_color: + colors = [colors] + else: + # ``colors`` is regarded as color cycle. + # mpl will raise error any of them is invalid + pass + if len(colors) != num_colors: multiple = num_colors//len(colors) - 1 mod = num_colors % len(colors) @@ -748,6 +774,7 @@ class MPLPlot(object): data : """ + _kind = 'base' _layout_type = 'vertical' _default_rot = 0 orientation = None @@ -804,10 +831,7 @@ def __init__(self, data, kind=None, by=None, subplots=False, sharex=None, self._rot_set = True else: self._rot_set = False - if isinstance(self._default_rot, dict): - self.rot = self._default_rot[self.kind] - else: - self.rot = self._default_rot + self.rot = self._default_rot if grid is None: grid = False if secondary_y else self.plt.rcParams['axes.grid'] @@ -1004,7 +1028,7 @@ def _compute_plot_data(self): label = 'None' data = data.to_frame(name=label) - numeric_data = data.convert_objects()._get_numeric_data() + numeric_data = data.convert_objects(datetime=True)._get_numeric_data() try: is_empty = numeric_data.empty @@ -1191,34 +1215,25 @@ def _get_xticks(self, convert_period=False): return x - def _is_datetype(self): - index = self.data.index - return (isinstance(index, (PeriodIndex, DatetimeIndex)) or - index.inferred_type in ('datetime', 'date', 'datetime64', - 'time')) + @classmethod + def _plot(cls, ax, x, y, style=None, is_errorbar=False, **kwds): + mask = com.isnull(y) + if mask.any(): + y = np.ma.array(y) + y = np.ma.masked_where(mask, y) - def _get_plot_function(self): - ''' - Returns the matplotlib plotting function (plot or errorbar) based on - the presence of errorbar keywords. - ''' - errorbar = any(e is not None for e in self.errors.values()) - def plotf(ax, x, y, style=None, **kwds): - mask = com.isnull(y) - if mask.any(): - y = np.ma.array(y) - y = np.ma.masked_where(mask, y) - - if errorbar: - return self.plt.Axes.errorbar(ax, x, y, **kwds) + if isinstance(x, Index): + x = x._mpl_repr() + + if is_errorbar: + return ax.errorbar(x, y, **kwds) + else: + # prevent style kwarg from going to errorbar, where it is unsupported + if style is not None: + args = (x, y, style) else: - # prevent style kwarg from going to errorbar, where it is unsupported - if style is not None: - args = (ax, x, y, style) - else: - args = (ax, x, y) - return self.plt.Axes.plot(*args, **kwds) - return plotf + args = (x, y) + return ax.plot(*args, **kwds) def _get_index_name(self): if isinstance(self.data.index, MultiIndex): @@ -1262,23 +1277,28 @@ def on_right(self, i): if isinstance(self.secondary_y, (tuple, list, np.ndarray, Index)): return self.data.columns[i] in self.secondary_y - def _get_style(self, i, col_name): - style = '' - if self.subplots: - style = 'k' - + def _apply_style_colors(self, colors, kwds, col_num, label): + """ + Manage style and color based on column number and its label. + Returns tuple of appropriate style and kwds which "color" may be added. + """ + style = None if self.style is not None: if isinstance(self.style, list): try: - style = self.style[i] + style = self.style[col_num] except IndexError: pass elif isinstance(self.style, dict): - style = self.style.get(col_name, style) + style = self.style.get(label, style) else: style = self.style - return style or None + has_color = 'color' in kwds or self.colormap is not None + nocolor_style = style is None or re.match('[a-z]+', style) is None + if (has_color or self.subplots) and nocolor_style: + kwds['color'] = colors[col_num % len(colors)] + return style, kwds def _get_colors(self, num_colors=None, color_kwds='color'): if num_colors is None: @@ -1288,11 +1308,6 @@ def _get_colors(self, num_colors=None, color_kwds='color'): colormap=self.colormap, color=self.kwds.get(color_kwds)) - def _maybe_add_color(self, colors, kwds, style, i): - has_color = 'color' in kwds or self.colormap is not None - if has_color and (style is None or re.match('[a-z]+', style) is None): - kwds['color'] = colors[i % len(colors)] - def _parse_errorbars(self, label, err): ''' Look for error keyword arguments and return the actual errorbar data @@ -1405,6 +1420,7 @@ def _get_axes_layout(self): return (len(y_set), len(x_set)) class ScatterPlot(MPLPlot): + _kind = 'scatter' _layout_type = 'single' def __init__(self, data, x, y, c=None, **kwargs): @@ -1483,6 +1499,7 @@ def _post_plot_logic(self): class HexBinPlot(MPLPlot): + _kind = 'hexbin' _layout_type = 'single' def __init__(self, data, x, y, C=None, **kwargs): @@ -1538,7 +1555,7 @@ def _post_plot_logic(self): class LinePlot(MPLPlot): - + _kind = 'line' _default_rot = 0 orientation = 'vertical' @@ -1550,71 +1567,35 @@ def __init__(self, data, **kwargs): if 'x_compat' in self.kwds: self.x_compat = bool(self.kwds.pop('x_compat')) - def _index_freq(self): - freq = getattr(self.data.index, 'freq', None) - if freq is None: - freq = getattr(self.data.index, 'inferred_freq', None) - if freq == 'B': - weekdays = np.unique(self.data.index.dayofweek) - if (5 in weekdays) or (6 in weekdays): - freq = None - return freq - - def _is_dynamic_freq(self, freq): - if isinstance(freq, DateOffset): - freq = freq.rule_code - else: - freq = frequencies.get_base_alias(freq) - freq = frequencies.get_period_alias(freq) - return freq is not None and self._no_base(freq) - - def _no_base(self, freq): - # hack this for 0.10.1, creating more technical debt...sigh - if isinstance(self.data.index, DatetimeIndex): - base = frequencies.get_freq(freq) - x = self.data.index - if (base <= frequencies.FreqGroup.FR_DAY): - return x[:1].is_normalized - - return Period(x[0], freq).to_timestamp(tz=x.tz) == x[0] - return True - - def _use_dynamic_x(self): - freq = self._index_freq() - - ax = self._get_ax(0) - ax_freq = getattr(ax, 'freq', None) - if freq is None: # convert irregular if axes has freq info - freq = ax_freq - else: # do not use tsplot if irregular was plotted first - if (ax_freq is None) and (len(ax.get_lines()) > 0): - return False - - return (freq is not None) and self._is_dynamic_freq(freq) - def _is_ts_plot(self): # this is slightly deceptive return not self.x_compat and self.use_index and self._use_dynamic_x() - def _make_plot(self): - self._initialize_prior(len(self.data)) + def _use_dynamic_x(self): + from pandas.tseries.plotting import _use_dynamic_x + return _use_dynamic_x(self._get_ax(0), self.data) + def _make_plot(self): if self._is_ts_plot(): - data = self._maybe_convert_index(self.data) + from pandas.tseries.plotting import _maybe_convert_index + data = _maybe_convert_index(self._get_ax(0), self.data) + x = data.index # dummy, not used - plotf = self._get_ts_plot_function() + plotf = self._ts_plot it = self._iter_data(data=data, keep_index=True) else: x = self._get_xticks(convert_period=True) - plotf = self._get_plot_function() + plotf = self._plot it = self._iter_data() + stacking_id = self._get_stacking_id() + is_errorbar = any(e is not None for e in self.errors.values()) + colors = self._get_colors() for i, (label, y) in enumerate(it): ax = self._get_ax(i) - style = self._get_style(i, label) kwds = self.kwds.copy() - self._maybe_add_color(colors, kwds, style, i) + style, kwds = self._apply_style_colors(colors, kwds, i, label) errors = self._get_errorbars(label=label, index=i) kwds = dict(kwds, **errors) @@ -1622,84 +1603,87 @@ def _make_plot(self): label = com.pprint_thing(label) # .encode('utf-8') kwds['label'] = label - newlines = plotf(ax, x, y, style=style, column_num=i, **kwds) + newlines = plotf(ax, x, y, style=style, column_num=i, + stacking_id=stacking_id, + is_errorbar=is_errorbar, + **kwds) self._add_legend_handle(newlines[0], label, index=i) lines = _get_all_lines(ax) left, right = _get_xlim(lines) ax.set_xlim(left, right) - def _get_stacked_values(self, y, label): + @classmethod + def _plot(cls, ax, x, y, style=None, column_num=None, + stacking_id=None, **kwds): + # column_num is used to get the target column from protf in line and area plots + if column_num == 0: + cls._initialize_stacker(ax, stacking_id, len(y)) + y_values = cls._get_stacked_values(ax, stacking_id, y, kwds['label']) + lines = MPLPlot._plot(ax, x, y_values, style=style, **kwds) + cls._update_stacker(ax, stacking_id, y) + return lines + + @classmethod + def _ts_plot(cls, ax, x, data, style=None, **kwds): + from pandas.tseries.plotting import (_maybe_resample, + _decorate_axes, + format_dateaxis) + # accept x to be consistent with normal plot func, + # x is not passed to tsplot as it uses data.index as x coordinate + # column_num must be in kwds for stacking purpose + freq, data = _maybe_resample(data, ax, kwds) + + # Set ax with freq info + _decorate_axes(ax, freq, kwds) + ax._plot_data.append((data, cls._kind, kwds)) + + lines = cls._plot(ax, data.index, data.values, style=style, **kwds) + # set date formatter, locators and rescale limits + format_dateaxis(ax, ax.freq) + return lines + + def _get_stacking_id(self): if self.stacked: - if (y >= 0).all(): - return self._pos_prior + y - elif (y <= 0).all(): - return self._neg_prior + y - else: - raise ValueError('When stacked is True, each column must be either all positive or negative.' - '{0} contains both positive and negative values'.format(label)) + return id(self.data) else: - return y - - def _get_plot_function(self): - f = MPLPlot._get_plot_function(self) - def plotf(ax, x, y, style=None, column_num=None, **kwds): - # column_num is used to get the target column from protf in line and area plots - if column_num == 0: - self._initialize_prior(len(self.data)) - y_values = self._get_stacked_values(y, kwds['label']) - lines = f(ax, x, y_values, style=style, **kwds) - self._update_prior(y) - return lines - return plotf - - def _get_ts_plot_function(self): - from pandas.tseries.plotting import tsplot - plotf = self._get_plot_function() - def _plot(ax, x, data, style=None, **kwds): - # accept x to be consistent with normal plot func, - # x is not passed to tsplot as it uses data.index as x coordinate - lines = tsplot(data, plotf, ax=ax, style=style, **kwds) - return lines - return _plot - - def _initialize_prior(self, n): - self._pos_prior = np.zeros(n) - self._neg_prior = np.zeros(n) - - def _update_prior(self, y): - if self.stacked and not self.subplots: - # tsplot resample may changedata length - if len(self._pos_prior) != len(y): - self._initialize_prior(len(y)) - if (y >= 0).all(): - self._pos_prior += y - elif (y <= 0).all(): - self._neg_prior += y - - def _maybe_convert_index(self, data): - # tsplot converts automatically, but don't want to convert index - # over and over for DataFrames - if isinstance(data.index, DatetimeIndex): - freq = getattr(data.index, 'freq', None) - - if freq is None: - freq = getattr(data.index, 'inferred_freq', None) - if isinstance(freq, DateOffset): - freq = freq.rule_code - - if freq is None: - ax = self._get_ax(0) - freq = getattr(ax, 'freq', None) - - if freq is None: - raise ValueError('Could not get frequency alias for plotting') - - freq = frequencies.get_base_alias(freq) - freq = frequencies.get_period_alias(freq) - - data.index = data.index.to_period(freq=freq) - return data + return None + + @classmethod + def _initialize_stacker(cls, ax, stacking_id, n): + if stacking_id is None: + return + if not hasattr(ax, '_stacker_pos_prior'): + ax._stacker_pos_prior = {} + if not hasattr(ax, '_stacker_neg_prior'): + ax._stacker_neg_prior = {} + ax._stacker_pos_prior[stacking_id] = np.zeros(n) + ax._stacker_neg_prior[stacking_id] = np.zeros(n) + + @classmethod + def _get_stacked_values(cls, ax, stacking_id, values, label): + if stacking_id is None: + return values + if not hasattr(ax, '_stacker_pos_prior'): + # stacker may not be initialized for subplots + cls._initialize_stacker(ax, stacking_id, len(values)) + + if (values >= 0).all(): + return ax._stacker_pos_prior[stacking_id] + values + elif (values <= 0).all(): + return ax._stacker_neg_prior[stacking_id] + values + + raise ValueError('When stacked is True, each column must be either all positive or negative.' + '{0} contains both positive and negative values'.format(label)) + + @classmethod + def _update_stacker(cls, ax, stacking_id, values): + if stacking_id is None: + return + if (values >= 0).all(): + ax._stacker_pos_prior[stacking_id] += values + elif (values <= 0).all(): + ax._stacker_neg_prior[stacking_id] += values def _post_plot_logic(self): df = self.data @@ -1724,6 +1708,7 @@ def _post_plot_logic(self): class AreaPlot(LinePlot): + _kind = 'area' def __init__(self, data, **kwargs): kwargs.setdefault('stacked', True) @@ -1734,35 +1719,36 @@ def __init__(self, data, **kwargs): # use smaller alpha to distinguish overlap self.kwds.setdefault('alpha', 0.5) - def _get_plot_function(self): if self.logy or self.loglog: raise ValueError("Log-y scales are not supported in area plot") - else: - f = MPLPlot._get_plot_function(self) - def plotf(ax, x, y, style=None, column_num=None, **kwds): - if column_num == 0: - self._initialize_prior(len(self.data)) - y_values = self._get_stacked_values(y, kwds['label']) - lines = f(ax, x, y_values, style=style, **kwds) - - # get data from the line to get coordinates for fill_between - xdata, y_values = lines[0].get_data(orig=False) - - if (y >= 0).all(): - start = self._pos_prior - elif (y <= 0).all(): - start = self._neg_prior - else: - start = np.zeros(len(y)) - if not 'color' in kwds: - kwds['color'] = lines[0].get_color() + @classmethod + def _plot(cls, ax, x, y, style=None, column_num=None, + stacking_id=None, is_errorbar=False, **kwds): + if column_num == 0: + cls._initialize_stacker(ax, stacking_id, len(y)) + y_values = cls._get_stacked_values(ax, stacking_id, y, kwds['label']) + lines = MPLPlot._plot(ax, x, y_values, style=style, **kwds) + + # get data from the line to get coordinates for fill_between + xdata, y_values = lines[0].get_data(orig=False) + + # unable to use ``_get_stacked_values`` here to get starting point + if stacking_id is None: + start = np.zeros(len(y)) + elif (y >= 0).all(): + start = ax._stacker_pos_prior[stacking_id] + elif (y <= 0).all(): + start = ax._stacker_neg_prior[stacking_id] + else: + start = np.zeros(len(y)) - self.plt.Axes.fill_between(ax, xdata, start, y_values, **kwds) - self._update_prior(y) - return lines + if not 'color' in kwds: + kwds['color'] = lines[0].get_color() - return plotf + ax.fill_between(xdata, start, y_values, **kwds) + cls._update_stacker(ax, stacking_id, y) + return lines def _add_legend_handle(self, handle, label, index=None): from matplotlib.patches import Rectangle @@ -1785,8 +1771,9 @@ def _post_plot_logic(self): class BarPlot(MPLPlot): - - _default_rot = {'bar': 90, 'barh': 0} + _kind = 'bar' + _default_rot = 90 + orientation = 'vertical' def __init__(self, data, **kwargs): self.bar_width = kwargs.pop('width', 0.5) @@ -1823,20 +1810,13 @@ def _args_adjust(self): if com.is_list_like(self.left): self.left = np.array(self.left) - def _get_plot_function(self): - if self.kind == 'bar': - def f(ax, x, y, w, start=None, **kwds): - start = start + self.bottom - return ax.bar(x, y, w, bottom=start, log=self.log, **kwds) - elif self.kind == 'barh': - - def f(ax, x, y, w, start=None, log=self.log, **kwds): - start = start + self.left - return ax.barh(x, y, w, left=start, log=self.log, **kwds) - else: - raise ValueError("BarPlot kind must be either 'bar' or 'barh'") + @classmethod + def _plot(cls, ax, x, y, w, start=0, log=False, **kwds): + return ax.bar(x, y, w, bottom=start, log=log, **kwds) - return f + @property + def _start_base(self): + return self.bottom def _make_plot(self): import matplotlib as mpl @@ -1844,7 +1824,6 @@ def _make_plot(self): colors = self._get_colors() ncolors = len(colors) - bar_f = self._get_plot_function() pos_prior = neg_prior = np.zeros(len(self.data)) K = self.nseries @@ -1865,24 +1844,25 @@ def _make_plot(self): start = 0 if self.log and (y >= 1).all(): start = 1 + start = start + self._start_base if self.subplots: w = self.bar_width / 2 - rect = bar_f(ax, self.ax_pos + w, y, self.bar_width, - start=start, label=label, **kwds) + rect = self._plot(ax, self.ax_pos + w, y, self.bar_width, + start=start, label=label, log=self.log, **kwds) ax.set_title(label) elif self.stacked: mask = y > 0 - start = np.where(mask, pos_prior, neg_prior) + start = np.where(mask, pos_prior, neg_prior) + self._start_base w = self.bar_width / 2 - rect = bar_f(ax, self.ax_pos + w, y, self.bar_width, - start=start, label=label, **kwds) + rect = self._plot(ax, self.ax_pos + w, y, self.bar_width, + start=start, label=label, log=self.log, **kwds) pos_prior = pos_prior + np.where(mask, y, 0) neg_prior = neg_prior + np.where(mask, 0, y) else: w = self.bar_width / K - rect = bar_f(ax, self.ax_pos + (i + 0.5) * w, y, w, - start=start, label=label, **kwds) + rect = self._plot(ax, self.ax_pos + (i + 0.5) * w, y, w, + start=start, label=label, log=self.log, **kwds) self._add_legend_handle(rect, label, index=i) def _post_plot_logic(self): @@ -1897,33 +1877,40 @@ def _post_plot_logic(self): s_edge = self.ax_pos[0] - 0.25 + self.lim_offset e_edge = self.ax_pos[-1] + 0.25 + self.bar_width + self.lim_offset - if self.kind == 'bar': - ax.set_xlim((s_edge, e_edge)) - ax.set_xticks(self.tick_pos) - ax.set_xticklabels(str_index) - if name is not None and self.use_index: - ax.set_xlabel(name) - elif self.kind == 'barh': - # horizontal bars - ax.set_ylim((s_edge, e_edge)) - ax.set_yticks(self.tick_pos) - ax.set_yticklabels(str_index) - if name is not None and self.use_index: - ax.set_ylabel(name) - else: - raise NotImplementedError(self.kind) + self._decorate_ticks(ax, name, str_index, s_edge, e_edge) + + def _decorate_ticks(self, ax, name, ticklabels, start_edge, end_edge): + ax.set_xlim((start_edge, end_edge)) + ax.set_xticks(self.tick_pos) + ax.set_xticklabels(ticklabels) + if name is not None and self.use_index: + ax.set_xlabel(name) + + +class BarhPlot(BarPlot): + _kind = 'barh' + _default_rot = 0 + orientation = 'horizontal' @property - def orientation(self): - if self.kind == 'bar': - return 'vertical' - elif self.kind == 'barh': - return 'horizontal' - else: - raise NotImplementedError(self.kind) + def _start_base(self): + return self.left + + @classmethod + def _plot(cls, ax, x, y, w, start=0, log=False, **kwds): + return ax.barh(x, y, w, left=start, log=log, **kwds) + + def _decorate_ticks(self, ax, name, ticklabels, start_edge, end_edge): + # horizontal bars + ax.set_ylim((start_edge, end_edge)) + ax.set_yticks(self.tick_pos) + ax.set_yticklabels(ticklabels) + if name is not None and self.use_index: + ax.set_ylabel(name) class HistPlot(LinePlot): + _kind = 'hist' def __init__(self, data, bins=10, bottom=0, **kwargs): self.bins = bins # use mpl default @@ -1934,7 +1921,8 @@ def __init__(self, data, bins=10, bottom=0, **kwargs): def _args_adjust(self): if com.is_integer(self.bins): # create common bin edge - values = self.data.convert_objects()._get_numeric_data() + values = (self.data.convert_objects(datetime=True) + ._get_numeric_data()) values = np.ravel(values) values = values[~com.isnull(values)] @@ -1945,44 +1933,55 @@ def _args_adjust(self): if com.is_list_like(self.bottom): self.bottom = np.array(self.bottom) - def _get_plot_function(self): - def plotf(ax, y, style=None, column_num=None, **kwds): - if column_num == 0: - self._initialize_prior(len(self.bins) - 1) - y = y[~com.isnull(y)] - bottom = self._pos_prior + self.bottom - # ignore style - n, bins, patches = self.plt.Axes.hist(ax, y, bins=self.bins, - bottom=bottom, **kwds) - self._update_prior(n) - return patches - return plotf + @classmethod + def _plot(cls, ax, y, style=None, bins=None, bottom=0, column_num=0, + stacking_id=None, **kwds): + if column_num == 0: + cls._initialize_stacker(ax, stacking_id, len(bins) - 1) + y = y[~com.isnull(y)] + + base = np.zeros(len(bins) - 1) + bottom = bottom + cls._get_stacked_values(ax, stacking_id, base, kwds['label']) + # ignore style + n, bins, patches = ax.hist(y, bins=bins, bottom=bottom, **kwds) + cls._update_stacker(ax, stacking_id, n) + return patches def _make_plot(self): - plotf = self._get_plot_function() colors = self._get_colors() + stacking_id = self._get_stacking_id() + for i, (label, y) in enumerate(self._iter_data()): ax = self._get_ax(i) - style = self._get_style(i, label) - label = com.pprint_thing(label) kwds = self.kwds.copy() + + label = com.pprint_thing(label) kwds['label'] = label - self._maybe_add_color(colors, kwds, style, i) + style, kwds = self._apply_style_colors(colors, kwds, i, label) if style is not None: kwds['style'] = style - artists = plotf(ax, y, column_num=i, **kwds) + kwds = self._make_plot_keywords(kwds, y) + artists = self._plot(ax, y, column_num=i, + stacking_id=stacking_id, **kwds) self._add_legend_handle(artists[0], label, index=i) + def _make_plot_keywords(self, kwds, y): + """merge BoxPlot/KdePlot properties to passed kwds""" + # y is required for KdePlot + kwds['bottom'] = self.bottom + kwds['bins'] = self.bins + return kwds + def _post_plot_logic(self): if self.orientation == 'horizontal': for ax in self.axes: - ax.set_xlabel('Degree') + ax.set_xlabel('Frequency') else: for ax in self.axes: - ax.set_ylabel('Degree') + ax.set_ylabel('Frequency') @property def orientation(self): @@ -1993,6 +1992,7 @@ def orientation(self): class KdePlot(HistPlot): + _kind = 'kde' orientation = 'vertical' def __init__(self, data, bw_method=None, ind=None, **kwargs): @@ -2012,26 +2012,31 @@ def _get_ind(self, y): ind = self.ind return ind - def _get_plot_function(self): + @classmethod + def _plot(cls, ax, y, style=None, bw_method=None, ind=None, + column_num=None, stacking_id=None, **kwds): from scipy.stats import gaussian_kde from scipy import __version__ as spv - f = MPLPlot._get_plot_function(self) - def plotf(ax, y, style=None, column_num=None, **kwds): - y = remove_na(y) - if LooseVersion(spv) >= '0.11.0': - gkde = gaussian_kde(y, bw_method=self.bw_method) - else: - gkde = gaussian_kde(y) - if self.bw_method is not None: - msg = ('bw_method was added in Scipy 0.11.0.' + - ' Scipy version in use is %s.' % spv) - warnings.warn(msg) - - ind = self._get_ind(y) - y = gkde.evaluate(ind) - lines = f(ax, ind, y, style=style, **kwds) - return lines - return plotf + + y = remove_na(y) + + if LooseVersion(spv) >= '0.11.0': + gkde = gaussian_kde(y, bw_method=bw_method) + else: + gkde = gaussian_kde(y) + if bw_method is not None: + msg = ('bw_method was added in Scipy 0.11.0.' + + ' Scipy version in use is %s.' % spv) + warnings.warn(msg) + + y = gkde.evaluate(ind) + lines = MPLPlot._plot(ax, ind, y, style=style, **kwds) + return lines + + def _make_plot_keywords(self, kwds, y): + kwds['bw_method'] = self.bw_method + kwds['ind'] = self._get_ind(y) + return kwds def _post_plot_logic(self): for ax in self.axes: @@ -2039,6 +2044,7 @@ def _post_plot_logic(self): class PiePlot(MPLPlot): + _kind = 'pie' _layout_type = 'horizontal' def __init__(self, data, kind=None, **kwargs): @@ -2057,8 +2063,8 @@ def _validate_color_args(self): pass def _make_plot(self): - self.kwds.setdefault('colors', self._get_colors(num_colors=len(self.data), - color_kwds='colors')) + colors = self._get_colors(num_colors=len(self.data), color_kwds='colors') + self.kwds.setdefault('colors', colors) for i, (label, y) in enumerate(self._iter_data()): ax = self._get_ax(i) @@ -2103,6 +2109,7 @@ def blank_labeler(label, value): class BoxPlot(LinePlot): + _kind = 'box' _layout_type = 'horizontal' _valid_return_types = (None, 'axes', 'dict', 'both') @@ -2125,25 +2132,24 @@ def _args_adjust(self): else: self.sharey = False - def _get_plot_function(self): - def plotf(ax, y, column_num=None, **kwds): - if y.ndim == 2: - y = [remove_na(v) for v in y] - # Boxplot fails with empty arrays, so need to add a NaN - # if any cols are empty - # GH 8181 - y = [v if v.size > 0 else np.array([np.nan]) for v in y] - else: - y = remove_na(y) - bp = ax.boxplot(y, **kwds) + @classmethod + def _plot(cls, ax, y, column_num=None, return_type=None, **kwds): + if y.ndim == 2: + y = [remove_na(v) for v in y] + # Boxplot fails with empty arrays, so need to add a NaN + # if any cols are empty + # GH 8181 + y = [v if v.size > 0 else np.array([np.nan]) for v in y] + else: + y = remove_na(y) + bp = ax.boxplot(y, **kwds) - if self.return_type == 'dict': - return bp, bp - elif self.return_type == 'both': - return self.BP(ax=ax, lines=bp), bp - else: - return ax, bp - return plotf + if return_type == 'dict': + return bp, bp + elif return_type == 'both': + return cls.BP(ax=ax, lines=bp), bp + else: + return ax, bp def _validate_color_args(self): if 'color' in self.kwds: @@ -2197,7 +2203,6 @@ def maybe_color_bp(self, bp): setp(bp['caps'], color=caps, alpha=1) def _make_plot(self): - plotf = self._get_plot_function() if self.subplots: self._return_obj = compat.OrderedDict() @@ -2205,7 +2210,8 @@ def _make_plot(self): ax = self._get_ax(i) kwds = self.kwds.copy() - ret, bp = plotf(ax, y, column_num=i, **kwds) + ret, bp = self._plot(ax, y, column_num=i, + return_type=self.return_type, **kwds) self.maybe_color_bp(bp) self._return_obj[label] = ret @@ -2216,7 +2222,8 @@ def _make_plot(self): ax = self._get_ax(0) kwds = self.kwds.copy() - ret, bp = plotf(ax, y, column_num=0, **kwds) + ret, bp = self._plot(ax, y, column_num=0, + return_type=self.return_type, **kwds) self.maybe_color_bp(bp) self._return_obj = ret @@ -2261,10 +2268,12 @@ def result(self): _series_kinds = ['pie'] _all_kinds = _common_kinds + _dataframe_kinds + _series_kinds -_plot_klass = {'line': LinePlot, 'bar': BarPlot, 'barh': BarPlot, - 'kde': KdePlot, 'hist': HistPlot, 'box': BoxPlot, - 'scatter': ScatterPlot, 'hexbin': HexBinPlot, - 'area': AreaPlot, 'pie': PiePlot} +_klasses = [LinePlot, BarPlot, BarhPlot, KdePlot, HistPlot, BoxPlot, + ScatterPlot, HexBinPlot, AreaPlot, PiePlot] + +_plot_klass = {} +for klass in _klasses: + _plot_klass[klass._kind] = klass def _plot(data, x=None, y=None, subplots=False, diff --git a/pandas/tools/rplot.py b/pandas/tools/rplot.py index c3c71ab749536..5996fceff8877 100644 --- a/pandas/tools/rplot.py +++ b/pandas/tools/rplot.py @@ -363,7 +363,7 @@ def work(self, fig=None, ax=None): else: ax = fig.gca() for index in range(len(self.data)): - row = self.data.irow(index) + row = self.data.iloc[index] x = row[self.aes['x']] y = row[self.aes['y']] size_scaler = self.aes['size'] diff --git a/pandas/tools/tests/test_merge.py b/pandas/tools/tests/test_merge.py index 7b322b0d311de..ee83b9632bd4b 100644 --- a/pandas/tools/tests/test_merge.py +++ b/pandas/tools/tests/test_merge.py @@ -737,6 +737,88 @@ def test_left_merge_empty_dataframe(self): result = merge(right, left, on='key', how='right') assert_frame_equal(result, left) + def test_merge_left_empty_right_empty(self): + # GH 10824 + left = pd.DataFrame([], columns=['a', 'b', 'c']) + right = pd.DataFrame([], columns=['x', 'y', 'z']) + + exp_in = pd.DataFrame([], columns=['a', 'b', 'c', 'x', 'y', 'z'], + dtype=object) + + for kwarg in [dict(left_index=True, right_index=True), + dict(left_index=True, right_on='x'), + dict(left_on='a', right_index=True), + dict(left_on='a', right_on='x')]: + + result = pd.merge(left, right, how='inner', **kwarg) + tm.assert_frame_equal(result, exp_in) + result = pd.merge(left, right, how='left', **kwarg) + tm.assert_frame_equal(result, exp_in) + result = pd.merge(left, right, how='right', **kwarg) + tm.assert_frame_equal(result, exp_in) + result = pd.merge(left, right, how='outer', **kwarg) + tm.assert_frame_equal(result, exp_in) + + def test_merge_left_empty_right_notempty(self): + # GH 10824 + left = pd.DataFrame([], columns=['a', 'b', 'c']) + right = pd.DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 9]], + columns=['x', 'y', 'z']) + + exp_out = pd.DataFrame({'a': np.array([np.nan]*3, dtype=object), + 'b': np.array([np.nan]*3, dtype=object), + 'c': np.array([np.nan]*3, dtype=object), + 'x': [1, 4, 7], + 'y': [2, 5, 8], + 'z': [3, 6, 9]}, + columns=['a', 'b', 'c', 'x', 'y', 'z']) + exp_in = exp_out[0:0] # make empty DataFrame keeping dtype + + for kwarg in [dict(left_index=True, right_index=True), + dict(left_index=True, right_on='x'), + dict(left_on='a', right_index=True), + dict(left_on='a', right_on='x')]: + + result = pd.merge(left, right, how='inner', **kwarg) + tm.assert_frame_equal(result, exp_in) + result = pd.merge(left, right, how='left', **kwarg) + tm.assert_frame_equal(result, exp_in) + + result = pd.merge(left, right, how='right', **kwarg) + tm.assert_frame_equal(result, exp_out) + result = pd.merge(left, right, how='outer', **kwarg) + tm.assert_frame_equal(result, exp_out) + + def test_merge_left_notempty_right_empty(self): + # GH 10824 + left = pd.DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 9]], + columns=['a', 'b', 'c']) + right = pd.DataFrame([], columns=['x', 'y', 'z']) + + exp_out = pd.DataFrame({'a': [1, 4, 7], + 'b': [2, 5, 8], + 'c': [3, 6, 9], + 'x': np.array([np.nan]*3, dtype=object), + 'y': np.array([np.nan]*3, dtype=object), + 'z': np.array([np.nan]*3, dtype=object)}, + columns=['a', 'b', 'c', 'x', 'y', 'z']) + exp_in = exp_out[0:0] # make empty DataFrame keeping dtype + + for kwarg in [dict(left_index=True, right_index=True), + dict(left_index=True, right_on='x'), + dict(left_on='a', right_index=True), + dict(left_on='a', right_on='x')]: + + result = pd.merge(left, right, how='inner', **kwarg) + tm.assert_frame_equal(result, exp_in) + result = pd.merge(left, right, how='right', **kwarg) + tm.assert_frame_equal(result, exp_in) + + result = pd.merge(left, right, how='left', **kwarg) + tm.assert_frame_equal(result, exp_out) + result = pd.merge(left, right, how='outer', **kwarg) + tm.assert_frame_equal(result, exp_out) + def test_merge_nosort(self): # #2098, anything to do? @@ -790,7 +872,7 @@ def _constructor(self): nad = NotADataFrame(self.df) result = nad.merge(self.df2, on='key1') - tm.assert_isinstance(result, NotADataFrame) + tm.assertIsInstance(result, NotADataFrame) def test_append_dtype_coerce(self): @@ -843,7 +925,6 @@ def test_join_append_timedeltas(self): assert_frame_equal(result, expected) def test_overlapping_columns_error_message(self): - # #2649 df = DataFrame({'key': [1, 2, 3], 'v1': [4, 5, 6], 'v2': [7, 8, 9]}) @@ -853,7 +934,16 @@ def test_overlapping_columns_error_message(self): df.columns = ['key', 'foo', 'foo'] df2.columns = ['key', 'bar', 'bar'] - + expected = DataFrame({'key': [1, 2, 3], + 'v1': [4, 5, 6], + 'v2': [7, 8, 9], + 'v3': [4, 5, 6], + 'v4': [7, 8, 9]}) + expected.columns = ['key', 'foo', 'foo', 'bar', 'bar'] + assert_frame_equal(merge(df, df2), expected) + + # #2649, #10639 + df2.columns = ['key1', 'foo', 'foo'] self.assertRaises(ValueError, merge, df, df2) def _check_merge(x, y): @@ -1994,6 +2084,13 @@ def test_dups_index(self): result = df.append(df) assert_frame_equal(result, expected) + def test_with_mixed_tuples(self): + # 10697 + # columns have mixed tuples, so handle properly + df1 = DataFrame({ u'A' : 'foo', (u'B',1) : 'bar' },index=range(2)) + df2 = DataFrame({ u'B' : 'foo', (u'B',1) : 'bar' },index=range(2)) + result = concat([df1,df2]) + def test_join_dups(self): # joining dups @@ -2535,8 +2632,25 @@ def _constructor(self): nad = NotADataFrame(self.left) result = nad.merge(self.right, on='key') - tm.assert_isinstance(result, NotADataFrame) - + tm.assertIsInstance(result, NotADataFrame) + + def test_empty_sequence_concat(self): + # GH 9157 + empty_pat = "[Nn]o objects" + none_pat = "objects.*None" + test_cases = [ + ((), empty_pat), + ([], empty_pat), + ({}, empty_pat), + ([None], none_pat), + ([None, None], none_pat) + ] + for df_seq, pattern in test_cases: + assertRaisesRegexp(ValueError, pattern, pd.concat, df_seq) + + pd.concat([pd.DataFrame()]) + pd.concat([None, pd.DataFrame()]) + pd.concat([pd.DataFrame(), None]) if __name__ == '__main__': nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'], diff --git a/pandas/tools/tests/test_pivot.py b/pandas/tools/tests/test_pivot.py index bb95234657ec2..34789a3c52cb7 100644 --- a/pandas/tools/tests/test_pivot.py +++ b/pandas/tools/tests/test_pivot.py @@ -268,7 +268,7 @@ def _check_output(res, col, index=['A', 'B'], columns=['C']): # no rows rtable = self.data.pivot_table(columns=['AA', 'BB'], margins=True, aggfunc=np.mean) - tm.assert_isinstance(rtable, Series) + tm.assertIsInstance(rtable, Series) for item in ['DD', 'EE', 'FF']: gmarg = table[item]['All', ''] self.assertEqual(gmarg, self.data[item].mean()) diff --git a/pandas/tools/tests/test_tile.py b/pandas/tools/tests/test_tile.py index 4a0218bef6001..eac6973bffb25 100644 --- a/pandas/tools/tests/test_tile.py +++ b/pandas/tools/tests/test_tile.py @@ -13,8 +13,6 @@ from pandas.tools.tile import cut, qcut import pandas.tools.tile as tmod -from numpy.testing import assert_equal, assert_almost_equal - class TestCut(tm.TestCase): @@ -22,31 +20,31 @@ def test_simple(self): data = np.ones(5) result = cut(data, 4, labels=False) desired = [1, 1, 1, 1, 1] - assert_equal(result, desired) + tm.assert_numpy_array_equal(result, desired) def test_bins(self): data = np.array([.2, 1.4, 2.5, 6.2, 9.7, 2.1]) result, bins = cut(data, 3, retbins=True) - assert_equal(result.codes, [0, 0, 0, 1, 2, 0]) - assert_almost_equal(bins, [0.1905, 3.36666667, 6.53333333, 9.7]) + tm.assert_numpy_array_equal(result.codes, [0, 0, 0, 1, 2, 0]) + tm.assert_almost_equal(bins, [0.1905, 3.36666667, 6.53333333, 9.7]) def test_right(self): data = np.array([.2, 1.4, 2.5, 6.2, 9.7, 2.1, 2.575]) result, bins = cut(data, 4, right=True, retbins=True) - assert_equal(result.codes, [0, 0, 0, 2, 3, 0, 0]) - assert_almost_equal(bins, [0.1905, 2.575, 4.95, 7.325, 9.7]) + tm.assert_numpy_array_equal(result.codes, [0, 0, 0, 2, 3, 0, 0]) + tm.assert_almost_equal(bins, [0.1905, 2.575, 4.95, 7.325, 9.7]) def test_noright(self): data = np.array([.2, 1.4, 2.5, 6.2, 9.7, 2.1, 2.575]) result, bins = cut(data, 4, right=False, retbins=True) - assert_equal(result.codes, [0, 0, 0, 2, 3, 0, 1]) - assert_almost_equal(bins, [0.2, 2.575, 4.95, 7.325, 9.7095]) + tm.assert_numpy_array_equal(result.codes, [0, 0, 0, 2, 3, 0, 1]) + tm.assert_almost_equal(bins, [0.2, 2.575, 4.95, 7.325, 9.7095]) def test_arraylike(self): data = [.2, 1.4, 2.5, 6.2, 9.7, 2.1] result, bins = cut(data, 3, retbins=True) - assert_equal(result.codes, [0, 0, 0, 1, 2, 0]) - assert_almost_equal(bins, [0.1905, 3.36666667, 6.53333333, 9.7]) + tm.assert_numpy_array_equal(result.codes, [0, 0, 0, 1, 2, 0]) + tm.assert_almost_equal(bins, [0.1905, 3.36666667, 6.53333333, 9.7]) def test_bins_not_monotonic(self): data = [.2, 1.4, 2.5, 6.2, 9.7, 2.1] @@ -68,7 +66,7 @@ def test_cut_out_of_range_more(self): s = Series([0, -1, 0, 1, -3]) ind = cut(s, [0, 1], labels=False) exp = [np.nan, np.nan, np.nan, 0, np.nan] - assert_almost_equal(ind, exp) + tm.assert_almost_equal(ind, exp) def test_labels(self): arr = np.tile(np.arange(0, 1.01, 0.1), 4) @@ -122,8 +120,8 @@ def test_inf_handling(self): ex_categories = ['(-inf, 2]', '(2, 4]', '(4, inf]'] - np.testing.assert_array_equal(result.categories, ex_categories) - np.testing.assert_array_equal(result_ser.cat.categories, ex_categories) + tm.assert_numpy_array_equal(result.categories, ex_categories) + tm.assert_numpy_array_equal(result_ser.cat.categories, ex_categories) self.assertEqual(result[5], '(4, inf]') self.assertEqual(result[0], '(-inf, 2]') self.assertEqual(result_ser[5], '(4, inf]') @@ -134,7 +132,7 @@ def test_qcut(self): labels, bins = qcut(arr, 4, retbins=True) ex_bins = quantile(arr, [0, .25, .5, .75, 1.]) - assert_almost_equal(bins, ex_bins) + tm.assert_almost_equal(bins, ex_bins) ex_levels = cut(arr, ex_bins, include_lowest=True) self.assert_numpy_array_equal(labels, ex_levels) @@ -252,12 +250,12 @@ def test_series_retbins(self): # GH 8589 s = Series(np.arange(4)) result, bins = cut(s, 2, retbins=True) - assert_equal(result.cat.codes.values, [0, 0, 1, 1]) - assert_almost_equal(bins, [-0.003, 1.5, 3]) + tm.assert_numpy_array_equal(result.cat.codes.values, [0, 0, 1, 1]) + tm.assert_almost_equal(bins, [-0.003, 1.5, 3]) result, bins = qcut(s, 2, retbins=True) - assert_equal(result.cat.codes.values, [0, 0, 1, 1]) - assert_almost_equal(bins, [0, 1.5, 3]) + tm.assert_numpy_array_equal(result.cat.codes.values, [0, 0, 1, 1]) + tm.assert_almost_equal(bins, [0, 1.5, 3]) def curpath(): diff --git a/pandas/tools/tests/test_util.py b/pandas/tools/tests/test_util.py index 9480ea7ee5bf8..1adf47e946a96 100644 --- a/pandas/tools/tests/test_util.py +++ b/pandas/tools/tests/test_util.py @@ -43,8 +43,7 @@ def setUpClass(cls): if not cls.locales: raise nose.SkipTest("No locales found") - if os.name == 'nt': # we're on windows - raise nose.SkipTest("Running on Windows") + tm._skip_if_windows() @classmethod def tearDownClass(cls): diff --git a/pandas/tools/tile.py b/pandas/tools/tile.py index 6830919d9c09f..416addfcf2ad5 100644 --- a/pandas/tools/tile.py +++ b/pandas/tools/tile.py @@ -217,7 +217,7 @@ def _bins_to_cuts(x, bins, right=True, labels=None, retbins=False, levels = np.asarray(levels, dtype=object) np.putmask(ids, na_mask, 0) - fac = Categorical(ids - 1, levels, ordered=True, name=name, fastpath=True) + fac = Categorical(ids - 1, levels, ordered=True, fastpath=True) else: fac = ids - 1 if has_nas: @@ -225,7 +225,7 @@ def _bins_to_cuts(x, bins, right=True, labels=None, retbins=False, np.putmask(fac, na_mask, np.nan) if x_is_series: - fac = Series(fac, index=series_index) + fac = Series(fac, index=series_index, name=name) if not retbins: return fac diff --git a/pandas/tseries/base.py b/pandas/tseries/base.py index 71ff0f6c9c56c..c353e66bc2dbb 100644 --- a/pandas/tseries/base.py +++ b/pandas/tseries/base.py @@ -17,6 +17,29 @@ import pandas.algos as _algos + +class DatelikeOps(object): + """ common ops for DatetimeIndex/PeriodIndex, but not TimedeltaIndex """ + + def strftime(self, date_format): + """ + Return an array of formatted strings specified by date_format, which + supports the same string format as the python standard library. Details + of the string format can be found in the `python string format doc + `__ + + Parameters + ---------- + date_format : str + date format string (e.g. "%Y-%m-%d") + + Returns + ------- + ndarray of formatted strings + """ + return np.asarray(self.format(date_format=date_format)) + + class DatetimeIndexOpsMixin(object): """ common ops mixin to support a unified inteface datetimelike Index """ @@ -140,20 +163,31 @@ def order(self, return_indexer=False, ascending=True): return sorted_index, _as else: sorted_values = np.sort(self.values) + attribs = self._get_attributes_dict() + freq = attribs['freq'] + from pandas.tseries.period import PeriodIndex + if freq is not None and not isinstance(self, PeriodIndex): + if freq.n > 0 and not ascending: + freq = freq * -1 + elif freq.n < 0 and ascending: + freq = freq * -1 + attribs['freq'] = freq + if not ascending: sorted_values = sorted_values[::-1] - attribs = self._get_attributes_dict() - attribs['freq'] = None + return self._simple_new(sorted_values, **attribs) def take(self, indices, axis=0): """ Analogous to ndarray.take """ - maybe_slice = lib.maybe_indices_to_slice(com._ensure_int64(indices)) + indices = com._ensure_int64(indices) + maybe_slice = lib.maybe_indices_to_slice(indices, len(self)) if isinstance(maybe_slice, slice): return self[maybe_slice] - return super(DatetimeIndexOpsMixin, self).take(indices, axis) + taken = self.asi8.take(com._ensure_platform_int(indices)) + return self._shallow_copy(taken, freq=None) def get_duplicates(self): values = Index.get_duplicates(self) @@ -169,6 +203,14 @@ def asobject(self): from pandas.core.index import Index return Index(self._box_values(self.asi8), name=self.name, dtype=object) + def _convert_tolerance(self, tolerance): + try: + return tslib.Timedelta(tolerance).to_timedelta64() + except ValueError: + raise ValueError('tolerance argument for %s must be convertible ' + 'to Timedelta: %r' + % (type(self).__name__, tolerance)) + def _maybe_mask_results(self, result, fill_value=None, convert=None): """ Parameters @@ -318,8 +360,7 @@ def resolution(self): """ Returns day, hour, minute, second, millisecond or microsecond """ - from pandas.tseries.frequencies import get_reso_string - return get_reso_string(self._resolution) + return Resolution.get_str(self._resolution) def _convert_scalar_indexer(self, key, kind=None): """ @@ -450,7 +491,7 @@ def isin(self, values): return self.asobject.isin(values) value_set = set(values.asi8) - return lib.ismember(self.asi8, value_set) + return lib.ismember_int64(self.asi8, value_set) def shift(self, n, freq=None): """ diff --git a/pandas/tseries/common.py b/pandas/tseries/common.py index c273906ef3d05..a4d5939d386ae 100644 --- a/pandas/tseries/common.py +++ b/pandas/tseries/common.py @@ -125,7 +125,7 @@ def to_pydatetime(self): accessors=DatetimeIndex._datetimelike_ops, typ='property') DatetimeProperties._add_delegate_accessors(delegate=DatetimeIndex, - accessors=["to_period","tz_localize","tz_convert","normalize"], + accessors=["to_period","tz_localize","tz_convert","normalize","strftime"], typ='method') class TimedeltaProperties(Properties): @@ -181,6 +181,9 @@ class PeriodProperties(Properties): PeriodProperties._add_delegate_accessors(delegate=PeriodIndex, accessors=PeriodIndex._datetimelike_ops, typ='property') +PeriodProperties._add_delegate_accessors(delegate=PeriodIndex, + accessors=["strftime"], + typ='method') class CombinedDatetimelikeProperties(DatetimeProperties, TimedeltaProperties): diff --git a/pandas/tseries/frequencies.py b/pandas/tseries/frequencies.py index 4af8c68110978..85de5e083d6d9 100644 --- a/pandas/tseries/frequencies.py +++ b/pandas/tseries/frequencies.py @@ -32,6 +32,8 @@ class FreqGroup(object): class Resolution(object): + # defined in period.pyx + # note that these are different from freq codes RESO_US = period.US_RESO RESO_MS = period.MS_RESO RESO_SEC = period.S_RESO @@ -65,30 +67,104 @@ class Resolution(object): @classmethod def get_str(cls, reso): + """ + Return resolution str against resolution code. + + Example + ------- + >>> Resolution.get_str(Resolution.RESO_SEC) + 'second' + """ return cls._reso_str_map.get(reso, 'day') @classmethod def get_reso(cls, resostr): + """ + Return resolution str against resolution code. + + Example + ------- + >>> Resolution.get_reso('second') + 2 + + >>> Resolution.get_reso('second') == Resolution.RESO_SEC + True + """ return cls._str_reso_map.get(resostr, cls.RESO_DAY) + @classmethod + def get_freq_group(cls, resostr): + """ + Return frequency str against resolution str. + + Example + ------- + >>> f.Resolution.get_freq_group('day') + 4000 + """ + return get_freq_group(cls.get_freq(resostr)) + @classmethod def get_freq(cls, resostr): + """ + Return frequency str against resolution str. + + Example + ------- + >>> f.Resolution.get_freq('day') + 'D' + """ return cls._reso_freq_map[resostr] @classmethod def get_str_from_freq(cls, freq): + """ + Return resolution str against frequency str. + + Example + ------- + >>> Resolution.get_str_from_freq('H') + 'hour' + """ return cls._freq_reso_map.get(freq, 'day') @classmethod def get_reso_from_freq(cls, freq): - return cls.get_reso(cls.get_str_from_freq(freq)) + """ + Return resolution code against frequency str. + Example + ------- + >>> Resolution.get_reso_from_freq('H') + 4 -def get_reso_string(reso): - return Resolution.get_str(reso) + >>> Resolution.get_reso_from_freq('H') == Resolution.RESO_HR + True + """ + return cls.get_reso(cls.get_str_from_freq(freq)) def get_to_timestamp_base(base): + """ + Return frequency code group used for base of to_timestamp against + frequency code. + + Example + ------- + # Return day freq code against longer freq than day + >>> get_to_timestamp_base(get_freq_code('D')[0]) + 6000 + >>> get_to_timestamp_base(get_freq_code('W')[0]) + 6000 + >>> get_to_timestamp_base(get_freq_code('M')[0]) + 6000 + + # Return second freq code against hour between second + >>> get_to_timestamp_base(get_freq_code('H')[0]) + 9000 + >>> get_to_timestamp_base(get_freq_code('S')[0]) + 9000 + """ if base < FreqGroup.FR_BUS: return FreqGroup.FR_DAY if FreqGroup.FR_HR <= base <= FreqGroup.FR_SEC: @@ -97,6 +173,17 @@ def get_to_timestamp_base(base): def get_freq_group(freq): + """ + Return frequency code group of given frequency str. + + Example + ------- + >>> get_freq_group('W-MON') + 4000 + + >>> get_freq_group('W-FRI') + 4000 + """ if isinstance(freq, compat.string_types): base, mult = get_freq_code(freq) freq = base @@ -104,6 +191,18 @@ def get_freq_group(freq): def get_freq(freq): + """ + Return frequency code of given frequency str. + If input is not string, return input as it is. + + Example + ------- + >>> get_freq('A') + 1000 + + >>> get_freq('3A') + 1000 + """ if isinstance(freq, compat.string_types): base, mult = get_freq_code(freq) freq = base @@ -112,15 +211,29 @@ def get_freq(freq): def get_freq_code(freqstr): """ + Return freq str or tuple to freq code and stride (mult) Parameters ---------- + freqstr : str or tuple Returns ------- + return : tuple of base frequency code and stride (mult) + + Example + ------- + >>> get_freq_code('3D') + (6000, 3) + + >>> get_freq_code('D') + (6000, 1) + + >>> get_freq_code(('D', 3)) + (6000, 3) """ if isinstance(freqstr, DateOffset): - freqstr = (get_offset_name(freqstr), freqstr.n) + freqstr = (freqstr.rule_code, freqstr.n) if isinstance(freqstr, tuple): if (com.is_integer(freqstr[0]) and @@ -201,14 +314,12 @@ def _get_freq_str(base, mult=1): } need_suffix = ['QS', 'BQ', 'BQS', 'AS', 'BA', 'BAS'] -_months = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', - 'OCT', 'NOV', 'DEC'] for __prefix in need_suffix: - for _m in _months: + for _m in tslib._MONTHS: _offset_to_period_map['%s-%s' % (__prefix, _m)] = \ _offset_to_period_map[__prefix] for __prefix in ['A', 'Q']: - for _m in _months: + for _m in tslib._MONTHS: _alias = '%s-%s' % (__prefix, _m) _offset_to_period_map[_alias] = _alias @@ -386,6 +497,7 @@ def get_base_alias(freqstr): """ return _base_and_stride(freqstr)[0] + _dont_uppercase = set(('MS', 'ms')) @@ -637,14 +749,6 @@ def _period_alias_dictionary(): return alias_dict -def _infer_period_group(freqstr): - return _period_group(Resolution._reso_freq_map[freqstr]) - - -def _period_group(freqstr): - base, mult = get_freq_code(freqstr) - return base // 1000 * 1000 - _period_alias_dict = _period_alias_dictionary() @@ -671,7 +775,7 @@ def _period_str_to_code(freqstr): def infer_freq(index, warn=True): """ Infer the most likely frequency given the input index. If the frequency is - uncertain, a warning will be printed. + uncertain, a warning will be printed. Parameters ---------- @@ -1082,12 +1186,7 @@ def is_superperiod(source, target): return target in ['N'] -def _get_rule_month(source, default='DEC'): - source = source.upper() - if '-' not in source: - return default - else: - return source.split('-')[1] +_get_rule_month = tslib._get_rule_month def _is_annual(rule): @@ -1118,15 +1217,10 @@ def _is_weekly(rule): DAYS = ['MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT', 'SUN'] -MONTHS = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', - 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'] - -_month_numbers = dict((k, i) for i, k in enumerate(MONTHS)) - - +MONTHS = tslib._MONTHS +_month_numbers = tslib._MONTH_NUMBERS +_month_aliases = tslib._MONTH_ALIASES _weekday_rule_aliases = dict((k, v) for k, v in enumerate(DAYS)) -_month_aliases = dict((k + 1, v) for k, v in enumerate(MONTHS)) - def _is_multiple(us, mult): return us % mult == 0 diff --git a/pandas/tseries/holiday.py b/pandas/tseries/holiday.py index f55569302ca05..e98c5dd93e68a 100644 --- a/pandas/tseries/holiday.py +++ b/pandas/tseries/holiday.py @@ -405,15 +405,15 @@ def merge(self, other, inplace=False): else: return holidays -USMemorialDay = Holiday('MemorialDay', month=5, day=24, - offset=DateOffset(weekday=MO(1))) +USMemorialDay = Holiday('MemorialDay', month=5, day=31, + offset=DateOffset(weekday=MO(-1))) USLaborDay = Holiday('Labor Day', month=9, day=1, offset=DateOffset(weekday=MO(1))) USColumbusDay = Holiday('Columbus Day', month=10, day=1, offset=DateOffset(weekday=MO(2))) USThanksgivingDay = Holiday('Thanksgiving', month=11, day=1, offset=DateOffset(weekday=TH(4))) -USMartinLutherKingJr = Holiday('Dr. Martin Luther King Jr.', month=1, day=1, +USMartinLutherKingJr = Holiday('Dr. Martin Luther King Jr.', start_date=datetime(1986,1,1), month=1, day=1, offset=DateOffset(weekday=MO(3))) USPresidentsDay = Holiday('President''s Day', month=2, day=1, offset=DateOffset(weekday=MO(3))) diff --git a/pandas/tseries/index.py b/pandas/tseries/index.py index 1a0d87c0d26d3..0525a29ef3fd0 100644 --- a/pandas/tseries/index.py +++ b/pandas/tseries/index.py @@ -1,20 +1,24 @@ # pylint: disable=E1101 import operator +import warnings from datetime import time, datetime from datetime import timedelta import numpy as np from pandas.core.common import (_NS_DTYPE, _INT64_DTYPE, _values_from_object, _maybe_box, - ABCSeries, is_integer, is_float) + ABCSeries, is_integer, is_float, + is_object_dtype, is_datetime64_dtype) +from pandas.io.common import PerformanceWarning from pandas.core.index import Index, Int64Index, Float64Index import pandas.compat as compat from pandas.compat import u from pandas.tseries.frequencies import ( to_offset, get_period_alias, Resolution) -from pandas.tseries.base import DatetimeIndexOpsMixin +from pandas.tseries.base import DatelikeOps, DatetimeIndexOpsMixin from pandas.tseries.offsets import DateOffset, generate_range, Tick, CDay from pandas.tseries.tools import parse_time_string, normalize_date +from pandas.tseries.timedeltas import to_timedelta from pandas.util.decorators import cache_readonly, deprecate_kwarg import pandas.core.common as com import pandas.tseries.offsets as offsets @@ -116,7 +120,7 @@ def _new_DatetimeIndex(cls, d): result.tz = tz return result -class DatetimeIndex(DatetimeIndexOpsMixin, Int64Index): +class DatetimeIndex(DatelikeOps, DatetimeIndexOpsMixin, Int64Index): """ Immutable ndarray of datetime64 data, represented internally as int64, and which can be boxed to Timestamp objects that are subclasses of datetime and @@ -179,8 +183,8 @@ def _join_i8_wrapper(joinf, **kwargs): tz = None offset = None - _comparables = ['name','freqstr','tz'] - _attributes = ['name','freq','tz'] + _comparables = ['name', 'freqstr', 'tz'] + _attributes = ['name', 'freq', 'tz'] _datetimelike_ops = ['year','month','day','hour','minute','second', 'weekofyear','week','dayofweek','weekday','dayofyear','quarter', 'days_in_month', 'daysinmonth', 'date','time','microsecond','nanosecond','is_month_start','is_month_end', @@ -239,8 +243,9 @@ def __new__(cls, data=None, # try a few ways to make it datetime64 if lib.is_string_array(data): - data = _str_to_dt_array(data, freq, dayfirst=dayfirst, - yearfirst=yearfirst) + data = tslib.parse_str_array_to_datetime(data, freq=freq, + dayfirst=dayfirst, + yearfirst=yearfirst) else: data = tools.to_datetime(data, errors='raise') data.offset = freq @@ -254,8 +259,9 @@ def __new__(cls, data=None, return data if issubclass(data.dtype.type, compat.string_types): - data = _str_to_dt_array(data, freq, dayfirst=dayfirst, - yearfirst=yearfirst) + data = tslib.parse_str_array_to_datetime(data, freq=freq, + dayfirst=dayfirst, + yearfirst=yearfirst) if issubclass(data.dtype.type, np.datetime64): if isinstance(data, ABCSeries): @@ -288,8 +294,9 @@ def __new__(cls, data=None, values = data if lib.is_string_array(values): - subarr = _str_to_dt_array(values, freq, dayfirst=dayfirst, - yearfirst=yearfirst) + subarr = tslib.parse_str_array_to_datetime(values, freq=freq, dayfirst=dayfirst, + yearfirst=yearfirst) + else: try: subarr = tools.to_datetime(data, box=False) @@ -298,11 +305,11 @@ def __new__(cls, data=None, if isinstance(subarr, ABCSeries): subarr = subarr.values if subarr.dtype == np.object_: - subarr = tools.to_datetime(subarr, box=False) + subarr = tools._to_datetime(subarr, box=False) except ValueError: # tz aware - subarr = tools.to_datetime(data, box=False, utc=True) + subarr = tools._to_datetime(data, box=False, utc=True) if not np.issubdtype(subarr.dtype, np.datetime64): raise ValueError('Unable to convert %s to datetime dtype' @@ -332,7 +339,7 @@ def __new__(cls, data=None, if inferred != freq.freqstr: on_freq = cls._generate(subarr[0], None, len(subarr), None, freq, tz=tz) if not np.array_equal(subarr.asi8, on_freq.asi8): - raise ValueError('Inferred frequency {0} from passed dates does not' + raise ValueError('Inferred frequency {0} from passed dates does not ' 'conform to passed frequency {1}'.format(inferred, freq.freqstr)) if freq_infer: @@ -491,9 +498,16 @@ def _local_timestamps(self): @classmethod def _simple_new(cls, values, name=None, freq=None, tz=None, **kwargs): + """ + we require the we have a dtype compat for the values + if we are passed a non-dtype compat, then coerce using the constructor + """ + if not getattr(values,'dtype',None): values = np.array(values,copy=False) - if values.dtype != _NS_DTYPE: + if is_object_dtype(values): + return cls(values, name=name, freq=freq, tz=tz, **kwargs).values + elif not is_datetime64_dtype(values): values = com._ensure_int64(values).view(_NS_DTYPE) result = object.__new__(cls) @@ -534,7 +548,7 @@ def _cached_range(cls, start=None, end=None, periods=None, offset=None, xdr = generate_range(offset=offset, start=_CACHE_START, end=_CACHE_END) - arr = tools.to_datetime(list(xdr), box=False) + arr = tools._to_datetime(list(xdr), box=False) cachedRange = DatetimeIndex._simple_new(arr) cachedRange.offset = offset @@ -661,8 +675,11 @@ def _add_delta(self, delta): new_values = self._add_delta_tdi(delta) # update name when delta is Index name = com._maybe_match_name(self, delta) + elif isinstance(delta, DateOffset): + new_values = self._add_offset(delta).asi8 else: new_values = self.astype('O') + delta + tz = 'UTC' if self.tz is not None else None result = DatetimeIndex(new_values, tz=tz, name=name, freq='infer') utc = _utc() @@ -670,6 +687,14 @@ def _add_delta(self, delta): result = result.tz_convert(self.tz) return result + def _add_offset(self, offset): + try: + return offset.apply_index(self) + except NotImplementedError: + warnings.warn("Non-vectorized DateOffset being applied to Series or DatetimeIndex", + PerformanceWarning) + return self.astype('O') + offset + def _format_native_types(self, na_rep=u('NaT'), date_format=None, **kwargs): from pandas.core.format import _get_format_datetime64_from_values @@ -823,6 +848,24 @@ def union(self, other): result.offset = to_offset(result.inferred_freq) return result + def to_perioddelta(self, freq): + """ + Calcuates TimedeltaIndex of difference between index + values and index converted to PeriodIndex at specified + freq. Used for vectorized offsets + + .. versionadded:: 0.17.0 + + Parameters + ---------- + freq : Period frequency + + Returns + ------- + y : TimedeltaIndex + """ + return to_timedelta(self.asi8 - self.to_period(freq).to_timestamp().asi8) + def union_many(self, others): """ A bit of a hack to accelerate unioning a collection of indexes @@ -1227,7 +1270,7 @@ def get_value_maybe_box(self, series, key): values = self._engine.get_value(_values_from_object(series), key) return _maybe_box(self, values, series, key) - def get_loc(self, key, method=None): + def get_loc(self, key, method=None, tolerance=None): """ Get integer location for requested label @@ -1235,10 +1278,15 @@ def get_loc(self, key, method=None): ------- loc : int """ + if tolerance is not None: + # try converting tolerance now, so errors don't get swallowed by + # the try/except clauses below + tolerance = self._convert_tolerance(tolerance) + if isinstance(key, datetime): # needed to localize naive datetimes key = Timestamp(key, tz=self.tz) - return Index.get_loc(self, key, method=method) + return Index.get_loc(self, key, method, tolerance) if isinstance(key, time): if method is not None: @@ -1247,7 +1295,7 @@ def get_loc(self, key, method=None): return self.indexer_at_time(key) try: - return Index.get_loc(self, key, method=method) + return Index.get_loc(self, key, method, tolerance) except (KeyError, ValueError, TypeError): try: return self._get_string_slice(key) @@ -1256,7 +1304,7 @@ def get_loc(self, key, method=None): try: stamp = Timestamp(key, tz=self.tz) - return Index.get_loc(self, stamp, method=method) + return Index.get_loc(self, stamp, method, tolerance) except (KeyError, ValueError): raise KeyError(key) @@ -1389,7 +1437,8 @@ def time(self): """ # can't call self.map() which tries to treat func as ufunc # and causes recursion warnings on python 2.6 - return self._maybe_mask_results(_algos.arrmap_object(self.asobject.values, lambda x: x.time())) + return self._maybe_mask_results(_algos.arrmap_object(self.asobject.values, + lambda x: np.nan if x is tslib.NaT else x.time())) @property def date(self): @@ -1497,7 +1546,7 @@ def insert(self, loc, item): if zone != izone: raise ValueError('Passed item and index have different timezone') # check freq can be preserved on edge cases - if self.freq is not None: + if self.size and self.freq is not None: if (loc == 0 or loc == -len(self)) and item + self.freq == self[0]: freq = self.freq elif (loc == len(self)) and item - self.freq == self[-1]: @@ -1538,7 +1587,7 @@ def delete(self, loc): freq = self.freq else: if com.is_list_like(loc): - loc = lib.maybe_indices_to_slice(com._ensure_int64(np.array(loc))) + loc = lib.maybe_indices_to_slice(com._ensure_int64(np.array(loc)), len(self)) if isinstance(loc, slice) and loc.step in (1, None): if (loc.start in (0, None) or loc.stop in (len(self), None)): freq = self.freq @@ -1926,17 +1975,6 @@ def _to_m8(key, tz=None): return np.int64(tslib.pydt_to_i8(key)).view(_NS_DTYPE) -def _str_to_dt_array(arr, offset=None, dayfirst=None, yearfirst=None): - def parser(x): - result = parse_time_string(x, offset, dayfirst=dayfirst, - yearfirst=yearfirst) - return result[0] - - arr = np.asarray(arr, dtype=object) - data = _algos.arrmap_object(arr, parser) - return tools.to_datetime(data) - - _CACHE_START = Timestamp(datetime(1950, 1, 1)) _CACHE_END = Timestamp(datetime(2030, 1, 1)) diff --git a/pandas/tseries/offsets.py b/pandas/tseries/offsets.py index 3bebd0daa6d29..33faac153cce0 100644 --- a/pandas/tseries/offsets.py +++ b/pandas/tseries/offsets.py @@ -4,6 +4,8 @@ import numpy as np from pandas.tseries.tools import to_datetime +from pandas.tseries.timedeltas import to_timedelta +from pandas.core.common import ABCSeries, ABCDatetimeIndex # import after tools, dateutil check from dateutil.relativedelta import relativedelta, weekday @@ -93,6 +95,15 @@ def wrapper(self, other): return wrapper +def apply_index_wraps(func): + @functools.wraps(func) + def wrapper(self, other): + result = func(self, other) + if self.normalize: + result = result.to_period('D').to_timestamp() + return result + return wrapper + def _is_normalized(dt): if (dt.hour != 0 or dt.minute != 0 or dt.second != 0 or dt.microsecond != 0 or getattr(dt, 'nanosecond', 0) != 0): @@ -221,6 +232,67 @@ def apply(self, other): else: return other + timedelta(self.n) + @apply_index_wraps + def apply_index(self, i): + """ + Vectorized apply of DateOffset to DatetimeIndex, + raises NotImplentedError for offsets without a + vectorized implementation + + .. versionadded:: 0.17.0 + + Parameters + ---------- + i : DatetimeIndex + + Returns + ------- + y : DatetimeIndex + """ + + if not type(self) is DateOffset: + raise NotImplementedError("DateOffset subclass %s " + "does not have a vectorized " + "implementation" + % (self.__class__.__name__,)) + relativedelta_fast = set(['years', 'months', 'weeks', + 'days', 'hours', 'minutes', + 'seconds', 'microseconds']) + # relativedelta/_offset path only valid for base DateOffset + if (self._use_relativedelta and + set(self.kwds).issubset(relativedelta_fast)): + months = ((self.kwds.get('years', 0) * 12 + + self.kwds.get('months', 0)) * self.n) + if months: + base = (i.to_period('M') + months).to_timestamp() + time = i.to_perioddelta('D') + days = i.to_perioddelta('M') - time + # minimum prevents month-end from wrapping + day_offset = np.minimum(days, + to_timedelta(base.days_in_month - 1, unit='D')) + i = base + day_offset + time + + weeks = (self.kwds.get('weeks', 0)) * self.n + if weeks: + i = (i.to_period('W') + weeks).to_timestamp() + i.to_perioddelta('W') + + timedelta_kwds = dict((k,v) for k,v in self.kwds.items() + if k in ['days','hours','minutes', + 'seconds','microseconds']) + if timedelta_kwds: + delta = Timedelta(**timedelta_kwds) + i = i + (self.n * delta) + return i + elif not self._use_relativedelta and hasattr(self, '_offset'): + # timedelta + return i + (self._offset * self.n) + else: + # relativedelta with other keywords + raise NotImplementedError("DateOffset with relativedelta " + "keyword(s) %s not able to be " + "applied vectorized" % + (set(self.kwds) - relativedelta_fast),) + def isAnchored(self): return (self.n == 1) @@ -307,6 +379,8 @@ def __call__(self, other): return self.apply(other) def __add__(self, other): + if isinstance(other, (ABCDatetimeIndex, ABCSeries)): + return other + self try: return self.apply(other) except ApplyTypeError: @@ -324,6 +398,8 @@ def __sub__(self, other): return NotImplemented def __rsub__(self, other): + if isinstance(other, (ABCDatetimeIndex, ABCSeries)): + return other - self return self.__class__(-self.n, normalize=self.normalize, **self.kwds) + other def __mul__(self, someInt): @@ -363,6 +439,37 @@ def onOffset(self, dt): b = ((dt + self) - self) return a == b + # helpers for vectorized offsets + def _beg_apply_index(self, i, freq): + """Offsets index to beginning of Period frequency""" + + off = i.to_perioddelta('D') + base_period = i.to_period(freq) + if self.n < 0: + # when subtracting, dates on start roll to prior + roll = np.where(base_period.to_timestamp() == i - off, + self.n, self.n + 1) + else: + roll = self.n + + base = (base_period + roll).to_timestamp() + return base + off + + def _end_apply_index(self, i, freq): + """Offsets index to end of Period frequency""" + + off = i.to_perioddelta('D') + base_period = i.to_period(freq) + if self.n > 0: + # when adding, dtates on end roll to next + roll = np.where(base_period.to_timestamp(how='end') == i - off, + self.n, self.n - 1) + else: + roll = self.n + + base = (base_period + roll).to_timestamp(how='end') + return base + off + # way to get around weirdness with rule_code @property def _prefix(self): @@ -529,6 +636,19 @@ def apply(self, other): raise ApplyTypeError('Only know how to combine business day with ' 'datetime or timedelta.') + @apply_index_wraps + def apply_index(self, i): + time = i.to_perioddelta('D') + # to_period rolls forward to next BDay; track and + # reduce n where it does when rolling forward + shifted = (i.to_perioddelta('B') - time).asi8 != 0 + if self.n > 0: + roll = np.where(shifted, self.n - 1, self.n) + else: + roll = self.n + + return (i.to_period('B') + roll).to_timestamp() + time + def onOffset(self, dt): if self.normalize and not _is_normalized(dt): return False @@ -902,6 +1022,9 @@ def apply(self, other): raise ApplyTypeError('Only know how to combine trading day with ' 'datetime, datetime64 or timedelta.') + def apply_index(self, i): + raise NotImplementedError + @staticmethod def _to_dt64(dt, dtype='datetime64'): # Currently @@ -949,6 +1072,10 @@ def apply(self, other): other = other + relativedelta(months=n, day=31) return other + @apply_index_wraps + def apply_index(self, i): + return self._end_apply_index(i, 'M') + def onOffset(self, dt): if self.normalize and not _is_normalized(dt): return False @@ -970,6 +1097,10 @@ def apply(self, other): return other + relativedelta(months=n, day=1) + @apply_index_wraps + def apply_index(self, i): + return self._beg_apply_index(i, 'M') + def onOffset(self, dt): if self.normalize and not _is_normalized(dt): return False @@ -1211,6 +1342,13 @@ def apply(self, other): base.hour, base.minute, base.second, base.microsecond) return other + @apply_index_wraps + def apply_index(self, i): + if self.weekday is None: + return (i.to_period('W') + self.n).to_timestamp() + i.to_perioddelta('W') + else: + return self._end_apply_index(i, self.freqstr) + def onOffset(self, dt): if self.normalize and not _is_normalized(dt): return False @@ -1508,22 +1646,7 @@ def onOffset(self, dt): modMonth = (dt.month - self.startingMonth) % 3 return BMonthEnd().onOffset(dt) and modMonth == 0 - -_int_to_month = { - 1: 'JAN', - 2: 'FEB', - 3: 'MAR', - 4: 'APR', - 5: 'MAY', - 6: 'JUN', - 7: 'JUL', - 8: 'AUG', - 9: 'SEP', - 10: 'OCT', - 11: 'NOV', - 12: 'DEC' -} - +_int_to_month = tslib._MONTH_ALIASES _month_to_int = dict((v, k) for k, v in _int_to_month.items()) @@ -1602,6 +1725,10 @@ def apply(self, other): other = other + relativedelta(months=monthsToGo + 3 * n, day=31) return other + @apply_index_wraps + def apply_index(self, i): + return self._end_apply_index(i, self.freqstr) + def onOffset(self, dt): if self.normalize and not _is_normalized(dt): return False @@ -1636,6 +1763,11 @@ def apply(self, other): other = other + relativedelta(months=3 * n - monthsSince, day=1) return other + @apply_index_wraps + def apply_index(self, i): + freq_month = 12 if self.startingMonth == 1 else self.startingMonth - 1 + freqstr = 'Q-%s' % (_int_to_month[freq_month],) + return self._beg_apply_index(i, freqstr) class YearOffset(DateOffset): """DateOffset that just needs a month""" @@ -1779,6 +1911,11 @@ def _rollf(date): result = _rollf(result) return result + @apply_index_wraps + def apply_index(self, i): + # convert month anchor to annual period tuple + return self._end_apply_index(i, self.freqstr) + def onOffset(self, dt): if self.normalize and not _is_normalized(dt): return False @@ -1824,6 +1961,12 @@ def _rollf(date): result = _rollf(result) return result + @apply_index_wraps + def apply_index(self, i): + freq_month = 12 if self.month == 1 else self.month - 1 + freqstr = 'A-%s' % (_int_to_month[freq_month],) + return self._beg_apply_index(i, freqstr) + def onOffset(self, dt): if self.normalize and not _is_normalized(dt): return False @@ -2326,6 +2469,7 @@ def apply(self, other): _prefix = 'undefined' + def isAnchored(self): return False @@ -2450,12 +2594,12 @@ def generate_range(start=None, end=None, periods=None, if start and not offset.onOffset(start): start = offset.rollforward(start) - if end and not offset.onOffset(end): + elif end and not offset.onOffset(end): end = offset.rollback(end) - if periods is None and end < start: - end = None - periods = 0 + if periods is None and end < start: + end = None + periods = 0 if end is None: end = start + (periods - 1) * offset @@ -2465,7 +2609,6 @@ def generate_range(start=None, end=None, periods=None, cur = start - next_date = cur while cur <= end: yield cur diff --git a/pandas/tseries/period.py b/pandas/tseries/period.py index 95bbc5016237c..56d7d45120fdc 100644 --- a/pandas/tseries/period.py +++ b/pandas/tseries/period.py @@ -4,7 +4,7 @@ import pandas.tseries.frequencies as frequencies from pandas.tseries.frequencies import get_freq_code as _gfc from pandas.tseries.index import DatetimeIndex, Int64Index, Index -from pandas.tseries.base import DatetimeIndexOpsMixin +from pandas.tseries.base import DatelikeOps, DatetimeIndexOpsMixin from pandas.tseries.tools import parse_time_string import pandas.tseries.offsets as offsets @@ -19,8 +19,10 @@ import pandas.core.common as com from pandas.core.common import (isnull, _INT64_DTYPE, _maybe_box, _values_from_object, ABCSeries, - is_integer, is_float) + is_integer, is_float, is_object_dtype) from pandas import compat +from pandas.util.decorators import cache_readonly + from pandas.lib import Timestamp, Timedelta import pandas.lib as lib import pandas.tslib as tslib @@ -92,7 +94,7 @@ def wrapper(self, other): return wrapper -class PeriodIndex(DatetimeIndexOpsMixin, Int64Index): +class PeriodIndex(DatelikeOps, DatetimeIndexOpsMixin, Int64Index): """ Immutable ndarray holding ordinal values indicating regular periods in time such as particular years, quarters, months, etc. A value of 1 is the @@ -259,13 +261,36 @@ def _from_arraylike(cls, data, freq, tz): @classmethod def _simple_new(cls, values, name=None, freq=None, **kwargs): + if not getattr(values,'dtype',None): + values = np.array(values,copy=False) + if is_object_dtype(values): + return PeriodIndex(values, name=name, freq=freq, **kwargs) + result = object.__new__(cls) result._data = values result.name = name + + if freq is None: + raise ValueError('freq not specified') result.freq = freq + result._reset_identity() return result + def _shallow_copy(self, values=None, infer=False, **kwargs): + """ we always want to return a PeriodIndex """ + return super(PeriodIndex, self)._shallow_copy(values=values, infer=False, **kwargs) + + def _coerce_scalar_to_index(self, item): + """ + we need to coerce a scalar to a compat for our index type + + Parameters + ---------- + item : scalar item to coerce + """ + return PeriodIndex([item], **self._get_attributes_dict()) + @property def _na_value(self): return self._box_func(tslib.iNaT) @@ -477,22 +502,26 @@ def to_timestamp(self, freq=None, how='start'): new_data = period.periodarr_to_dt64arr(new_data.values, base) return DatetimeIndex(new_data, freq='infer', name=self.name) - def _add_delta(self, other): + def _maybe_convert_timedelta(self, other): if isinstance(other, (timedelta, np.timedelta64, offsets.Tick, Timedelta)): offset = frequencies.to_offset(self.freq) if isinstance(offset, offsets.Tick): nanos = tslib._delta_to_nanoseconds(other) offset_nanos = tslib._delta_to_nanoseconds(offset) if nanos % offset_nanos == 0: - return self.shift(nanos // offset_nanos) + return nanos // offset_nanos elif isinstance(other, offsets.DateOffset): freqstr = frequencies.get_standard_freq(other) base = frequencies.get_base_alias(freqstr) if base == self.freq: - return self.shift(other.n) + return other.n raise ValueError("Input has different freq from PeriodIndex(freq={0})".format(self.freq)) + def _add_delta(self, other): + ordinal_delta = self._maybe_convert_timedelta(other) + return self.shift(ordinal_delta) + def shift(self, n): """ Specialized shift which produces an PeriodIndex @@ -511,6 +540,11 @@ def shift(self, n): values[mask] = tslib.iNaT return PeriodIndex(data=values, name=self.name, freq=self.freq) + @cache_readonly + def dtype_str(self): + """ return the dtype str of the underlying data """ + return self.inferred_type + @property def inferred_type(self): # b/c data is represented as ints make sure we can't have ambiguous @@ -528,8 +562,8 @@ def get_value(self, series, key): except (KeyError, IndexError): try: asdt, parsed, reso = parse_time_string(key, self.freq) - grp = frequencies._infer_period_group(reso) - freqn = frequencies._period_group(self.freq) + grp = frequencies.Resolution.get_freq_group(reso) + freqn = frequencies.get_freq_group(self.freq) vals = self.values @@ -556,13 +590,13 @@ def get_value(self, series, key): key = Period(key, self.freq).ordinal return _maybe_box(self, self._engine.get_value(s, key), series, key) - def get_indexer(self, target, method=None, limit=None): + def get_indexer(self, target, method=None, limit=None, tolerance=None): if hasattr(target, 'freq') and target.freq != self.freq: raise ValueError('target and index have different freq: ' '(%s, %s)' % (target.freq, self.freq)) - return Index.get_indexer(self, target, method, limit) + return Index.get_indexer(self, target, method, limit, tolerance) - def get_loc(self, key, method=None): + def get_loc(self, key, method=None, tolerance=None): """ Get integer location for requested label @@ -584,7 +618,7 @@ def get_loc(self, key, method=None): key = Period(key, self.freq) try: - return Index.get_loc(self, key.ordinal, method=method) + return Index.get_loc(self, key.ordinal, method, tolerance) except KeyError: raise KeyError(key) @@ -655,8 +689,8 @@ def _get_string_slice(self, key): key, parsed, reso = parse_time_string(key, self.freq) - grp = frequencies._infer_period_group(reso) - freqn = frequencies._period_group(self.freq) + grp = frequencies.Resolution.get_freq_group(reso) + freqn = frequencies.get_freq_group(self.freq) if reso in ['day', 'hour', 'minute', 'second'] and not grp < freqn: raise KeyError(key) @@ -664,6 +698,10 @@ def _get_string_slice(self, key): return slice(self.searchsorted(t1.ordinal, side='left'), self.searchsorted(t2.ordinal, side='right')) + def _convert_tolerance(self, tolerance): + tolerance = DatetimeIndexOpsMixin._convert_tolerance(self, tolerance) + return self._maybe_convert_timedelta(tolerance) + def join(self, other, how='left', level=None, return_indexers=False): """ See Index.join @@ -718,14 +756,18 @@ def __getitem__(self, key): return PeriodIndex(result, name=self.name, freq=self.freq) - def _format_native_types(self, na_rep=u('NaT'), **kwargs): + def _format_native_types(self, na_rep=u('NaT'), date_format=None, **kwargs): values = np.array(list(self), dtype=object) mask = isnull(self.values) values[mask] = na_rep - imask = ~mask - values[imask] = np.array([u('%s') % dt for dt in values[imask]]) + + if date_format: + formatter = lambda dt: dt.strftime(date_format) + else: + formatter = lambda dt: u('%s') % dt + values[imask] = np.array([formatter(dt) for dt in values[imask]]) return values def __array_finalize__(self, obj): diff --git a/pandas/tseries/plotting.py b/pandas/tseries/plotting.py index 9d28fa11f646f..ad27b412cddb9 100644 --- a/pandas/tseries/plotting.py +++ b/pandas/tseries/plotting.py @@ -4,12 +4,16 @@ """ #!!! TODO: Use the fact that axis can have units to simplify the process + +import numpy as np + from matplotlib import pylab from pandas.tseries.period import Period from pandas.tseries.offsets import DateOffset import pandas.tseries.frequencies as frequencies from pandas.tseries.index import DatetimeIndex import pandas.core.common as com +import pandas.compat as compat from pandas.tseries.converter import (TimeSeries_DateLocator, TimeSeries_DateFormatter) @@ -18,7 +22,7 @@ # Plotting functions and monkey patches -def tsplot(series, plotf, **kwargs): +def tsplot(series, plotf, ax=None, **kwargs): """ Plots a Series on the given Matplotlib axes or the current axes @@ -33,46 +37,33 @@ def tsplot(series, plotf, **kwargs): """ # Used inferred freq is possible, need a test case for inferred - if 'ax' in kwargs: - ax = kwargs.pop('ax') - else: + if ax is None: import matplotlib.pyplot as plt ax = plt.gca() - freq = _get_freq(ax, series) - # resample against axes freq if necessary - if freq is None: # pragma: no cover - raise ValueError('Cannot use dynamic axis without frequency info') - else: - # Convert DatetimeIndex to PeriodIndex - if isinstance(series.index, DatetimeIndex): - series = series.to_period(freq=freq) - freq, ax_freq, series = _maybe_resample(series, ax, freq, plotf, - kwargs) + freq, series = _maybe_resample(series, ax, kwargs) # Set ax with freq info _decorate_axes(ax, freq, kwargs) - - # how to make sure ax.clear() flows through? - if not hasattr(ax, '_plot_data'): - ax._plot_data = [] ax._plot_data.append((series, plotf, kwargs)) lines = plotf(ax, series.index._mpl_repr(), series.values, **kwargs) # set date formatter, locators and rescale limits format_dateaxis(ax, ax.freq) + return lines - # x and y coord info - ax.format_coord = lambda t, y: ("t = {0} " - "y = {1:8f}".format(Period(ordinal=int(t), - freq=ax.freq), - y)) - return lines +def _maybe_resample(series, ax, kwargs): + # resample against axes freq if necessary + freq, ax_freq = _get_freq(ax, series) + + if freq is None: # pragma: no cover + raise ValueError('Cannot use dynamic axis without frequency info') + # Convert DatetimeIndex to PeriodIndex + if isinstance(series.index, DatetimeIndex): + series = series.to_period(freq=freq) -def _maybe_resample(series, ax, freq, plotf, kwargs): - ax_freq = _get_ax_freq(ax) if ax_freq is not None and freq != ax_freq: if frequencies.is_superperiod(freq, ax_freq): # upsample input series = series.copy() @@ -84,21 +75,11 @@ def _maybe_resample(series, ax, freq, plotf, kwargs): series = series.resample(ax_freq, how=how).dropna() freq = ax_freq elif frequencies.is_subperiod(freq, ax_freq) or _is_sub(freq, ax_freq): - _upsample_others(ax, freq, plotf, kwargs) + _upsample_others(ax, freq, kwargs) ax_freq = freq else: # pragma: no cover raise ValueError('Incompatible frequency conversion') - return freq, ax_freq, series - - -def _get_ax_freq(ax): - ax_freq = getattr(ax, 'freq', None) - if ax_freq is None: - if hasattr(ax, 'left_ax'): - ax_freq = getattr(ax.left_ax, 'freq', None) - elif hasattr(ax, 'right_ax'): - ax_freq = getattr(ax.right_ax, 'freq', None) - return ax_freq + return freq, series def _is_sub(f1, f2): @@ -111,9 +92,10 @@ def _is_sup(f1, f2): (f2.startswith('W') and frequencies.is_superperiod(f1, 'D'))) -def _upsample_others(ax, freq, plotf, kwargs): +def _upsample_others(ax, freq, kwargs): legend = ax.get_legend() lines, labels = _replot_ax(ax, freq, kwargs) + _replot_ax(ax, freq, kwargs) other_ax = None if hasattr(ax, 'left_ax'): @@ -136,8 +118,11 @@ def _upsample_others(ax, freq, plotf, kwargs): def _replot_ax(ax, freq, kwargs): data = getattr(ax, '_plot_data', None) + + # clear current axes and data ax._plot_data = [] ax.clear() + _decorate_axes(ax, freq, kwargs) lines = [] @@ -147,7 +132,13 @@ def _replot_ax(ax, freq, kwargs): series = series.copy() idx = series.index.asfreq(freq, how='S') series.index = idx - ax._plot_data.append(series) + ax._plot_data.append((series, plotf, kwds)) + + # for tsplot + if isinstance(plotf, compat.string_types): + from pandas.tools.plotting import _plot_klass + plotf = _plot_klass[plotf]._plot + lines.append(plotf(ax, series.index._mpl_repr(), series.values, **kwds)[0]) labels.append(com.pprint_thing(series.name)) @@ -155,6 +146,10 @@ def _replot_ax(ax, freq, kwargs): def _decorate_axes(ax, freq, kwargs): + """Initialize axes for time-series plotting""" + if not hasattr(ax, '_plot_data'): + ax._plot_data = [] + ax.freq = freq xaxis = ax.get_xaxis() xaxis.freq = freq @@ -173,6 +168,11 @@ def _get_freq(ax, series): freq = getattr(series.index, 'inferred_freq', None) ax_freq = getattr(ax, 'freq', None) + if ax_freq is None: + if hasattr(ax, 'left_ax'): + ax_freq = getattr(ax.left_ax, 'freq', None) + elif hasattr(ax, 'right_ax'): + ax_freq = getattr(ax.right_ax, 'freq', None) # use axes freq if no data freq if freq is None: @@ -185,10 +185,76 @@ def _get_freq(ax, series): freq = frequencies.get_base_alias(freq) freq = frequencies.get_period_alias(freq) + return freq, ax_freq + + +def _use_dynamic_x(ax, data): + freq = _get_index_freq(data) + ax_freq = getattr(ax, 'freq', None) + + if freq is None: # convert irregular if axes has freq info + freq = ax_freq + else: # do not use tsplot if irregular was plotted first + if (ax_freq is None) and (len(ax.get_lines()) > 0): + return False + + if freq is None: + return False + + if isinstance(freq, DateOffset): + freq = freq.rule_code + else: + freq = frequencies.get_base_alias(freq) + freq = frequencies.get_period_alias(freq) + if freq is None: + return False + + # hack this for 0.10.1, creating more technical debt...sigh + if isinstance(data.index, DatetimeIndex): + base = frequencies.get_freq(freq) + x = data.index + if (base <= frequencies.FreqGroup.FR_DAY): + return x[:1].is_normalized + return Period(x[0], freq).to_timestamp(tz=x.tz) == x[0] + return True + + +def _get_index_freq(data): + freq = getattr(data.index, 'freq', None) + if freq is None: + freq = getattr(data.index, 'inferred_freq', None) + if freq == 'B': + weekdays = np.unique(data.index.dayofweek) + if (5 in weekdays) or (6 in weekdays): + freq = None return freq +def _maybe_convert_index(ax, data): + # tsplot converts automatically, but don't want to convert index + # over and over for DataFrames + if isinstance(data.index, DatetimeIndex): + freq = getattr(data.index, 'freq', None) + + if freq is None: + freq = getattr(data.index, 'inferred_freq', None) + if isinstance(freq, DateOffset): + freq = freq.rule_code + + if freq is None: + freq = getattr(ax, 'freq', None) + + if freq is None: + raise ValueError('Could not get frequency alias for plotting') + + freq = frequencies.get_base_alias(freq) + freq = frequencies.get_period_alias(freq) + + data = data.to_period(freq=freq) + return data + + # Patch methods for subplot. Only format_dateaxis is currently used. # Do we need the rest for convenience? @@ -219,4 +285,9 @@ def format_dateaxis(subplot, freq): plot_obj=subplot) subplot.xaxis.set_major_formatter(majformatter) subplot.xaxis.set_minor_formatter(minformatter) + + # x and y coord info + subplot.format_coord = lambda t, y: ("t = {0} " + "y = {1:8f}".format(Period(ordinal=int(t), freq=freq), y)) + pylab.draw_if_interactive() diff --git a/pandas/tseries/resample.py b/pandas/tseries/resample.py index 53c1292204f71..0ecdb43895f07 100644 --- a/pandas/tseries/resample.py +++ b/pandas/tseries/resample.py @@ -238,6 +238,10 @@ def _get_time_delta_bins(self, ax): end_stamps = labels + 1 bins = ax.searchsorted(end_stamps, side='left') + # Addresses GH #10530 + if self.base > 0: + labels += type(self.freq)(self.base) + return binner, bins, labels def _get_time_period_bins(self, ax): diff --git a/pandas/tseries/tdi.py b/pandas/tseries/tdi.py index f1871e78e21a1..b0c9d8852f8c9 100644 --- a/pandas/tseries/tdi.py +++ b/pandas/tseries/tdi.py @@ -126,8 +126,8 @@ def _join_i8_wrapper(joinf, **kwargs): _engine_type = _index.TimedeltaEngine - _comparables = ['name','freq'] - _attributes = ['name','freq'] + _comparables = ['name', 'freq'] + _attributes = ['name', 'freq'] _is_numeric_dtype = True freq = None @@ -645,7 +645,7 @@ def get_value_maybe_box(self, series, key): values = self._engine.get_value(_values_from_object(series), key) return _maybe_box(self, values, series, key) - def get_loc(self, key, method=None): + def get_loc(self, key, method=None, tolerance=None): """ Get integer location for requested label @@ -653,12 +653,17 @@ def get_loc(self, key, method=None): ------- loc : int """ + if tolerance is not None: + # try converting tolerance now, so errors don't get swallowed by + # the try/except clauses below + tolerance = self._convert_tolerance(tolerance) + if _is_convertible_to_td(key): key = Timedelta(key) - return Index.get_loc(self, key, method=method) + return Index.get_loc(self, key, method, tolerance) try: - return Index.get_loc(self, key, method=method) + return Index.get_loc(self, key, method, tolerance) except (KeyError, ValueError, TypeError): try: return self._get_string_slice(key) @@ -667,7 +672,7 @@ def get_loc(self, key, method=None): try: stamp = Timedelta(key) - return Index.get_loc(self, stamp, method=method) + return Index.get_loc(self, stamp, method, tolerance) except (KeyError, ValueError): raise KeyError(key) @@ -853,7 +858,7 @@ def delete(self, loc): freq = self.freq else: if com.is_list_like(loc): - loc = lib.maybe_indices_to_slice(com._ensure_int64(np.array(loc))) + loc = lib.maybe_indices_to_slice(com._ensure_int64(np.array(loc)), len(self)) if isinstance(loc, slice) and loc.step in (1, None): if (loc.start in (0, None) or loc.stop in (len(self), None)): freq = self.freq diff --git a/pandas/tseries/tests/test_base.py b/pandas/tseries/tests/test_base.py index fc432d5236f62..3d9e80f351c44 100644 --- a/pandas/tseries/tests/test_base.py +++ b/pandas/tseries/tests/test_base.py @@ -4,10 +4,11 @@ import numpy as np import pandas as pd from pandas.tseries.base import DatetimeIndexOpsMixin -from pandas.util.testing import assertRaisesRegexp, assert_isinstance +from pandas.util.testing import assertRaisesRegexp, assertIsInstance from pandas.tseries.common import is_datetimelike from pandas import (Series, Index, Int64Index, Timestamp, DatetimeIndex, PeriodIndex, TimedeltaIndex, Timedelta, timedelta_range, date_range, Float64Index) +import pandas.tseries.offsets as offsets import pandas.tslib as tslib import nose @@ -297,6 +298,72 @@ def test_nonunique_contains(self): ['2015', '2015', '2016'], ['2015', '2015', '2014'])): tm.assertIn(idx[0], idx) + def test_order(self): + # with freq + idx1 = DatetimeIndex(['2011-01-01', '2011-01-02', '2011-01-03'], freq='D', name='idx') + idx2 = DatetimeIndex(['2011-01-01 09:00', '2011-01-01 10:00', '2011-01-01 11:00'], + freq='H', tz='Asia/Tokyo', name='tzidx') + + for idx in [idx1, idx2]: + ordered = idx.order() + self.assert_index_equal(ordered, idx) + self.assertEqual(ordered.freq, idx.freq) + + ordered = idx.order(ascending=False) + expected = idx[::-1] + self.assert_index_equal(ordered, expected) + self.assertEqual(ordered.freq, expected.freq) + self.assertEqual(ordered.freq.n, -1) + + ordered, indexer = idx.order(return_indexer=True) + self.assert_index_equal(ordered, idx) + self.assert_numpy_array_equal(indexer, np.array([0, 1, 2])) + self.assertEqual(ordered.freq, idx.freq) + + ordered, indexer = idx.order(return_indexer=True, ascending=False) + expected = idx[::-1] + self.assert_index_equal(ordered, expected) + self.assert_numpy_array_equal(indexer, np.array([2, 1, 0])) + self.assertEqual(ordered.freq, expected.freq) + self.assertEqual(ordered.freq.n, -1) + + # without freq + idx1 = DatetimeIndex(['2011-01-01', '2011-01-03', '2011-01-05', + '2011-01-02', '2011-01-01'], name='idx1') + exp1 = DatetimeIndex(['2011-01-01', '2011-01-01', '2011-01-02', + '2011-01-03', '2011-01-05'], name='idx1') + + idx2 = DatetimeIndex(['2011-01-01', '2011-01-03', '2011-01-05', + '2011-01-02', '2011-01-01'], + tz='Asia/Tokyo', name='idx2') + exp2 = DatetimeIndex(['2011-01-01', '2011-01-01', '2011-01-02', + '2011-01-03', '2011-01-05'], + tz='Asia/Tokyo', name='idx2') + + idx3 = DatetimeIndex([pd.NaT, '2011-01-03', '2011-01-05', + '2011-01-02', pd.NaT], name='idx3') + exp3 = DatetimeIndex([pd.NaT, pd.NaT, '2011-01-02', '2011-01-03', + '2011-01-05'], name='idx3') + + for idx, expected in [(idx1, exp1), (idx1, exp1), (idx1, exp1)]: + ordered = idx.order() + self.assert_index_equal(ordered, expected) + self.assertIsNone(ordered.freq) + + ordered = idx.order(ascending=False) + self.assert_index_equal(ordered, expected[::-1]) + self.assertIsNone(ordered.freq) + + ordered, indexer = idx.order(return_indexer=True) + self.assert_index_equal(ordered, expected) + self.assert_numpy_array_equal(indexer, np.array([0, 4, 3, 1, 2])) + self.assertIsNone(ordered.freq) + + ordered, indexer = idx.order(return_indexer=True, ascending=False) + self.assert_index_equal(ordered, expected[::-1]) + self.assert_numpy_array_equal(indexer, np.array([2, 1, 3, 4, 0])) + self.assertIsNone(ordered.freq) + def test_getitem(self): idx1 = pd.date_range('2011-01-01', '2011-01-31', freq='D', name='idx') idx2 = pd.date_range('2011-01-01', '2011-01-31', freq='D', tz='Asia/Tokyo', name='idx') @@ -318,7 +385,7 @@ def test_getitem(self): self.assertEqual(result.freq, expected.freq) result = idx[-20:-5:3] - expected = pd.date_range('2011-01-12', '2011-01-25', freq='3D', + expected = pd.date_range('2011-01-12', '2011-01-24', freq='3D', tz=idx.tz, name='idx') self.assert_index_equal(result, expected) self.assertEqual(result.freq, expected.freq) @@ -330,6 +397,59 @@ def test_getitem(self): self.assert_index_equal(result, expected) self.assertEqual(result.freq, expected.freq) + def test_drop_duplicates_metadata(self): + #GH 10115 + idx = pd.date_range('2011-01-01', '2011-01-31', freq='D', name='idx') + result = idx.drop_duplicates() + self.assert_index_equal(idx, result) + self.assertEqual(idx.freq, result.freq) + + idx_dup = idx.append(idx) + self.assertIsNone(idx_dup.freq) # freq is reset + result = idx_dup.drop_duplicates() + self.assert_index_equal(idx, result) + self.assertIsNone(result.freq) + + def test_take(self): + #GH 10295 + idx1 = pd.date_range('2011-01-01', '2011-01-31', freq='D', name='idx') + idx2 = pd.date_range('2011-01-01', '2011-01-31', freq='D', tz='Asia/Tokyo', name='idx') + + for idx in [idx1, idx2]: + result = idx.take([0]) + self.assertEqual(result, pd.Timestamp('2011-01-01', tz=idx.tz)) + + result = idx.take([0, 1, 2]) + expected = pd.date_range('2011-01-01', '2011-01-03', freq='D', + tz=idx.tz, name='idx') + self.assert_index_equal(result, expected) + self.assertEqual(result.freq, expected.freq) + + result = idx.take([0, 2, 4]) + expected = pd.date_range('2011-01-01', '2011-01-05', freq='2D', + tz=idx.tz, name='idx') + self.assert_index_equal(result, expected) + self.assertEqual(result.freq, expected.freq) + + result = idx.take([7, 4, 1]) + expected = pd.date_range('2011-01-08', '2011-01-02', freq='-3D', + tz=idx.tz, name='idx') + self.assert_index_equal(result, expected) + self.assertEqual(result.freq, expected.freq) + + result = idx.take([3, 2, 5]) + expected = DatetimeIndex(['2011-01-04', '2011-01-03', '2011-01-06'], + freq=None, tz=idx.tz, name='idx') + self.assert_index_equal(result, expected) + self.assertIsNone(result.freq) + + result = idx.take([-3, 2, 5]) + expected = DatetimeIndex(['2011-01-29', '2011-01-03', '2011-01-06'], + freq=None, tz=idx.tz, name='idx') + self.assert_index_equal(result, expected) + self.assertIsNone(result.freq) + + class TestTimedeltaIndexOps(Ops): def setUp(self): @@ -748,7 +868,7 @@ def test_value_counts_unique(self): tm.assert_index_equal(idx.unique(), expected) idx = TimedeltaIndex(['1 days 09:00:00', '1 days 09:00:00', '1 days 09:00:00', - '1 days 08:00:00', '1 days 08:00:00', pd.NaT]) + '1 days 08:00:00', '1 days 08:00:00', pd.NaT]) exp_idx = TimedeltaIndex(['1 days 09:00:00', '1 days 08:00:00']) expected = Series([3, 2], index=exp_idx) @@ -774,6 +894,66 @@ def test_unknown_attribute(self): self.assertNotIn('foo',ts.__dict__.keys()) self.assertRaises(AttributeError,lambda : ts.foo) + def test_order(self): + #GH 10295 + idx1 = TimedeltaIndex(['1 day', '2 day', '3 day'], freq='D', name='idx') + idx2 = TimedeltaIndex(['1 hour', '2 hour', '3 hour'], freq='H', name='idx') + + for idx in [idx1, idx2]: + ordered = idx.order() + self.assert_index_equal(ordered, idx) + self.assertEqual(ordered.freq, idx.freq) + + ordered = idx.order(ascending=False) + expected = idx[::-1] + self.assert_index_equal(ordered, expected) + self.assertEqual(ordered.freq, expected.freq) + self.assertEqual(ordered.freq.n, -1) + + ordered, indexer = idx.order(return_indexer=True) + self.assert_index_equal(ordered, idx) + self.assert_numpy_array_equal(indexer, np.array([0, 1, 2])) + self.assertEqual(ordered.freq, idx.freq) + + ordered, indexer = idx.order(return_indexer=True, ascending=False) + self.assert_index_equal(ordered, idx[::-1]) + self.assertEqual(ordered.freq, expected.freq) + self.assertEqual(ordered.freq.n, -1) + + idx1 = TimedeltaIndex(['1 hour', '3 hour', '5 hour', + '2 hour ', '1 hour'], name='idx1') + exp1 = TimedeltaIndex(['1 hour', '1 hour', '2 hour', + '3 hour', '5 hour'], name='idx1') + + idx2 = TimedeltaIndex(['1 day', '3 day', '5 day', + '2 day', '1 day'], name='idx2') + exp2 = TimedeltaIndex(['1 day', '1 day', '2 day', + '3 day', '5 day'], name='idx2') + + idx3 = TimedeltaIndex([pd.NaT, '3 minute', '5 minute', + '2 minute', pd.NaT], name='idx3') + exp3 = TimedeltaIndex([pd.NaT, pd.NaT, '2 minute', '3 minute', + '5 minute'], name='idx3') + + for idx, expected in [(idx1, exp1), (idx1, exp1), (idx1, exp1)]: + ordered = idx.order() + self.assert_index_equal(ordered, expected) + self.assertIsNone(ordered.freq) + + ordered = idx.order(ascending=False) + self.assert_index_equal(ordered, expected[::-1]) + self.assertIsNone(ordered.freq) + + ordered, indexer = idx.order(return_indexer=True) + self.assert_index_equal(ordered, expected) + self.assert_numpy_array_equal(indexer, np.array([0, 4, 3, 1, 2])) + self.assertIsNone(ordered.freq) + + ordered, indexer = idx.order(return_indexer=True, ascending=False) + self.assert_index_equal(ordered, expected[::-1]) + self.assert_numpy_array_equal(indexer, np.array([2, 1, 3, 4, 0])) + self.assertIsNone(ordered.freq) + def test_getitem(self): idx1 = pd.timedelta_range('1 day', '31 day', freq='D', name='idx') @@ -792,7 +972,7 @@ def test_getitem(self): self.assertEqual(result.freq, expected.freq) result = idx[-20:-5:3] - expected = pd.timedelta_range('12 day', '25 day', freq='3D', name='idx') + expected = pd.timedelta_range('12 day', '24 day', freq='3D', name='idx') self.assert_index_equal(result, expected) self.assertEqual(result.freq, expected.freq) @@ -802,6 +982,56 @@ def test_getitem(self): self.assert_index_equal(result, expected) self.assertEqual(result.freq, expected.freq) + def test_drop_duplicates_metadata(self): + #GH 10115 + idx = pd.timedelta_range('1 day', '31 day', freq='D', name='idx') + result = idx.drop_duplicates() + self.assert_index_equal(idx, result) + self.assertEqual(idx.freq, result.freq) + + idx_dup = idx.append(idx) + self.assertIsNone(idx_dup.freq) # freq is reset + result = idx_dup.drop_duplicates() + self.assert_index_equal(idx, result) + self.assertIsNone(result.freq) + + def test_take(self): + #GH 10295 + idx1 = pd.timedelta_range('1 day', '31 day', freq='D', name='idx') + + for idx in [idx1]: + result = idx.take([0]) + self.assertEqual(result, pd.Timedelta('1 day')) + + result = idx.take([-1]) + self.assertEqual(result, pd.Timedelta('31 day')) + + result = idx.take([0, 1, 2]) + expected = pd.timedelta_range('1 day', '3 day', freq='D', name='idx') + self.assert_index_equal(result, expected) + self.assertEqual(result.freq, expected.freq) + + result = idx.take([0, 2, 4]) + expected = pd.timedelta_range('1 day', '5 day', freq='2D', name='idx') + self.assert_index_equal(result, expected) + self.assertEqual(result.freq, expected.freq) + + result = idx.take([7, 4, 1]) + expected = pd.timedelta_range('8 day', '2 day', freq='-3D', name='idx') + self.assert_index_equal(result, expected) + self.assertEqual(result.freq, expected.freq) + + result = idx.take([3, 2, 5]) + expected = TimedeltaIndex(['4 day', '3 day', '6 day'], name='idx') + self.assert_index_equal(result, expected) + self.assertIsNone(result.freq) + + result = idx.take([-3, 2, 5]) + expected = TimedeltaIndex(['29 day', '3 day', '6 day'], name='idx') + self.assert_index_equal(result, expected) + self.assertIsNone(result.freq) + + class TestPeriodIndexOps(Ops): def setUp(self): @@ -1228,6 +1458,221 @@ def test_value_counts_unique(self): tm.assert_index_equal(idx.unique(), exp_idx) + def test_drop_duplicates_metadata(self): + #GH 10115 + idx = pd.period_range('2011-01-01', '2011-01-31', freq='D', name='idx') + result = idx.drop_duplicates() + self.assert_index_equal(idx, result) + self.assertEqual(idx.freq, result.freq) + + idx_dup = idx.append(idx) # freq will not be reset + result = idx_dup.drop_duplicates() + self.assert_index_equal(idx, result) + self.assertEqual(idx.freq, result.freq) + + def test_order_compat(self): + + def _check_freq(index, expected_index): + if isinstance(index, PeriodIndex): + self.assertEqual(index.freq, expected_index.freq) + + pidx = PeriodIndex(['2011', '2012', '2013'], name='pidx', freq='A') + # for compatibility check + iidx = Index([2011, 2012, 2013], name='idx') + for idx in [pidx, iidx]: + ordered = idx.order() + self.assert_index_equal(ordered, idx) + _check_freq(ordered, idx) + + ordered = idx.order(ascending=False) + self.assert_index_equal(ordered, idx[::-1]) + _check_freq(ordered, idx[::-1]) + + ordered, indexer = idx.order(return_indexer=True) + self.assert_index_equal(ordered, idx) + self.assert_numpy_array_equal(indexer, np.array([0, 1, 2])) + _check_freq(ordered, idx) + + ordered, indexer = idx.order(return_indexer=True, ascending=False) + self.assert_index_equal(ordered, idx[::-1]) + self.assert_numpy_array_equal(indexer, np.array([2, 1, 0])) + _check_freq(ordered, idx[::-1]) + + pidx = PeriodIndex(['2011', '2013', '2015', '2012', '2011'], name='pidx', freq='A') + pexpected = PeriodIndex(['2011', '2011', '2012', '2013', '2015'], name='pidx', freq='A') + # for compatibility check + iidx = Index([2011, 2013, 2015, 2012, 2011], name='idx') + iexpected = Index([2011, 2011, 2012, 2013, 2015], name='idx') + for idx, expected in [(pidx, pexpected), (iidx, iexpected)]: + ordered = idx.order() + self.assert_index_equal(ordered, expected) + _check_freq(ordered, idx) + + ordered = idx.order(ascending=False) + self.assert_index_equal(ordered, expected[::-1]) + _check_freq(ordered, idx) + + ordered, indexer = idx.order(return_indexer=True) + self.assert_index_equal(ordered, expected) + self.assert_numpy_array_equal(indexer, np.array([0, 4, 3, 1, 2])) + _check_freq(ordered, idx) + + ordered, indexer = idx.order(return_indexer=True, ascending=False) + self.assert_index_equal(ordered, expected[::-1]) + self.assert_numpy_array_equal(indexer, np.array([2, 1, 3, 4, 0])) + _check_freq(ordered, idx) + + pidx = PeriodIndex(['2011', '2013', 'NaT', '2011'], name='pidx', freq='D') + + result = pidx.order() + expected = PeriodIndex(['NaT', '2011', '2011', '2013'], name='pidx', freq='D') + self.assert_index_equal(result, expected) + self.assertEqual(result.freq, 'D') + + result = pidx.order(ascending=False) + expected = PeriodIndex(['2013', '2011', '2011', 'NaT'], name='pidx', freq='D') + self.assert_index_equal(result, expected) + self.assertEqual(result.freq, 'D') + + def test_order(self): + idx1 = PeriodIndex(['2011-01-01', '2011-01-02', '2011-01-03'], + freq='D', name='idx') + + for idx in [idx1]: + ordered = idx.order() + self.assert_index_equal(ordered, idx) + self.assertEqual(ordered.freq, idx.freq) + + ordered = idx.order(ascending=False) + expected = idx[::-1] + self.assert_index_equal(ordered, expected) + self.assertEqual(ordered.freq, 'D') + + ordered, indexer = idx.order(return_indexer=True) + self.assert_index_equal(ordered, idx) + self.assert_numpy_array_equal(indexer, np.array([0, 1, 2])) + self.assertEqual(ordered.freq, 'D') + + ordered, indexer = idx.order(return_indexer=True, ascending=False) + expected = idx[::-1] + self.assert_index_equal(ordered, expected) + self.assert_numpy_array_equal(indexer, np.array([2, 1, 0])) + self.assertEqual(ordered.freq, 'D') + + idx1 = PeriodIndex(['2011-01-01', '2011-01-03', '2011-01-05', + '2011-01-02', '2011-01-01'], freq='D', name='idx1') + exp1 = PeriodIndex(['2011-01-01', '2011-01-01', '2011-01-02', + '2011-01-03', '2011-01-05'], freq='D', name='idx1') + + idx2 = PeriodIndex(['2011-01-01', '2011-01-03', '2011-01-05', + '2011-01-02', '2011-01-01'], + freq='D', name='idx2') + exp2 = PeriodIndex(['2011-01-01', '2011-01-01', '2011-01-02', + '2011-01-03', '2011-01-05'], + freq='D', name='idx2') + + idx3 = PeriodIndex([pd.NaT, '2011-01-03', '2011-01-05', + '2011-01-02', pd.NaT], freq='D', name='idx3') + exp3 = PeriodIndex([pd.NaT, pd.NaT, '2011-01-02', '2011-01-03', + '2011-01-05'], freq='D', name='idx3') + + for idx, expected in [(idx1, exp1), (idx1, exp1), (idx1, exp1)]: + ordered = idx.order() + self.assert_index_equal(ordered, expected) + self.assertEqual(ordered.freq, 'D') + + ordered = idx.order(ascending=False) + self.assert_index_equal(ordered, expected[::-1]) + self.assertEqual(ordered.freq, 'D') + + ordered, indexer = idx.order(return_indexer=True) + self.assert_index_equal(ordered, expected) + self.assert_numpy_array_equal(indexer, np.array([0, 4, 3, 1, 2])) + self.assertEqual(ordered.freq, 'D') + + ordered, indexer = idx.order(return_indexer=True, ascending=False) + self.assert_index_equal(ordered, expected[::-1]) + self.assert_numpy_array_equal(indexer, np.array([2, 1, 3, 4, 0])) + self.assertEqual(ordered.freq, 'D') + + def test_getitem(self): + idx1 = pd.period_range('2011-01-01', '2011-01-31', freq='D', name='idx') + + for idx in [idx1]: + result = idx[0] + self.assertEqual(result, pd.Period('2011-01-01', freq='D')) + + result = idx[-1] + self.assertEqual(result, pd.Period('2011-01-31', freq='D')) + + result = idx[0:5] + expected = pd.period_range('2011-01-01', '2011-01-05', freq='D', + name='idx') + self.assert_index_equal(result, expected) + self.assertEqual(result.freq, expected.freq) + + result = idx[0:10:2] + expected = pd.PeriodIndex(['2011-01-01', '2011-01-03', '2011-01-05', + '2011-01-07', '2011-01-09'], + freq='D', name='idx') + self.assert_index_equal(result, expected) + self.assertEqual(result.freq, expected.freq) + + result = idx[-20:-5:3] + expected = pd.PeriodIndex(['2011-01-12', '2011-01-15', '2011-01-18', + '2011-01-21', '2011-01-24'], + freq='D', name='idx') + self.assert_index_equal(result, expected) + self.assertEqual(result.freq, expected.freq) + + result = idx[4::-1] + expected = PeriodIndex(['2011-01-05', '2011-01-04', '2011-01-03', + '2011-01-02', '2011-01-01'], + freq='D', name='idx') + self.assert_index_equal(result, expected) + self.assertEqual(result.freq, expected.freq) + + def test_take(self): + #GH 10295 + idx1 = pd.period_range('2011-01-01', '2011-01-31', freq='D', name='idx') + + for idx in [idx1]: + result = idx.take([0]) + self.assertEqual(result, pd.Period('2011-01-01', freq='D')) + + result = idx.take([5]) + self.assertEqual(result, pd.Period('2011-01-06', freq='D')) + + result = idx.take([0, 1, 2]) + expected = pd.period_range('2011-01-01', '2011-01-03', freq='D', + name='idx') + self.assert_index_equal(result, expected) + self.assertEqual(result.freq, expected.freq) + + result = idx.take([0, 2, 4]) + expected = pd.PeriodIndex(['2011-01-01', '2011-01-03', '2011-01-05'], + freq='D', name='idx') + self.assert_index_equal(result, expected) + self.assertEqual(result.freq, expected.freq) + + result = idx.take([7, 4, 1]) + expected = pd.PeriodIndex(['2011-01-08', '2011-01-05', '2011-01-02'], + freq='D', name='idx') + self.assert_index_equal(result, expected) + self.assertEqual(result.freq, expected.freq) + + result = idx.take([3, 2, 5]) + expected = PeriodIndex(['2011-01-04', '2011-01-03', '2011-01-06'], + freq='D', name='idx') + self.assert_index_equal(result, expected) + self.assertEqual(result.freq, expected.freq) + + result = idx.take([-3, 2, 5]) + expected = PeriodIndex(['2011-01-29', '2011-01-03', '2011-01-06'], + freq='D', name='idx') + self.assert_index_equal(result, expected) + self.assertEqual(result.freq, expected.freq) + if __name__ == '__main__': import nose diff --git a/pandas/tseries/tests/test_daterange.py b/pandas/tseries/tests/test_daterange.py index 69b1d84670d45..86e0f7162c545 100644 --- a/pandas/tseries/tests/test_daterange.py +++ b/pandas/tseries/tests/test_daterange.py @@ -1,7 +1,6 @@ from datetime import datetime from pandas.compat import range import nose -import sys import numpy as np from pandas.core.index import Index @@ -16,11 +15,6 @@ import pandas.util.testing as tm -def _skip_if_windows_python_3(): - if sys.version_info > (3,) and sys.platform == 'win32': - raise nose.SkipTest("not used on python 3/win32") - - def eq_gen_range(kwargs, expected): rng = generate_range(**kwargs) assert(np.array_equal(list(rng), expected)) @@ -57,6 +51,26 @@ def test_3(self): end=datetime(2008, 1, 6)), []) + def test_precision_finer_than_offset(self): + # GH 9907 + result1 = DatetimeIndex(start='2015-04-15 00:00:03', + end='2016-04-22 00:00:00', freq='Q') + result2 = DatetimeIndex(start='2015-04-15 00:00:03', + end='2015-06-22 00:00:04', freq='W') + expected1_list = ['2015-06-30 00:00:03', '2015-09-30 00:00:03', + '2015-12-31 00:00:03', '2016-03-31 00:00:03'] + expected2_list = ['2015-04-19 00:00:03', '2015-04-26 00:00:03', + '2015-05-03 00:00:03', '2015-05-10 00:00:03', + '2015-05-17 00:00:03', '2015-05-24 00:00:03', + '2015-05-31 00:00:03', '2015-06-07 00:00:03', + '2015-06-14 00:00:03', '2015-06-21 00:00:03'] + expected1 = DatetimeIndex(expected1_list, dtype='datetime64[ns]', + freq='Q-DEC', tz=None) + expected2 = DatetimeIndex(expected2_list, dtype='datetime64[ns]', + freq='W-SUN', tz=None) + self.assertTrue(result1.equals(expected1)) + self.assertTrue(result2.equals(expected2)) + class TestDateRange(tm.TestCase): @@ -138,7 +152,7 @@ def test_getitem(self): fancy_indexed = self.rng[[4, 3, 2, 1, 0]] self.assertEqual(len(fancy_indexed), 5) - tm.assert_isinstance(fancy_indexed, DatetimeIndex) + tm.assertIsInstance(fancy_indexed, DatetimeIndex) self.assertIsNone(fancy_indexed.freq) # 32-bit vs. 64-bit platforms @@ -176,21 +190,21 @@ def test_union(self): right = self.rng[5:10] the_union = left.union(right) - tm.assert_isinstance(the_union, DatetimeIndex) + tm.assertIsInstance(the_union, DatetimeIndex) # non-overlapping, gap in middle left = self.rng[:5] right = self.rng[10:] the_union = left.union(right) - tm.assert_isinstance(the_union, Index) + tm.assertIsInstance(the_union, Index) # non-overlapping, no gap left = self.rng[:5] right = self.rng[5:10] the_union = left.union(right) - tm.assert_isinstance(the_union, DatetimeIndex) + tm.assertIsInstance(the_union, DatetimeIndex) # order does not matter self.assert_numpy_array_equal(right.union(left), the_union) @@ -199,7 +213,7 @@ def test_union(self): rng = date_range(START, END, freq=datetools.bmonthEnd) the_union = self.rng.union(rng) - tm.assert_isinstance(the_union, DatetimeIndex) + tm.assertIsInstance(the_union, DatetimeIndex) def test_outer_join(self): # should just behave as union @@ -209,14 +223,14 @@ def test_outer_join(self): right = self.rng[5:10] the_join = left.join(right, how='outer') - tm.assert_isinstance(the_join, DatetimeIndex) + tm.assertIsInstance(the_join, DatetimeIndex) # non-overlapping, gap in middle left = self.rng[:5] right = self.rng[10:] the_join = left.join(right, how='outer') - tm.assert_isinstance(the_join, DatetimeIndex) + tm.assertIsInstance(the_join, DatetimeIndex) self.assertIsNone(the_join.freq) # non-overlapping, no gap @@ -224,13 +238,13 @@ def test_outer_join(self): right = self.rng[5:10] the_join = left.join(right, how='outer') - tm.assert_isinstance(the_join, DatetimeIndex) + tm.assertIsInstance(the_join, DatetimeIndex) # overlapping, but different offset rng = date_range(START, END, freq=datetools.bmonthEnd) the_join = self.rng.join(rng, how='outer') - tm.assert_isinstance(the_join, DatetimeIndex) + tm.assertIsInstance(the_join, DatetimeIndex) self.assertIsNone(the_join.freq) def test_union_not_cacheable(self): @@ -253,7 +267,7 @@ def test_intersection(self): the_int = rng1.intersection(rng2) expected = rng[10:25] self.assertTrue(the_int.equals(expected)) - tm.assert_isinstance(the_int, DatetimeIndex) + tm.assertIsInstance(the_int, DatetimeIndex) self.assertEqual(the_int.offset, rng.offset) the_int = rng1.intersection(rng2.view(DatetimeIndex)) @@ -333,7 +347,7 @@ def test_daterange_bug_456(self): rng2.offset = datetools.BDay() result = rng1.union(rng2) - tm.assert_isinstance(result, DatetimeIndex) + tm.assertIsInstance(result, DatetimeIndex) def test_error_with_zero_monthends(self): self.assertRaises(ValueError, date_range, '1/1/2000', '1/1/2001', @@ -439,7 +453,7 @@ def test_month_range_union_tz_pytz(self): early_dr.union(late_dr) def test_month_range_union_tz_dateutil(self): - _skip_if_windows_python_3() + tm._skip_if_windows_python_3() tm._skip_if_no_dateutil() from pandas.tslib import _dateutil_gettz as timezone tz = timezone('US/Eastern') @@ -535,7 +549,7 @@ def test_getitem(self): fancy_indexed = self.rng[[4, 3, 2, 1, 0]] self.assertEqual(len(fancy_indexed), 5) - tm.assert_isinstance(fancy_indexed, DatetimeIndex) + tm.assertIsInstance(fancy_indexed, DatetimeIndex) self.assertIsNone(fancy_indexed.freq) # 32-bit vs. 64-bit platforms @@ -573,21 +587,21 @@ def test_union(self): right = self.rng[5:10] the_union = left.union(right) - tm.assert_isinstance(the_union, DatetimeIndex) + tm.assertIsInstance(the_union, DatetimeIndex) # non-overlapping, gap in middle left = self.rng[:5] right = self.rng[10:] the_union = left.union(right) - tm.assert_isinstance(the_union, Index) + tm.assertIsInstance(the_union, Index) # non-overlapping, no gap left = self.rng[:5] right = self.rng[5:10] the_union = left.union(right) - tm.assert_isinstance(the_union, DatetimeIndex) + tm.assertIsInstance(the_union, DatetimeIndex) # order does not matter self.assert_numpy_array_equal(right.union(left), the_union) @@ -596,7 +610,7 @@ def test_union(self): rng = date_range(START, END, freq=datetools.bmonthEnd) the_union = self.rng.union(rng) - tm.assert_isinstance(the_union, DatetimeIndex) + tm.assertIsInstance(the_union, DatetimeIndex) def test_outer_join(self): # should just behave as union @@ -606,14 +620,14 @@ def test_outer_join(self): right = self.rng[5:10] the_join = left.join(right, how='outer') - tm.assert_isinstance(the_join, DatetimeIndex) + tm.assertIsInstance(the_join, DatetimeIndex) # non-overlapping, gap in middle left = self.rng[:5] right = self.rng[10:] the_join = left.join(right, how='outer') - tm.assert_isinstance(the_join, DatetimeIndex) + tm.assertIsInstance(the_join, DatetimeIndex) self.assertIsNone(the_join.freq) # non-overlapping, no gap @@ -621,13 +635,13 @@ def test_outer_join(self): right = self.rng[5:10] the_join = left.join(right, how='outer') - tm.assert_isinstance(the_join, DatetimeIndex) + tm.assertIsInstance(the_join, DatetimeIndex) # overlapping, but different offset rng = date_range(START, END, freq=datetools.bmonthEnd) the_join = self.rng.join(rng, how='outer') - tm.assert_isinstance(the_join, DatetimeIndex) + tm.assertIsInstance(the_join, DatetimeIndex) self.assertIsNone(the_join.freq) def test_intersection_bug(self): @@ -682,7 +696,7 @@ def test_daterange_bug_456(self): rng2.offset = datetools.CDay() result = rng1.union(rng2) - tm.assert_isinstance(result, DatetimeIndex) + tm.assertIsInstance(result, DatetimeIndex) def test_cdaterange(self): rng = cdate_range('2013-05-01', periods=3) diff --git a/pandas/tseries/tests/test_frequencies.py b/pandas/tseries/tests/test_frequencies.py index 823c762c692e5..29152551f5ddf 100644 --- a/pandas/tseries/tests/test_frequencies.py +++ b/pandas/tseries/tests/test_frequencies.py @@ -132,6 +132,117 @@ def test_anchored_shortcuts(): expected = frequencies.to_offset('Q-DEC') assert(result == expected) +class TestFrequencyCode(tm.TestCase): + + def test_freq_code(self): + self.assertEqual(frequencies.get_freq('A'), 1000) + self.assertEqual(frequencies.get_freq('3A'), 1000) + self.assertEqual(frequencies.get_freq('-1A'), 1000) + + self.assertEqual(frequencies.get_freq('W'), 4000) + self.assertEqual(frequencies.get_freq('W-MON'), 4001) + self.assertEqual(frequencies.get_freq('W-FRI'), 4005) + + for freqstr, code in compat.iteritems(frequencies._period_code_map): + result = frequencies.get_freq(freqstr) + self.assertEqual(result, code) + + result = frequencies.get_freq_group(freqstr) + self.assertEqual(result, code // 1000 * 1000) + + result = frequencies.get_freq_group(code) + self.assertEqual(result, code // 1000 * 1000) + + def test_get_to_timestamp_base(self): + tsb = frequencies.get_to_timestamp_base + + self.assertEqual(tsb(frequencies.get_freq_code('D')[0]), + frequencies.get_freq_code('D')[0]) + self.assertEqual(tsb(frequencies.get_freq_code('W')[0]), + frequencies.get_freq_code('D')[0]) + self.assertEqual(tsb(frequencies.get_freq_code('M')[0]), + frequencies.get_freq_code('D')[0]) + + self.assertEqual(tsb(frequencies.get_freq_code('S')[0]), + frequencies.get_freq_code('S')[0]) + self.assertEqual(tsb(frequencies.get_freq_code('T')[0]), + frequencies.get_freq_code('S')[0]) + self.assertEqual(tsb(frequencies.get_freq_code('H')[0]), + frequencies.get_freq_code('S')[0]) + + + def test_freq_to_reso(self): + Reso = frequencies.Resolution + + self.assertEqual(Reso.get_str_from_freq('A'), 'year') + self.assertEqual(Reso.get_str_from_freq('Q'), 'quarter') + self.assertEqual(Reso.get_str_from_freq('M'), 'month') + self.assertEqual(Reso.get_str_from_freq('D'), 'day') + self.assertEqual(Reso.get_str_from_freq('H'), 'hour') + self.assertEqual(Reso.get_str_from_freq('T'), 'minute') + self.assertEqual(Reso.get_str_from_freq('S'), 'second') + self.assertEqual(Reso.get_str_from_freq('L'), 'millisecond') + self.assertEqual(Reso.get_str_from_freq('U'), 'microsecond') + self.assertEqual(Reso.get_str_from_freq('N'), 'nanosecond') + + for freq in ['A', 'Q', 'M', 'D', 'H', 'T', 'S', 'L', 'U', 'N']: + # check roundtrip + result = Reso.get_freq(Reso.get_str_from_freq(freq)) + self.assertEqual(freq, result) + + for freq in ['D', 'H', 'T', 'S', 'L', 'U']: + result = Reso.get_freq(Reso.get_str(Reso.get_reso_from_freq(freq))) + self.assertEqual(freq, result) + + def test_get_freq_code(self): + # freqstr + self.assertEqual(frequencies.get_freq_code('A'), + (frequencies.get_freq('A'), 1)) + self.assertEqual(frequencies.get_freq_code('3D'), + (frequencies.get_freq('D'), 3)) + self.assertEqual(frequencies.get_freq_code('-2M'), + (frequencies.get_freq('M'), -2)) + + # tuple + self.assertEqual(frequencies.get_freq_code(('D', 1)), + (frequencies.get_freq('D'), 1)) + self.assertEqual(frequencies.get_freq_code(('A', 3)), + (frequencies.get_freq('A'), 3)) + self.assertEqual(frequencies.get_freq_code(('M', -2)), + (frequencies.get_freq('M'), -2)) + # numeric tuple + self.assertEqual(frequencies.get_freq_code((1000, 1)), (1000, 1)) + + # offsets + self.assertEqual(frequencies.get_freq_code(offsets.Day()), + (frequencies.get_freq('D'), 1)) + self.assertEqual(frequencies.get_freq_code(offsets.Day(3)), + (frequencies.get_freq('D'), 3)) + self.assertEqual(frequencies.get_freq_code(offsets.Day(-2)), + (frequencies.get_freq('D'), -2)) + + self.assertEqual(frequencies.get_freq_code(offsets.MonthEnd()), + (frequencies.get_freq('M'), 1)) + self.assertEqual(frequencies.get_freq_code(offsets.MonthEnd(3)), + (frequencies.get_freq('M'), 3)) + self.assertEqual(frequencies.get_freq_code(offsets.MonthEnd(-2)), + (frequencies.get_freq('M'), -2)) + + self.assertEqual(frequencies.get_freq_code(offsets.Week()), + (frequencies.get_freq('W'), 1)) + self.assertEqual(frequencies.get_freq_code(offsets.Week(3)), + (frequencies.get_freq('W'), 3)) + self.assertEqual(frequencies.get_freq_code(offsets.Week(-2)), + (frequencies.get_freq('W'), -2)) + + # monday is weekday=0 + self.assertEqual(frequencies.get_freq_code(offsets.Week(weekday=1)), + (frequencies.get_freq('W-TUE'), 1)) + self.assertEqual(frequencies.get_freq_code(offsets.Week(3, weekday=0)), + (frequencies.get_freq('W-MON'), 3)) + self.assertEqual(frequencies.get_freq_code(offsets.Week(-2, weekday=4)), + (frequencies.get_freq('W-FRI'), -2)) + _dti = DatetimeIndex @@ -333,7 +444,6 @@ def test_infer_freq_tz_transition(self): for date_pair in date_pairs: for freq in freqs: idx = date_range(date_pair[0], date_pair[1], freq=freq, tz=tz) - print(idx) self.assertEqual(idx.inferred_freq, freq) index = date_range("2013-11-03", periods=5, freq="3H").tz_localize("America/Chicago") diff --git a/pandas/tseries/tests/test_offsets.py b/pandas/tseries/tests/test_offsets.py index a051560617604..d364206017c7e 100644 --- a/pandas/tseries/tests/test_offsets.py +++ b/pandas/tseries/tests/test_offsets.py @@ -19,7 +19,7 @@ get_offset, get_offset_name, get_standard_freq) from pandas import Series -from pandas.tseries.frequencies import _offset_map +from pandas.tseries.frequencies import _offset_map, get_freq_code, _get_freq_str from pandas.tseries.index import _to_m8, DatetimeIndex, _daterange_cache, date_range from pandas.tseries.tools import parse_time_string, DateParseError import pandas.tseries.offsets as offsets @@ -68,7 +68,7 @@ def test_to_datetime1(): # unparseable s = 'Month 1, 1999' - assert to_datetime(s) == s + assert to_datetime(s, errors='ignore') == s def test_normalize_date(): @@ -79,7 +79,7 @@ def test_normalize_date(): def test_to_m8(): valb = datetime(2007, 10, 1) valu = _to_m8(valb) - tm.assert_isinstance(valu, np.datetime64) + tm.assertIsInstance(valu, np.datetime64) # assert valu == np.datetime64(datetime(2007,10,1)) # def test_datetime64_box(): @@ -211,6 +211,27 @@ def test_return_type(self): self.assertTrue(NaT - offset is NaT) self.assertTrue((-offset).apply(NaT) is NaT) + def test_offset_n(self): + for offset_klass in self.offset_types: + offset = self._get_offset(offset_klass) + self.assertEqual(offset.n, 1) + + neg_offset = offset * -1 + self.assertEqual(neg_offset.n, -1) + + mul_offset = offset * 3 + self.assertEqual(mul_offset.n, 3) + + def test_offset_freqstr(self): + for offset_klass in self.offset_types: + offset = self._get_offset(offset_klass) + + freqstr = offset.freqstr + if freqstr not in ('', "", + 'LWOM-SAT', ): + code = get_offset(freqstr) + self.assertEqual(offset.rule_code, code) + def _check_offsetfunc_works(self, offset, funcname, dt, expected, normalize=False): offset_s = self._get_offset(offset, normalize=normalize) @@ -3695,6 +3716,12 @@ def test_rule_code(self): self.assertEqual(alias, get_offset(alias).rule_code) self.assertEqual(alias, (get_offset(alias) * 5).rule_code) + lst = ['M', 'D', 'B', 'H', 'T', 'S', 'L', 'U'] + for k in lst: + code, stride = get_freq_code('3' + k) + self.assertTrue(isinstance(code, int)) + self.assertEqual(stride, 3) + self.assertEqual(k, _get_freq_str(code)) def test_apply_ticks(): result = offsets.Hour(3).apply(offsets.Hour(4)) diff --git a/pandas/tseries/tests/test_period.py b/pandas/tseries/tests/test_period.py index 0218af63ca7d6..b78b5d5ad71d7 100644 --- a/pandas/tseries/tests/test_period.py +++ b/pandas/tseries/tests/test_period.py @@ -6,6 +6,9 @@ """ +import pickle +import os + from datetime import datetime, date, timedelta from numpy.ma.testutils import assert_equal @@ -30,7 +33,6 @@ assertRaisesRegexp) import pandas.util.testing as tm from pandas import compat -from numpy.testing import assert_array_equal class TestPeriodProperties(tm.TestCase): @@ -282,7 +284,7 @@ def test_strftime(self): p = Period('2000-1-1 12:34:12', freq='S') res = p.strftime('%Y-%m-%d %H:%M:%S') self.assertEqual(res, '2000-01-01 12:34:12') - tm.assert_isinstance(res, compat.text_type) # GH3363 + tm.assertIsInstance(res, compat.text_type) # GH3363 def test_sub_delta(self): left, right = Period('2011', freq='A'), Period('2007', freq='A') @@ -1192,7 +1194,7 @@ def test_hash_error(self): def test_make_time_series(self): index = PeriodIndex(freq='A', start='1/1/2001', end='12/1/2009') series = Series(1, index=index) - tm.assert_isinstance(series, TimeSeries) + tm.assertIsInstance(series, TimeSeries) def test_astype(self): idx = period_range('1990', '2009', freq='A') @@ -1350,7 +1352,7 @@ def test_getitem_ndim2(self): result = idx[:, None] # MPL kludge - tm.assert_isinstance(result, PeriodIndex) + tm.assertIsInstance(result, PeriodIndex) def test_getitem_partial(self): rng = period_range('2007-01', periods=50, freq='M') @@ -1442,7 +1444,7 @@ def test_periods_number_check(self): def test_tolist(self): index = PeriodIndex(freq='A', start='1/1/2001', end='12/1/2009') rs = index.tolist() - [tm.assert_isinstance(x, Period) for x in rs] + [tm.assertIsInstance(x, Period) for x in rs] recon = PeriodIndex(rs) self.assertTrue(index.equals(recon)) @@ -1562,7 +1564,7 @@ def test_frame_setitem(self): self.assertTrue(rs.equals(rng)) rs = df.reset_index().set_index('index') - tm.assert_isinstance(rs.index, PeriodIndex) + tm.assertIsInstance(rs.index, PeriodIndex) self.assertTrue(rs.index.equals(rng)) def test_period_set_index_reindex(self): @@ -1979,7 +1981,7 @@ def test_negative_ordinals(self): idx1 = PeriodIndex(ordinal=[-1, 0, 1], freq='A') idx2 = PeriodIndex(ordinal=np.array([-1, 0, 1]), freq='A') - assert_array_equal(idx1,idx2) + tm.assert_numpy_array_equal(idx1,idx2) def test_dti_to_period(self): dti = DatetimeIndex(start='1/1/2005', end='12/1/2005', freq='M') @@ -2212,7 +2214,7 @@ def test_iteration(self): index = PeriodIndex(start='1/1/10', periods=4, freq='B') result = list(index) - tm.assert_isinstance(result[0], Period) + tm.assertIsInstance(result[0], Period) self.assertEqual(result[0].freq, index.freq) def test_take(self): @@ -2226,7 +2228,7 @@ def test_take(self): for taken in [taken1, taken2]: self.assertTrue(taken.equals(expected)) - tm.assert_isinstance(taken, PeriodIndex) + tm.assertIsInstance(taken, PeriodIndex) self.assertEqual(taken.freq, index.freq) self.assertEqual(taken.name, expected.name) @@ -2236,7 +2238,7 @@ def test_joins(self): for kind in ['inner', 'outer', 'left', 'right']: joined = index.join(index[:-5], how=kind) - tm.assert_isinstance(joined, PeriodIndex) + tm.assertIsInstance(joined, PeriodIndex) self.assertEqual(joined.freq, index.freq) def test_join_self(self): @@ -2393,7 +2395,7 @@ def test_map(self): result = index.map(lambda x: x.ordinal) exp = [x.ordinal for x in index] - assert_array_equal(result, exp) + tm.assert_numpy_array_equal(result, exp) def test_map_with_string_constructor(self): raw = [2005, 2007, 2009] @@ -2409,7 +2411,7 @@ def test_map_with_string_constructor(self): res = index.map(t) # should return an array - tm.assert_isinstance(res, np.ndarray) + tm.assertIsInstance(res, np.ndarray) # preserve element types self.assertTrue(all(isinstance(resi, t) for resi in res)) @@ -2418,14 +2420,14 @@ def test_map_with_string_constructor(self): self.assertEqual(res.dtype, np.dtype('object').type) # lastly, values should compare equal - assert_array_equal(res, expected) + tm.assert_numpy_array_equal(res, expected) def test_convert_array_of_periods(self): rng = period_range('1/1/2000', periods=20, freq='D') periods = list(rng) result = pd.Index(periods) - tm.assert_isinstance(result, PeriodIndex) + tm.assertIsInstance(result, PeriodIndex) def test_with_multi_index(self): # #1705 @@ -2434,9 +2436,9 @@ def test_with_multi_index(self): s = Series([0, 1, 2, 3], index_as_arrays) - tm.assert_isinstance(s.index.levels[0], PeriodIndex) + tm.assertIsInstance(s.index.levels[0], PeriodIndex) - tm.assert_isinstance(s.index.values[0][0], Period) + tm.assertIsInstance(s.index.values[0][0], Period) def test_to_datetime_1703(self): index = period_range('1/1/2012', periods=4, freq='D') @@ -2467,7 +2469,7 @@ def test_append_concat(self): # drops index result = pd.concat([s1, s2]) - tm.assert_isinstance(result.index, PeriodIndex) + tm.assertIsInstance(result.index, PeriodIndex) self.assertEqual(result.index[0], s1.index[0]) def test_pickle_freq(self): @@ -2537,6 +2539,14 @@ def test_searchsorted(self): ValueError, 'Different period frequency: H', lambda: pidx.searchsorted(pd.Period('2014-01-01', freq='H'))) + def test_round_trip(self): + + import pickle + p = Period('2000Q1') + + new_p = self.round_trip_pickle(p) + self.assertEqual(new_p, p) + def _permute(obj): return obj.take(np.random.permutation(len(obj))) diff --git a/pandas/tseries/tests/test_plotting.py b/pandas/tseries/tests/test_plotting.py index c5ed8a1ac3e31..39736eef79295 100644 --- a/pandas/tseries/tests/test_plotting.py +++ b/pandas/tseries/tests/test_plotting.py @@ -5,7 +5,6 @@ import numpy as np from numpy.testing.decorators import slow -from numpy.testing import assert_array_equal from pandas import Index, Series, DataFrame @@ -105,6 +104,12 @@ def test_tsplot(self): for s in self.datetime_ser: _check_plot_works(f, s.index.freq.rule_code, ax=ax, series=s) + for s in self.period_ser: + _check_plot_works(s.plot, ax=ax) + + for s in self.datetime_ser: + _check_plot_works(s.plot, ax=ax) + ax = ts.plot(style='k') self.assertEqual((0., 0., 0.), ax.get_lines()[0].get_color()) @@ -151,6 +156,15 @@ def check_format_of_first_point(ax, expected_string): # note this is added to the annual plot already in existence, and changes its freq field daily = Series(1, index=date_range('2014-01-01', periods=3, freq='D')) check_format_of_first_point(daily.plot(), 't = 2014-01-01 y = 1.000000') + tm.close() + + # tsplot + import matplotlib.pyplot as plt + from pandas.tseries.plotting import tsplot + tsplot(annual, plt.Axes.plot) + check_format_of_first_point(plt.gca(), 't = 2014 y = 1.000000') + tsplot(daily, plt.Axes.plot) + check_format_of_first_point(plt.gca(), 't = 2014-01-01 y = 1.000000') @slow def test_line_plot_period_series(self): @@ -306,7 +320,7 @@ def test_dataframe(self): bts = DataFrame({'a': tm.makeTimeSeries()}) ax = bts.plot() idx = ax.get_lines()[0].get_xdata() - assert_array_equal(bts.index.to_period(), PeriodIndex(idx)) + tm.assert_numpy_array_equal(bts.index.to_period(), PeriodIndex(idx)) @slow def test_axis_limits(self): @@ -472,7 +486,7 @@ def test_gaps(self): self.assertEqual(len(lines), 1) l = lines[0] data = l.get_xydata() - tm.assert_isinstance(data, np.ma.core.MaskedArray) + tm.assertIsInstance(data, np.ma.core.MaskedArray) mask = data.mask self.assertTrue(mask[5:25, 1].all()) plt.close(ax.get_figure()) @@ -486,7 +500,7 @@ def test_gaps(self): self.assertEqual(len(lines), 1) l = lines[0] data = l.get_xydata() - tm.assert_isinstance(data, np.ma.core.MaskedArray) + tm.assertIsInstance(data, np.ma.core.MaskedArray) mask = data.mask self.assertTrue(mask[2:5, 1].all()) plt.close(ax.get_figure()) @@ -500,7 +514,7 @@ def test_gaps(self): self.assertEqual(len(lines), 1) l = lines[0] data = l.get_xydata() - tm.assert_isinstance(data, np.ma.core.MaskedArray) + tm.assertIsInstance(data, np.ma.core.MaskedArray) mask = data.mask self.assertTrue(mask[2:5, 1].all()) @@ -518,7 +532,7 @@ def test_gap_upsample(self): self.assertEqual(len(ax.right_ax.get_lines()), 1) l = lines[0] data = l.get_xydata() - tm.assert_isinstance(data, np.ma.core.MaskedArray) + tm.assertIsInstance(data, np.ma.core.MaskedArray) mask = data.mask self.assertTrue(mask[5:25, 1].all()) @@ -642,9 +656,9 @@ def test_mixed_freq_irregular_first(self): self.assertFalse(hasattr(ax, 'freq')) lines = ax.get_lines() x1 = lines[0].get_xdata() - assert_array_equal(x1, s2.index.asobject.values) + tm.assert_numpy_array_equal(x1, s2.index.asobject.values) x2 = lines[1].get_xdata() - assert_array_equal(x2, s1.index.asobject.values) + tm.assert_numpy_array_equal(x2, s1.index.asobject.values) def test_mixed_freq_regular_first_df(self): # GH 9852 @@ -674,9 +688,9 @@ def test_mixed_freq_irregular_first_df(self): self.assertFalse(hasattr(ax, 'freq')) lines = ax.get_lines() x1 = lines[0].get_xdata() - assert_array_equal(x1, s2.index.asobject.values) + tm.assert_numpy_array_equal(x1, s2.index.asobject.values) x2 = lines[1].get_xdata() - assert_array_equal(x2, s1.index.asobject.values) + tm.assert_numpy_array_equal(x2, s1.index.asobject.values) def test_mixed_freq_hf_first(self): idxh = date_range('1/1/1999', periods=365, freq='D') @@ -746,6 +760,15 @@ def test_to_weekly_resampling(self): for l in ax.get_lines(): self.assertTrue(PeriodIndex(data=l.get_xdata()).freq.startswith('W')) + # tsplot + from pandas.tseries.plotting import tsplot + import matplotlib.pyplot as plt + + tsplot(high, plt.Axes.plot) + lines = tsplot(low, plt.Axes.plot) + for l in lines: + self.assertTrue(PeriodIndex(data=l.get_xdata()).freq.startswith('W')) + @slow def test_from_weekly_resampling(self): idxh = date_range('1/1/1999', periods=52, freq='W') @@ -760,7 +783,22 @@ def test_from_weekly_resampling(self): 1553, 1558, 1562]) for l in ax.get_lines(): self.assertTrue(PeriodIndex(data=l.get_xdata()).freq.startswith('W')) + xdata = l.get_xdata(orig=False) + if len(xdata) == 12: # idxl lines + self.assert_numpy_array_equal(xdata, expected_l) + else: + self.assert_numpy_array_equal(xdata, expected_h) + tm.close() + + # tsplot + from pandas.tseries.plotting import tsplot + import matplotlib.pyplot as plt + + tsplot(low, plt.Axes.plot) + lines = tsplot(high, plt.Axes.plot) + for l in lines: + self.assertTrue(PeriodIndex(data=l.get_xdata()).freq.startswith('W')) xdata = l.get_xdata(orig=False) if len(xdata) == 12: # idxl lines self.assert_numpy_array_equal(xdata, expected_l) @@ -1044,7 +1082,7 @@ def test_ax_plot(self): fig = plt.figure() ax = fig.add_subplot(111) lines = ax.plot(x, y, label='Y') - assert_array_equal(DatetimeIndex(lines[0].get_xdata()), x) + tm.assert_numpy_array_equal(DatetimeIndex(lines[0].get_xdata()), x) @slow def test_mpl_nopandas(self): @@ -1063,9 +1101,9 @@ def test_mpl_nopandas(self): ax.plot_date([x.toordinal() for x in dates], values2, **kw) line1, line2 = ax.get_lines() - assert_array_equal(np.array([x.toordinal() for x in dates]), + tm.assert_numpy_array_equal(np.array([x.toordinal() for x in dates]), line1.get_xydata()[:, 0]) - assert_array_equal(np.array([x.toordinal() for x in dates]), + tm.assert_numpy_array_equal(np.array([x.toordinal() for x in dates]), line2.get_xydata()[:, 0]) @slow diff --git a/pandas/tseries/tests/test_resample.py b/pandas/tseries/tests/test_resample.py index 202ccb9438db5..4b3085dc8259f 100644 --- a/pandas/tseries/tests/test_resample.py +++ b/pandas/tseries/tests/test_resample.py @@ -9,7 +9,9 @@ from pandas import (Series, TimeSeries, DataFrame, Panel, Index, isnull, notnull, Timestamp) +from pandas.core.groupby import DataError from pandas.tseries.index import date_range +from pandas.tseries.tdi import timedelta_range from pandas.tseries.offsets import Minute, BDay from pandas.tseries.period import period_range, PeriodIndex, Period from pandas.tseries.resample import DatetimeIndex, TimeGrouper @@ -239,47 +241,47 @@ def test_resample_basic_from_daily(self): self.assertEqual(len(result), 3) self.assertTrue((result.index.dayofweek == [6, 6, 6]).all()) - self.assertEqual(result.irow(0), s['1/2/2005']) - self.assertEqual(result.irow(1), s['1/9/2005']) - self.assertEqual(result.irow(2), s.irow(-1)) + self.assertEqual(result.iloc[0], s['1/2/2005']) + self.assertEqual(result.iloc[1], s['1/9/2005']) + self.assertEqual(result.iloc[2], s.iloc[-1]) result = s.resample('W-MON', how='last') self.assertEqual(len(result), 2) self.assertTrue((result.index.dayofweek == [0, 0]).all()) - self.assertEqual(result.irow(0), s['1/3/2005']) - self.assertEqual(result.irow(1), s['1/10/2005']) + self.assertEqual(result.iloc[0], s['1/3/2005']) + self.assertEqual(result.iloc[1], s['1/10/2005']) result = s.resample('W-TUE', how='last') self.assertEqual(len(result), 2) self.assertTrue((result.index.dayofweek == [1, 1]).all()) - self.assertEqual(result.irow(0), s['1/4/2005']) - self.assertEqual(result.irow(1), s['1/10/2005']) + self.assertEqual(result.iloc[0], s['1/4/2005']) + self.assertEqual(result.iloc[1], s['1/10/2005']) result = s.resample('W-WED', how='last') self.assertEqual(len(result), 2) self.assertTrue((result.index.dayofweek == [2, 2]).all()) - self.assertEqual(result.irow(0), s['1/5/2005']) - self.assertEqual(result.irow(1), s['1/10/2005']) + self.assertEqual(result.iloc[0], s['1/5/2005']) + self.assertEqual(result.iloc[1], s['1/10/2005']) result = s.resample('W-THU', how='last') self.assertEqual(len(result), 2) self.assertTrue((result.index.dayofweek == [3, 3]).all()) - self.assertEqual(result.irow(0), s['1/6/2005']) - self.assertEqual(result.irow(1), s['1/10/2005']) + self.assertEqual(result.iloc[0], s['1/6/2005']) + self.assertEqual(result.iloc[1], s['1/10/2005']) result = s.resample('W-FRI', how='last') self.assertEqual(len(result), 2) self.assertTrue((result.index.dayofweek == [4, 4]).all()) - self.assertEqual(result.irow(0), s['1/7/2005']) - self.assertEqual(result.irow(1), s['1/10/2005']) + self.assertEqual(result.iloc[0], s['1/7/2005']) + self.assertEqual(result.iloc[1], s['1/10/2005']) # to biz day result = s.resample('B', how='last') self.assertEqual(len(result), 7) self.assertTrue((result.index.dayofweek == [4, 0, 1, 2, 3, 4, 0]).all()) - self.assertEqual(result.irow(0), s['1/2/2005']) - self.assertEqual(result.irow(1), s['1/3/2005']) - self.assertEqual(result.irow(5), s['1/9/2005']) + self.assertEqual(result.iloc[0], s['1/2/2005']) + self.assertEqual(result.iloc[1], s['1/3/2005']) + self.assertEqual(result.iloc[5], s['1/9/2005']) self.assertEqual(result.index.name, 'index') def test_resample_upsampling_picked_but_not_correct(self): @@ -406,13 +408,13 @@ def test_resample_ohlc(self): self.assertEqual(len(result), len(expect)) self.assertEqual(len(result.columns), 4) - xs = result.irow(-2) + xs = result.iloc[-2] self.assertEqual(xs['open'], s[-6]) self.assertEqual(xs['high'], s[-6:-1].max()) self.assertEqual(xs['low'], s[-6:-1].min()) self.assertEqual(xs['close'], s[-2]) - xs = result.irow(0) + xs = result.iloc[0] self.assertEqual(xs['open'], s[0]) self.assertEqual(xs['high'], s[:5].max()) self.assertEqual(xs['low'], s[:5].min()) @@ -462,7 +464,7 @@ def test_resample_reresample(self): bs = s.resample('B', closed='right', label='right') result = bs.resample('8H') self.assertEqual(len(result), 22) - tm.assert_isinstance(result.index.freq, offsets.DateOffset) + tm.assertIsInstance(result.index.freq, offsets.DateOffset) self.assertEqual(result.index.freq, offsets.Hour(8)) def test_resample_timestamp_to_period(self): @@ -626,6 +628,21 @@ def test_resample_base(self): freq='5min') self.assertTrue(resampled.index.equals(exp_rng)) + def test_resample_base_with_timedeltaindex(self): + + # GH 10530 + rng = timedelta_range(start = '0s', periods = 25, freq = 's') + ts = Series(np.random.randn(len(rng)), index = rng) + + with_base = ts.resample('2s', base = 5) + without_base = ts.resample('2s') + + exp_without_base = timedelta_range(start = '0s', end = '25s', freq = '2s') + exp_with_base = timedelta_range(start = '5s', end = '29s', freq = '2s') + + self.assertTrue(without_base.index.equals(exp_without_base)) + self.assertTrue(with_base.index.equals(exp_with_base)) + def test_resample_daily_anchored(self): rng = date_range('1/1/2000 0:00:00', periods=10000, freq='T') ts = Series(np.random.randn(len(rng)), index=rng) @@ -660,6 +677,20 @@ def test_resample_empty(self): rs = xp.resample('A') assert_frame_equal(xp, rs) + # Empty series were sometimes causing a segfault (for the functions + # with Cython bounds-checking disabled) or an IndexError. We just run + # them to ensure they no longer do. (GH #10228) + for index in tm.all_timeseries_index_generator(0): + for dtype in (np.float, np.int, np.object, 'datetime64[ns]'): + for how in ('count', 'mean', 'min', 'ohlc', 'last', 'prod'): + empty_series = pd.Series([], index, dtype) + try: + empty_series.resample('d', how) + except DataError: + # Ignore these since some combinations are invalid + # (ex: doing mean with dtype of np.object) + pass + def test_weekly_resample_buglet(self): # #1327 rng = date_range('1/1/2000', freq='B', periods=20) @@ -774,7 +805,7 @@ def test_upsample_apply_functions(self): ts = Series(np.random.randn(len(rng)), index=rng) result = ts.resample('20min', how=['mean', 'sum']) - tm.assert_isinstance(result, DataFrame) + tm.assertIsInstance(result, DataFrame) def test_resample_not_monotonic(self): rng = pd.date_range('2012-06-12', periods=200, freq='h') diff --git a/pandas/tseries/tests/test_timedeltas.py b/pandas/tseries/tests/test_timedeltas.py index 948a0be91b276..5c7d459d3abc4 100644 --- a/pandas/tseries/tests/test_timedeltas.py +++ b/pandas/tseries/tests/test_timedeltas.py @@ -11,7 +11,7 @@ from pandas import (Index, Series, DataFrame, Timestamp, Timedelta, TimedeltaIndex, isnull, notnull, bdate_range, date_range, timedelta_range, Int64Index) import pandas.core.common as com -from pandas.compat import StringIO, lrange, range, zip, u, OrderedDict, long, PY3_2 +from pandas.compat import StringIO, lrange, range, zip, u, OrderedDict, long from pandas import compat, to_timedelta, tslib from pandas.tseries.timedeltas import _coerce_scalar_to_timedelta_type as ct from pandas.util.testing import (assert_series_equal, @@ -109,6 +109,23 @@ def test_construction(self): # currently invalid as it has a - on the hhmmdd part (only allowed on the days) self.assertRaises(ValueError, lambda : Timedelta('-10 days -1 h 1.5m 1s 3us')) + # only leading neg signs are allowed + self.assertRaises(ValueError, lambda : Timedelta('10 days -1 h 1.5m 1s 3us')) + + # no units specified + self.assertRaises(ValueError, lambda : Timedelta('3.1415')) + + # invalid construction + tm.assertRaisesRegexp(ValueError, + "cannot construct a TimeDelta", + lambda : Timedelta()) + tm.assertRaisesRegexp(ValueError, + "unit abbreviation w/o a number", + lambda : Timedelta('foo')) + tm.assertRaisesRegexp(ValueError, + "cannot construct a TimeDelta from the passed arguments, allowed keywords are ", + lambda : Timedelta(day=10)) + # roundtripping both for string and value for v in ['1s', '-1s', @@ -146,17 +163,6 @@ def test_construction(self): self.assertEqual(Timedelta(pd.offsets.Hour(2)),Timedelta('0 days, 02:00:00')) self.assertEqual(Timedelta(pd.offsets.Second(2)),Timedelta('0 days, 00:00:02')) - # invalid - tm.assertRaisesRegexp(ValueError, - "cannot construct a TimeDelta", - lambda : Timedelta()) - tm.assertRaisesRegexp(ValueError, - "cannot create timedelta string convert", - lambda : Timedelta('foo')) - tm.assertRaisesRegexp(ValueError, - "cannot construct a TimeDelta from the passed arguments, allowed keywords are ", - lambda : Timedelta(day=10)) - def test_repr(self): self.assertEqual(repr(Timedelta(10,unit='d')),"Timedelta('10 days 00:00:00')") @@ -601,12 +607,22 @@ def testit(unit, transform): # ms testit('L',lambda x: 'ms') + def test_to_timedelta_invalid(self): + # these will error self.assertRaises(ValueError, lambda : to_timedelta([1,2],unit='foo')) self.assertRaises(ValueError, lambda : to_timedelta(1,unit='foo')) # time not supported ATM self.assertRaises(ValueError, lambda :to_timedelta(time(second=1))) + self.assertTrue(to_timedelta(time(second=1), errors='coerce') is pd.NaT) + + self.assertRaises(ValueError, lambda : to_timedelta(['foo','bar'])) + tm.assert_index_equal(TimedeltaIndex([pd.NaT,pd.NaT]), + to_timedelta(['foo','bar'], errors='coerce')) + + tm.assert_index_equal(TimedeltaIndex(['1 day', pd.NaT, '1 min']), + to_timedelta(['1 day','bar','1 min'], errors='coerce')) def test_to_timedelta_via_apply(self): # GH 5458 @@ -871,7 +887,7 @@ def test_append_join_nondatetimeindex(self): idx = Index(['a', 'b', 'c', 'd']) result = rng.append(idx) - tm.assert_isinstance(result[0], Timedelta) + tm.assertIsInstance(result[0], Timedelta) # it works rng.join(idx, how='outer') @@ -1040,8 +1056,6 @@ def test_comparisons_coverage(self): self.assert_numpy_array_equal(result, exp) def test_comparisons_nat(self): - if PY3_2: - raise nose.SkipTest('nat comparisons on 3.2 broken') tdidx1 = pd.TimedeltaIndex(['1 day', pd.NaT, '1 day 00:00:01', pd.NaT, '1 day 00:00:01', '5 day 00:00:03']) @@ -1099,7 +1113,7 @@ def test_misc_coverage(self): rng = timedelta_range('1 day', periods=5) result = rng.groupby(rng.days) - tm.assert_isinstance(list(result.values())[0][0], Timedelta) + tm.assertIsInstance(list(result.values())[0][0], Timedelta) idx = TimedeltaIndex(['3d','1d','2d']) self.assertTrue(idx.equals(list(idx))) @@ -1305,7 +1319,7 @@ def test_take(self): for taken in [taken1, taken2]: self.assertTrue(taken.equals(expected)) - tm.assert_isinstance(taken, TimedeltaIndex) + tm.assertIsInstance(taken, TimedeltaIndex) self.assertIsNone(taken.freq) self.assertEqual(taken.name, expected.name) @@ -1387,7 +1401,7 @@ def test_partial_slice(self): assert_series_equal(result, expected) result = s['6 days, 23:11:12'] - self.assertEqual(result, s.irow(133)) + self.assertEqual(result, s.iloc[133]) self.assertRaises(KeyError, s.__getitem__, '50 days') @@ -1406,7 +1420,7 @@ def test_partial_slice_high_reso(self): assert_series_equal(result, expected) result = s['1 days, 10:11:12.001001'] - self.assertEqual(result, s.irow(1001)) + self.assertEqual(result, s.iloc[1001]) def test_slice_with_negative_step(self): ts = Series(np.arange(20), diff --git a/pandas/tseries/tests/test_timeseries.py b/pandas/tseries/tests/test_timeseries.py index 09b2bb24714af..e02973136863d 100644 --- a/pandas/tseries/tests/test_timeseries.py +++ b/pandas/tseries/tests/test_timeseries.py @@ -11,7 +11,7 @@ from pandas import (Index, Series, TimeSeries, DataFrame, isnull, date_range, Timestamp, Period, DatetimeIndex, - Int64Index, to_datetime, bdate_range, Float64Index, TimedeltaIndex) + Int64Index, to_datetime, bdate_range, Float64Index, TimedeltaIndex, NaT) import pandas.core.datetools as datetools import pandas.tseries.offsets as offsets @@ -28,10 +28,10 @@ import pandas.index as _index -from pandas.compat import range, long, StringIO, lrange, lmap, zip, product, PY3_2 +from pandas.compat import range, long, StringIO, lrange, lmap, zip, product from numpy.random import rand -from numpy.testing import assert_array_equal from pandas.util.testing import assert_frame_equal +from pandas.io.common import PerformanceWarning import pandas.compat as compat import pandas.core.common as com from pandas import concat @@ -46,14 +46,6 @@ def _skip_if_has_locale(): if lang is not None: raise nose.SkipTest("Specific locale is set {0}".format(lang)) -def _skip_if_windows_python_3(): - if sys.version_info > (3,) and sys.platform == 'win32': - raise nose.SkipTest("not used on python 3/win32") - -def _skip_if_not_windows_python_3(): - if sys.version_info < (3,) or sys.platform != 'win32': - raise nose.SkipTest("only run on python 3/win32") - class TestTimeSeriesDuplicates(tm.TestCase): _multiprocess_can_split_ = True @@ -68,8 +60,8 @@ def setUp(self): self.dups = Series(np.random.randn(len(dates)), index=dates) def test_constructor(self): - tm.assert_isinstance(self.dups, TimeSeries) - tm.assert_isinstance(self.dups.index, DatetimeIndex) + tm.assertIsInstance(self.dups, TimeSeries) + tm.assertIsInstance(self.dups.index, DatetimeIndex) def test_is_unique_monotonic(self): self.assertFalse(self.dups.index.is_unique) @@ -369,13 +361,13 @@ def test_series_box_timestamp(self): rng = date_range('20090415', '20090519', freq='B') s = Series(rng) - tm.assert_isinstance(s[5], Timestamp) + tm.assertIsInstance(s[5], Timestamp) rng = date_range('20090415', '20090519', freq='B') s = Series(rng, index=rng) - tm.assert_isinstance(s[5], Timestamp) + tm.assertIsInstance(s[5], Timestamp) - tm.assert_isinstance(s.iget_value(5), Timestamp) + tm.assertIsInstance(s.iat[5], Timestamp) def test_date_range_ambiguous_arguments(self): # #2538 @@ -417,7 +409,7 @@ def test_timestamp_to_datetime_explicit_pytz(self): self.assertEqual(stamp.tzinfo, dtval.tzinfo) def test_timestamp_to_datetime_explicit_dateutil(self): - _skip_if_windows_python_3() + tm._skip_if_windows_python_3() tm._skip_if_no_dateutil() from pandas.tslib import _dateutil_gettz as gettz rng = date_range('20090415', '20090519', @@ -433,9 +425,9 @@ def test_index_convert_to_datetime_array(self): def _check_rng(rng): converted = rng.to_pydatetime() - tm.assert_isinstance(converted, np.ndarray) + tm.assertIsInstance(converted, np.ndarray) for x, stamp in zip(converted, rng): - tm.assert_isinstance(x, datetime) + tm.assertIsInstance(x, datetime) self.assertEqual(x, stamp.to_pydatetime()) self.assertEqual(x.tzinfo, stamp.tzinfo) @@ -453,9 +445,9 @@ def test_index_convert_to_datetime_array_explicit_pytz(self): def _check_rng(rng): converted = rng.to_pydatetime() - tm.assert_isinstance(converted, np.ndarray) + tm.assertIsInstance(converted, np.ndarray) for x, stamp in zip(converted, rng): - tm.assert_isinstance(x, datetime) + tm.assertIsInstance(x, datetime) self.assertEqual(x, stamp.to_pydatetime()) self.assertEqual(x.tzinfo, stamp.tzinfo) @@ -473,9 +465,9 @@ def test_index_convert_to_datetime_array_dateutil(self): def _check_rng(rng): converted = rng.to_pydatetime() - tm.assert_isinstance(converted, np.ndarray) + tm.assertIsInstance(converted, np.ndarray) for x, stamp in zip(converted, rng): - tm.assert_isinstance(x, datetime) + tm.assertIsInstance(x, datetime) self.assertEqual(x, stamp.to_pydatetime()) self.assertEqual(x.tzinfo, stamp.tzinfo) @@ -856,12 +848,16 @@ def test_string_na_nat_conversion(self): assert_almost_equal(result, expected) result2 = to_datetime(strings) - tm.assert_isinstance(result2, DatetimeIndex) - self.assert_numpy_array_equal(result, result2) + tm.assertIsInstance(result2, DatetimeIndex) + tm.assert_numpy_array_equal(result, result2) malformed = np.array(['1/100/2000', np.nan], dtype=object) - result = to_datetime(malformed) - self.assert_numpy_array_equal(result, malformed) + + # GH 10636, default is now 'raise' + self.assertRaises(ValueError, lambda : to_datetime(malformed, errors='raise')) + + result = to_datetime(malformed, errors='ignore') + tm.assert_numpy_array_equal(result, malformed) self.assertRaises(ValueError, to_datetime, malformed, errors='raise') @@ -927,11 +923,11 @@ def test_to_datetime_with_apply(self): assert_series_equal(result, expected) td = pd.Series(['May 04', 'Jun 02', ''], index=[1,2,3]) - self.assertRaises(ValueError, lambda : pd.to_datetime(td,format='%b %y')) - self.assertRaises(ValueError, lambda : td.apply(pd.to_datetime, format='%b %y')) - expected = pd.to_datetime(td, format='%b %y', coerce=True) + self.assertRaises(ValueError, lambda : pd.to_datetime(td,format='%b %y', errors='raise')) + self.assertRaises(ValueError, lambda : td.apply(pd.to_datetime, format='%b %y', errors='raise')) + expected = pd.to_datetime(td, format='%b %y', errors='coerce') - result = td.apply(lambda x: pd.to_datetime(x, format='%b %y', coerce=True)) + result = td.apply(lambda x: pd.to_datetime(x, format='%b %y', errors='coerce')) assert_series_equal(result, expected) def test_nat_vector_field_access(self): @@ -944,17 +940,39 @@ def test_nat_vector_field_access(self): result = getattr(idx, field) expected = [getattr(x, field) if x is not NaT else np.nan for x in idx] - self.assert_numpy_array_equivalent(result, np.array(expected)) + self.assert_numpy_array_equal(result, np.array(expected)) def test_nat_scalar_field_access(self): fields = ['year', 'quarter', 'month', 'day', 'hour', 'minute', 'second', 'microsecond', 'nanosecond', - 'week', 'dayofyear', 'days_in_month'] + 'week', 'dayofyear', 'days_in_month', 'daysinmonth', + 'dayofweek'] for field in fields: result = getattr(NaT, field) self.assertTrue(np.isnan(result)) - self.assertTrue(np.isnan(NaT.weekday())) + def test_NaT_methods(self): + # GH 9513 + raise_methods = ['astimezone', 'combine', 'ctime', 'dst', 'fromordinal', + 'fromtimestamp', 'isocalendar', 'isoformat', + 'strftime', 'strptime', + 'time', 'timestamp', 'timetuple', 'timetz', + 'toordinal', 'tzname', 'utcfromtimestamp', + 'utcnow', 'utcoffset', 'utctimetuple'] + nat_methods = ['date', 'now', 'replace', 'to_datetime', 'today'] + nan_methods = ['weekday', 'isoweekday'] + + for method in raise_methods: + if hasattr(NaT, method): + self.assertRaises(ValueError, getattr(NaT, method)) + + for method in nan_methods: + if hasattr(NaT, method): + self.assertTrue(np.isnan(getattr(NaT, method)())) + + for method in nat_methods: + if hasattr(NaT, method): + self.assertIs(getattr(NaT, method)(), NaT) def test_to_datetime_types(self): @@ -989,7 +1007,7 @@ def test_to_datetime_types(self): def test_to_datetime_unprocessable_input(self): # GH 4928 self.assert_numpy_array_equal( - to_datetime([1, '1']), + to_datetime([1, '1'], errors='ignore'), np.array([1, '1'], dtype='O') ) self.assertRaises(TypeError, to_datetime, [1, '1'], errors='raise') @@ -1035,7 +1053,7 @@ def test_to_datetime_dt64s(self): for dt in oob_dts: self.assertRaises(ValueError, pd.to_datetime, dt, errors='raise') self.assertRaises(ValueError, tslib.Timestamp, dt) - self.assertIs(pd.to_datetime(dt, coerce=True), NaT) + self.assertIs(pd.to_datetime(dt, errors='coerce'), NaT) def test_to_datetime_array_of_dt64s(self): dts = [ @@ -1057,12 +1075,11 @@ def test_to_datetime_array_of_dt64s(self): ValueError, pd.to_datetime, dts_with_oob, - coerce=False, errors='raise' ) self.assert_numpy_array_equal( - pd.to_datetime(dts_with_oob, box=False, coerce=True), + pd.to_datetime(dts_with_oob, box=False, errors='coerce'), np.array( [ Timestamp(dts_with_oob[0]).asm8, @@ -1073,11 +1090,11 @@ def test_to_datetime_array_of_dt64s(self): ) ) - # With coerce=False and errors='ignore', out of bounds datetime64s + # With errors='ignore', out of bounds datetime64s # are converted to their .item(), which depending on the version of # numpy is either a python datetime.datetime or datetime.date self.assert_numpy_array_equal( - pd.to_datetime(dts_with_oob, box=False, coerce=False), + pd.to_datetime(dts_with_oob, box=False, errors='ignore'), np.array( [dt.item() for dt in dts_with_oob], dtype='O' @@ -1440,6 +1457,25 @@ def test_dti_constructor_preserve_dti_freq(self): rng2 = DatetimeIndex(rng) self.assertEqual(rng.freq, rng2.freq) + def test_dti_constructor_years_only(self): + # GH 6961 + for tz in [None, 'UTC', 'Asia/Tokyo', 'dateutil/US/Pacific']: + rng1 = date_range('2014', '2015', freq='M', tz=tz) + expected1 = date_range('2014-01-31', '2014-12-31', freq='M', tz=tz) + + rng2 = date_range('2014', '2015', freq='MS', tz=tz) + expected2 = date_range('2014-01-01', '2015-01-01', freq='MS', tz=tz) + + rng3 = date_range('2014', '2020', freq='A', tz=tz) + expected3 = date_range('2014-12-31', '2019-12-31', freq='A', tz=tz) + + rng4 = date_range('2014', '2020', freq='AS', tz=tz) + expected4 = date_range('2014-01-01', '2020-01-01', freq='AS', tz=tz) + + for rng, expected in [(rng1, expected1), (rng2, expected2), + (rng3, expected3), (rng4, expected4)]: + tm.assert_index_equal(rng, expected) + def test_normalize(self): rng = date_range('1/1/2000 9:30', periods=10, freq='D') @@ -2092,7 +2128,7 @@ def test_append_join_nondatetimeindex(self): idx = Index(['a', 'b', 'c', 'd']) result = rng.append(idx) - tm.assert_isinstance(result[0], Timestamp) + tm.assertIsInstance(result[0], Timestamp) # it works rng.join(idx, how='outer') @@ -2154,6 +2190,15 @@ def test_constructor_coverage(self): from_ints = DatetimeIndex(expected.asi8) self.assertTrue(from_ints.equals(expected)) + # string with NaT + strings = np.array(['2000-01-01', '2000-01-02', 'NaT']) + result = DatetimeIndex(strings) + expected = DatetimeIndex(strings.astype('O')) + self.assertTrue(result.equals(expected)) + + from_ints = DatetimeIndex(expected.asi8) + self.assertTrue(from_ints.equals(expected)) + # non-conforming self.assertRaises(ValueError, DatetimeIndex, ['2000-01-01', '2000-01-02', '2000-01-04'], @@ -2225,8 +2270,6 @@ def test_comparisons_coverage(self): self.assert_numpy_array_equal(result, exp) def test_comparisons_nat(self): - if PY3_2: - raise nose.SkipTest('nat comparisons on 3.2 broken') fidx1 = pd.Index([1.0, np.nan, 3.0, np.nan, 5.0, 7.0]) fidx2 = pd.Index([2.0, 3.0, np.nan, np.nan, 6.0, 7.0]) @@ -2323,7 +2366,7 @@ def test_map(self): f = lambda x: x.strftime('%Y%m%d') result = rng.map(f) exp = [f(x) for x in rng] - self.assert_numpy_array_equal(result, exp) + tm.assert_almost_equal(result, exp) def test_iteration_preserves_tz(self): @@ -2359,7 +2402,7 @@ def test_iteration_preserves_tz(self): def test_misc_coverage(self): rng = date_range('1/1/2000', periods=5) result = rng.groupby(rng.day) - tm.assert_isinstance(list(result.values())[0][0], Timestamp) + tm.assertIsInstance(list(result.values())[0][0], Timestamp) idx = DatetimeIndex(['2000-01-03', '2000-01-01', '2000-01-02']) self.assertTrue(idx.equals(list(idx))) @@ -2412,6 +2455,91 @@ def test_intersection_bug_1708(self): result = index_1 & index_2 self.assertEqual(len(result), 0) + # GH 10699 + def test_datetime64_with_DateOffset(self): + for klass, assert_func in zip([Series, DatetimeIndex], + [self.assert_series_equal, + tm.assert_index_equal]): + s = klass(date_range('2000-01-01', '2000-01-31')) + result = s + pd.DateOffset(years=1) + result2 = pd.DateOffset(years=1) + s + exp = klass(date_range('2001-01-01', '2001-01-31')) + assert_func(result, exp) + assert_func(result2, exp) + + result = s - pd.DateOffset(years=1) + exp = klass(date_range('1999-01-01', '1999-01-31')) + assert_func(result, exp) + + s = klass([Timestamp('2000-01-15 00:15:00', tz='US/Central'), + pd.Timestamp('2000-02-15', tz='US/Central')]) + result = s + pd.offsets.MonthEnd() + result2 = pd.offsets.MonthEnd() + s + exp = klass([Timestamp('2000-01-31 00:15:00', tz='US/Central'), + Timestamp('2000-02-29', tz='US/Central')]) + assert_func(result, exp) + assert_func(result2, exp) + + # array of offsets - valid for Series only + if klass is Series: + with tm.assert_produces_warning(PerformanceWarning): + s = klass([Timestamp('2000-1-1'), Timestamp('2000-2-1')]) + result = s + Series([pd.offsets.DateOffset(years=1), + pd.offsets.MonthEnd()]) + exp = klass([Timestamp('2001-1-1'), Timestamp('2000-2-29')]) + assert_func(result, exp) + + # same offset + result = s + Series([pd.offsets.DateOffset(years=1), + pd.offsets.DateOffset(years=1)]) + exp = klass([Timestamp('2001-1-1'), Timestamp('2001-2-1')]) + assert_func(result, exp) + + s = klass([Timestamp('2000-01-05 00:15:00'), Timestamp('2000-01-31 00:23:00'), + Timestamp('2000-01-01'), Timestamp('2000-02-29'), Timestamp('2000-12-31')]) + + #DateOffset relativedelta fastpath + relative_kwargs = [('years', 2), ('months', 5), ('days', 3), + ('hours', 5), ('minutes', 10), ('seconds', 2), + ('microseconds', 5)] + for i, kwd in enumerate(relative_kwargs): + op = pd.DateOffset(**dict([kwd])) + assert_func(klass([x + op for x in s]), s + op) + assert_func(klass([x - op for x in s]), s - op) + op = pd.DateOffset(**dict(relative_kwargs[:i+1])) + assert_func(klass([x + op for x in s]), s + op) + assert_func(klass([x - op for x in s]), s - op) + + + # split by fast/slow path to test perf warning + off = {False: + ['YearBegin', ('YearBegin', {'month': 5}), + 'YearEnd', ('YearEnd', {'month': 5}), + 'MonthBegin', 'MonthEnd', 'Week', ('Week', {'weekday': 3}), + 'BusinessDay', 'BDay', 'QuarterEnd', 'QuarterBegin'], + PerformanceWarning: + ['CustomBusinessDay', 'CDay', 'CBMonthEnd','CBMonthBegin', + 'BMonthBegin', 'BMonthEnd', 'BusinessHour', 'BYearBegin', + 'BYearEnd','BQuarterBegin', ('LastWeekOfMonth', {'weekday':2}), + ('FY5253Quarter', {'qtr_with_extra_week': 1, 'startingMonth': 1, + 'weekday': 2, 'variation': 'nearest'}), + ('FY5253',{'weekday': 0, 'startingMonth': 2, 'variation': 'nearest'}), + ('WeekOfMonth', {'weekday': 2, 'week': 2}), 'Easter', + ('DateOffset', {'day': 4}), ('DateOffset', {'month': 5})]} + + for normalize in (True, False): + for warning, offsets in off.items(): + for do in offsets: + if isinstance(do, tuple): + do, kwargs = do + else: + do = do + kwargs = {} + op = getattr(pd.offsets,do)(5, normalize=normalize, **kwargs) + with tm.assert_produces_warning(warning): + assert_func(klass([x + op for x in s]), s + op) + assert_func(klass([x - op for x in s]), s - op) + assert_func(klass([op + x for x in s]), op + s) # def test_add_timedelta64(self): # rng = date_range('1/1/2000', periods=5) # delta = rng.values[3] - rng.values[1] @@ -2645,7 +2773,7 @@ def test_take(self): for taken in [taken1, taken2]: self.assertTrue(taken.equals(expected)) - tm.assert_isinstance(taken, DatetimeIndex) + tm.assertIsInstance(taken, DatetimeIndex) self.assertIsNone(taken.freq) self.assertEqual(taken.tz, expected.tz) self.assertEqual(taken.name, expected.name) @@ -2664,7 +2792,7 @@ def test_groupby_function_tuple_1677(self): monthly_group = df.groupby(lambda x: (x.year, x.month)) result = monthly_group.mean() - tm.assert_isinstance(result.index[0], tuple) + tm.assertIsInstance(result.index[0], tuple) def test_append_numpy_bug_1681(self): # another datetime64 bug @@ -2718,7 +2846,7 @@ def test_does_not_convert_mixed_integer(self): joined = cols.join(df.columns) self.assertEqual(cols.dtype, np.dtype('O')) self.assertEqual(cols.dtype, joined.dtype) - assert_array_equal(cols.values, joined.values) + tm.assert_numpy_array_equal(cols.values, joined.values) def test_slice_keeps_name(self): # GH4226 @@ -3139,11 +3267,11 @@ def test_datetimeindex_union_join_empty(self): empty = Index([]) result = dti.union(empty) - tm.assert_isinstance(result, DatetimeIndex) + tm.assertIsInstance(result, DatetimeIndex) self.assertIs(result, result) result = dti.join(empty) - tm.assert_isinstance(result, DatetimeIndex) + tm.assertIsInstance(result, DatetimeIndex) def test_series_set_value(self): # #1561 @@ -3249,6 +3377,12 @@ def test_NaT_scalar(self): series[2] = val self.assertTrue(com.isnull(series[2])) + def test_NaT_cast(self): + # GH10747 + result = Series([np.nan]).astype('M8[ns]') + expected = Series([NaT]) + assert_series_equal(result, expected) + def test_set_none_nan(self): self.series[3] = None self.assertIs(self.series[3], NaT) @@ -3502,6 +3636,9 @@ def check(val,unit=None,h=1,s=1,us=0): result = Timestamp(NaT) self.assertIs(result, NaT) + result = Timestamp('NaT') + self.assertIs(result, NaT) + def test_roundtrip(self): # test value to string and back conversions @@ -3809,7 +3946,7 @@ def test_partial_slice(self): assert_series_equal(result, expected) result = s['2005-1-1'] - self.assertEqual(result, s.irow(0)) + self.assertEqual(result, s.iloc[0]) self.assertRaises(Exception, s.__getitem__, '2004-12-31') @@ -4005,8 +4142,8 @@ def test_min_max(self): the_min = rng2.min() the_max = rng2.max() - tm.assert_isinstance(the_min, Timestamp) - tm.assert_isinstance(the_max, Timestamp) + tm.assertIsInstance(the_min, Timestamp) + tm.assertIsInstance(the_max, Timestamp) self.assertEqual(the_min, rng[0]) self.assertEqual(the_max, rng[-1]) @@ -4020,12 +4157,12 @@ def test_min_max_series(self): 'L': lvls}) result = df.TS.max() - exp = Timestamp(df.TS.iget(-1)) + exp = Timestamp(df.TS.iat[-1]) self.assertTrue(isinstance(result, Timestamp)) self.assertEqual(result, exp) result = df.TS.min() - exp = Timestamp(df.TS.iget(0)) + exp = Timestamp(df.TS.iat[0]) self.assertTrue(isinstance(result, Timestamp)) self.assertEqual(result, exp) @@ -4146,14 +4283,28 @@ def test_to_datetime_format_YYYYMMDD(self): # coercion # GH 7930 s = Series([20121231, 20141231, 99991231]) - result = pd.to_datetime(s,format='%Y%m%d') + result = pd.to_datetime(s,format='%Y%m%d',errors='ignore') expected = np.array([ datetime(2012,12,31), datetime(2014,12,31), datetime(9999,12,31) ], dtype=object) self.assert_numpy_array_equal(result, expected) - result = pd.to_datetime(s,format='%Y%m%d', coerce=True) + result = pd.to_datetime(s,format='%Y%m%d', errors='coerce') expected = Series(['20121231','20141231','NaT'],dtype='M8[ns]') assert_series_equal(result, expected) + # GH 10178 + def test_to_datetime_format_integer(self): + s = Series([2000, 2001, 2002]) + expected = Series([ Timestamp(x) for x in s.apply(str) ]) + + result = to_datetime(s,format='%Y') + assert_series_equal(result, expected) + + s = Series([200001, 200105, 200206]) + expected = Series([ Timestamp(x[:4] + '-' + x[4:]) for x in s.apply(str) ]) + + result = to_datetime(s,format='%Y%m') + assert_series_equal(result, expected) + def test_to_datetime_format_microsecond(self): val = '01-Apr-2011 00:00:01.978' format = '%d-%b-%Y %H:%M:%S.%f' @@ -4163,17 +4314,19 @@ def test_to_datetime_format_microsecond(self): def test_to_datetime_format_time(self): data = [ - ['01/10/2010 15:20', '%m/%d/%Y %H:%M', Timestamp('2010-01-10 15:20')], - ['01/10/2010 05:43', '%m/%d/%Y %I:%M', Timestamp('2010-01-10 05:43')], - ['01/10/2010 13:56:01', '%m/%d/%Y %H:%M:%S', Timestamp('2010-01-10 13:56:01')]#, - #['01/10/2010 08:14 PM', '%m/%d/%Y %I:%M %p', Timestamp('2010-01-10 20:14')], - #['01/10/2010 07:40 AM', '%m/%d/%Y %I:%M %p', Timestamp('2010-01-10 07:40')], - #['01/10/2010 09:12:56 AM', '%m/%d/%Y %I:%M:%S %p', Timestamp('2010-01-10 09:12:56')] + ['01/10/2010 15:20', '%m/%d/%Y %H:%M', Timestamp('2010-01-10 15:20')], + ['01/10/2010 05:43', '%m/%d/%Y %I:%M', Timestamp('2010-01-10 05:43')], + ['01/10/2010 13:56:01', '%m/%d/%Y %H:%M:%S', Timestamp('2010-01-10 13:56:01')]#, + #['01/10/2010 08:14 PM', '%m/%d/%Y %I:%M %p', Timestamp('2010-01-10 20:14')], + #['01/10/2010 07:40 AM', '%m/%d/%Y %I:%M %p', Timestamp('2010-01-10 07:40')], + #['01/10/2010 09:12:56 AM', '%m/%d/%Y %I:%M:%S %p', Timestamp('2010-01-10 09:12:56')] ] for s, format, dt in data: self.assertEqual(to_datetime(s, format=format), dt) def test_to_datetime_with_non_exact(self): + # GH 10834 + _skip_if_has_locale() # 8904 # exact kw @@ -4463,6 +4616,40 @@ def test_second(self): self.assertIsInstance(r2, Float64Index) tm.assert_index_equal(r1, r2) +class TestDaysInMonth(tm.TestCase): + + def test_coerce_deprecation(self): + + # deprecation of coerce + with tm.assert_produces_warning(FutureWarning): + to_datetime('2015-02-29', coerce=True) + with tm.assert_produces_warning(FutureWarning): + self.assertRaises(ValueError, lambda : to_datetime('2015-02-29', coerce=False)) + + # multiple arguments + for e, c in zip(['raise','ignore','coerce'],[True,False]): + with tm.assert_produces_warning(FutureWarning): + self.assertRaises(TypeError, lambda : to_datetime('2015-02-29', errors=e, coerce=c)) + + # tests for issue #10154 + def test_day_not_in_month_coerce(self): + self.assertTrue(isnull(to_datetime('2015-02-29', errors='coerce'))) + self.assertTrue(isnull(to_datetime('2015-02-29', format="%Y-%m-%d", errors='coerce'))) + self.assertTrue(isnull(to_datetime('2015-02-32', format="%Y-%m-%d", errors='coerce'))) + self.assertTrue(isnull(to_datetime('2015-04-31', format="%Y-%m-%d", errors='coerce'))) + + def test_day_not_in_month_raise(self): + self.assertRaises(ValueError, to_datetime, '2015-02-29', errors='raise') + self.assertRaises(ValueError, to_datetime, '2015-02-29', errors='raise', format="%Y-%m-%d") + self.assertRaises(ValueError, to_datetime, '2015-02-32', errors='raise', format="%Y-%m-%d") + self.assertRaises(ValueError, to_datetime, '2015-04-31', errors='raise', format="%Y-%m-%d") + + def test_day_not_in_month_ignore(self): + self.assertEqual(to_datetime('2015-02-29', errors='ignore'), '2015-02-29') + self.assertEqual(to_datetime('2015-02-29', errors='ignore', format="%Y-%m-%d"), '2015-02-29') + self.assertEqual(to_datetime('2015-02-32', errors='ignore', format="%Y-%m-%d"), '2015-02-32') + self.assertEqual(to_datetime('2015-04-31', errors='ignore', format="%Y-%m-%d"), '2015-04-31') + if __name__ == '__main__': nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'], exit=False) diff --git a/pandas/tseries/tests/test_timeseries_legacy.py b/pandas/tseries/tests/test_timeseries_legacy.py index 1f811af0e24ba..6889f8e2afbb2 100644 --- a/pandas/tseries/tests/test_timeseries_legacy.py +++ b/pandas/tseries/tests/test_timeseries_legacy.py @@ -90,7 +90,7 @@ def test_unpickle_legacy_len0_daterange(self): ex_index = DatetimeIndex([], freq='B') self.assertTrue(result.index.equals(ex_index)) - tm.assert_isinstance(result.index.freq, offsets.BDay) + tm.assertIsInstance(result.index.freq, offsets.BDay) self.assertEqual(len(result), 0) def test_arithmetic_interaction(self): @@ -102,12 +102,12 @@ def test_arithmetic_interaction(self): result = dseries + oseries expected = dseries * 2 - tm.assert_isinstance(result.index, DatetimeIndex) + tm.assertIsInstance(result.index, DatetimeIndex) assert_series_equal(result, expected) result = dseries + oseries[:5] expected = dseries + dseries[:5] - tm.assert_isinstance(result.index, DatetimeIndex) + tm.assertIsInstance(result.index, DatetimeIndex) assert_series_equal(result, expected) def test_join_interaction(self): @@ -119,7 +119,7 @@ def _check_join(left, right, how='inner'): ea, eb, ec = left.join(DatetimeIndex(right), how=how, return_indexers=True) - tm.assert_isinstance(ra, DatetimeIndex) + tm.assertIsInstance(ra, DatetimeIndex) self.assertTrue(ra.equals(ea)) assert_almost_equal(rb, eb) @@ -143,8 +143,8 @@ def test_unpickle_daterange(self): filepath = os.path.join(pth, 'data', 'daterange_073.pickle') rng = read_pickle(filepath) - tm.assert_isinstance(rng[0], datetime) - tm.assert_isinstance(rng.offset, offsets.BDay) + tm.assertIsInstance(rng[0], datetime) + tm.assertIsInstance(rng.offset, offsets.BDay) self.assertEqual(rng.values.dtype, object) def test_setops(self): @@ -153,17 +153,17 @@ def test_setops(self): result = index[:5].union(obj_index[5:]) expected = index - tm.assert_isinstance(result, DatetimeIndex) + tm.assertIsInstance(result, DatetimeIndex) self.assertTrue(result.equals(expected)) result = index[:10].intersection(obj_index[5:]) expected = index[5:10] - tm.assert_isinstance(result, DatetimeIndex) + tm.assertIsInstance(result, DatetimeIndex) self.assertTrue(result.equals(expected)) result = index[:10] - obj_index[5:] expected = index[:5] - tm.assert_isinstance(result, DatetimeIndex) + tm.assertIsInstance(result, DatetimeIndex) self.assertTrue(result.equals(expected)) def test_index_conversion(self): @@ -179,7 +179,7 @@ def test_tolist(self): rng = date_range('1/1/2000', periods=10) result = rng.tolist() - tm.assert_isinstance(result[0], Timestamp) + tm.assertIsInstance(result[0], Timestamp) def test_object_convert_fail(self): idx = DatetimeIndex([NaT]) diff --git a/pandas/tseries/tests/test_timezones.py b/pandas/tseries/tests/test_timezones.py index c7909acca96bb..aa655efc08ca5 100644 --- a/pandas/tseries/tests/test_timezones.py +++ b/pandas/tseries/tests/test_timezones.py @@ -1,7 +1,5 @@ # pylint: disable-msg=E1101,W0612 from datetime import datetime, timedelta, tzinfo, date -import sys -import os import nose import numpy as np @@ -238,7 +236,7 @@ def test_astimezone(self): expected = utc.tz_convert(self.tzstr('US/Eastern')) result = utc.astimezone(self.tzstr('US/Eastern')) self.assertEqual(expected, result) - tm.assert_isinstance(result, Timestamp) + tm.assertIsInstance(result, Timestamp) def test_create_with_tz(self): stamp = Timestamp('3/11/2012 05:00', tz=self.tzstr('US/Eastern')) @@ -837,8 +835,8 @@ def localize(self, tz, x): return x.replace(tzinfo=tz) def test_utc_with_system_utc(self): - if sys.platform == 'win32': - raise nose.SkipTest('Skipped on win32 due to dateutil bug.') + # Skipped on win32 due to dateutil bug + tm._skip_if_windows() from pandas.tslib import maybe_get_tz @@ -1045,11 +1043,11 @@ def test_join_utc_convert(self): for how in ['inner', 'outer', 'left', 'right']: result = left.join(left[:-5], how=how) - tm.assert_isinstance(result, DatetimeIndex) + tm.assertIsInstance(result, DatetimeIndex) self.assertEqual(result.tz, left.tz) result = left.join(right[:-5], how=how) - tm.assert_isinstance(result, DatetimeIndex) + tm.assertIsInstance(result, DatetimeIndex) self.assertEqual(result.tz.zone, 'UTC') def test_join_aware(self): diff --git a/pandas/tseries/tests/test_tslib.py b/pandas/tseries/tests/test_tslib.py index 341450f504e2a..85bae42e7a492 100644 --- a/pandas/tseries/tests/test_tslib.py +++ b/pandas/tseries/tests/test_tslib.py @@ -6,13 +6,15 @@ import pandas._period as period import datetime -from pandas.core.api import Timestamp, Series, Timedelta, Period +from pandas.core.api import Timestamp, Series, Timedelta, Period, to_datetime from pandas.tslib import get_timezone from pandas._period import period_asfreq, period_ordinal -from pandas.tseries.index import date_range +from pandas.tseries.index import date_range, DatetimeIndex from pandas.tseries.frequencies import get_freq +import pandas.tseries.tools as tools import pandas.tseries.offsets as offsets import pandas.util.testing as tm +import pandas.compat as compat from pandas.util.testing import assert_series_equal import pandas.compat as compat @@ -416,6 +418,7 @@ def test_nat_fields(self): class TestDatetimeParsingWrappers(tm.TestCase): + def test_does_not_convert_mixed_integer(self): bad_date_strings = ( '-50000', @@ -444,6 +447,179 @@ def test_does_not_convert_mixed_integer(self): tslib._does_string_look_like_datetime(good_date_string) ) + def test_parsers(self): + cases = {'2011-01-01': datetime.datetime(2011, 1, 1), + '2Q2005': datetime.datetime(2005, 4, 1), + '2Q05': datetime.datetime(2005, 4, 1), + '2005Q1': datetime.datetime(2005, 1, 1), + '05Q1': datetime.datetime(2005, 1, 1), + '2011Q3': datetime.datetime(2011, 7, 1), + '11Q3': datetime.datetime(2011, 7, 1), + '3Q2011': datetime.datetime(2011, 7, 1), + '3Q11': datetime.datetime(2011, 7, 1), + + # quarterly without space + '2000Q4': datetime.datetime(2000, 10, 1), + '00Q4': datetime.datetime(2000, 10, 1), + '4Q2000': datetime.datetime(2000, 10, 1), + '4Q00': datetime.datetime(2000, 10, 1), + '2000q4': datetime.datetime(2000, 10, 1), + + '2000-Q4': datetime.datetime(2000, 10, 1), + '00-Q4': datetime.datetime(2000, 10, 1), + '4Q-2000': datetime.datetime(2000, 10, 1), + '4Q-00': datetime.datetime(2000, 10, 1), + + '2000q4': datetime.datetime(2000, 10, 1), + '00q4': datetime.datetime(2000, 10, 1), + + '2005': datetime.datetime(2005, 1, 1), + '2005-11': datetime.datetime(2005, 11, 1), + '2005 11': datetime.datetime(2005, 11, 1), + '11-2005': datetime.datetime(2005, 11, 1), + '11 2005': datetime.datetime(2005, 11, 1), + '200511': datetime.datetime(2020, 5, 11), + '20051109': datetime.datetime(2005, 11, 9), + + '20051109 10:15': datetime.datetime(2005, 11, 9, 10, 15), + '20051109 08H': datetime.datetime(2005, 11, 9, 8, 0), + + '2005-11-09 10:15': datetime.datetime(2005, 11, 9, 10, 15), + '2005-11-09 08H': datetime.datetime(2005, 11, 9, 8, 0), + '2005/11/09 10:15': datetime.datetime(2005, 11, 9, 10, 15), + '2005/11/09 08H': datetime.datetime(2005, 11, 9, 8, 0), + + "Thu Sep 25 10:36:28 2003": datetime.datetime(2003, 9, 25, 10, 36, 28), + "Thu Sep 25 2003": datetime.datetime(2003, 9, 25), + "Sep 25 2003": datetime.datetime(2003, 9, 25), + "January 1 2014": datetime.datetime(2014, 1, 1), + + # GH 10537 + '2014-06': datetime.datetime(2014, 6, 1), + '06-2014': datetime.datetime(2014, 6, 1), + '2014-6': datetime.datetime(2014, 6, 1), + '6-2014': datetime.datetime(2014, 6, 1), + } + + for date_str, expected in compat.iteritems(cases): + result1, _, _ = tools.parse_time_string(date_str) + result2 = to_datetime(date_str) + result3 = to_datetime([date_str]) + result4 = to_datetime(np.array([date_str], dtype=object)) + result5 = Timestamp(date_str) + result6 = DatetimeIndex([date_str])[0] + result7 = date_range(date_str, freq='S', periods=1) + self.assertEqual(result1, expected) + self.assertEqual(result2, expected) + self.assertEqual(result3, expected) + self.assertEqual(result4, expected) + self.assertEqual(result5, expected) + self.assertEqual(result6, expected) + self.assertEqual(result7, expected) + + # NaT + result1, _, _ = tools.parse_time_string('NaT') + result2 = to_datetime('NaT') + result3 = Timestamp('NaT') + result4 = DatetimeIndex(['NaT'])[0] + self.assertTrue(result1 is tslib.NaT) + self.assertTrue(result1 is tslib.NaT) + self.assertTrue(result1 is tslib.NaT) + self.assertTrue(result1 is tslib.NaT) + + def test_parsers_quarter_invalid(self): + + cases = ['2Q 2005', '2Q-200A', '2Q-200', + '22Q2005', '6Q-20', '2Q200.'] + for case in cases: + self.assertRaises(ValueError, tools.parse_time_string, case) + + def test_parsers_dayfirst_yearfirst(self): + # str : dayfirst, yearfirst, expected + cases = {'10-11-12': [(False, False, datetime.datetime(2012, 10, 11)), + (True, False, datetime.datetime(2012, 11, 10)), + (False, True, datetime.datetime(2010, 11, 12)), + (True, True, datetime.datetime(2010, 11, 12))], + '20/12/21': [(False, False, datetime.datetime(2021, 12, 20)), + (True, False, datetime.datetime(2021, 12, 20)), + (False, True, datetime.datetime(2020, 12, 21)), + (True, True, datetime.datetime(2020, 12, 21))]} + + tm._skip_if_no_dateutil() + from dateutil.parser import parse + for date_str, values in compat.iteritems(cases): + for dayfirst, yearfirst ,expected in values: + result1, _, _ = tools.parse_time_string(date_str, dayfirst=dayfirst, + yearfirst=yearfirst) + + result2 = to_datetime(date_str, dayfirst=dayfirst, + yearfirst=yearfirst) + + result3 = DatetimeIndex([date_str], dayfirst=dayfirst, + yearfirst=yearfirst)[0] + + # Timestamp doesn't support dayfirst and yearfirst + + self.assertEqual(result1, expected) + self.assertEqual(result2, expected) + self.assertEqual(result3, expected) + + # compare with dateutil result + dateutil_result = parse(date_str, dayfirst=dayfirst, yearfirst=yearfirst) + self.assertEqual(dateutil_result, expected) + + def test_parsers_timestring(self): + tm._skip_if_no_dateutil() + from dateutil.parser import parse + + # must be the same as dateutil result + cases = {'10:15': (parse('10:15'), datetime.datetime(1, 1, 1, 10, 15)), + '9:05': (parse('9:05'), datetime.datetime(1, 1, 1, 9, 5)) } + + for date_str, (exp_now, exp_def) in compat.iteritems(cases): + result1, _, _ = tools.parse_time_string(date_str) + result2 = to_datetime(date_str) + result3 = to_datetime([date_str]) + result4 = Timestamp(date_str) + result5 = DatetimeIndex([date_str])[0] + # parse time string return time string based on default date + # others are not, and can't be changed because it is used in + # time series plot + self.assertEqual(result1, exp_def) + self.assertEqual(result2, exp_now) + self.assertEqual(result3, exp_now) + self.assertEqual(result4, exp_now) + self.assertEqual(result5, exp_now) + + def test_parsers_monthfreq(self): + cases = {'201101': datetime.datetime(2011, 1, 1, 0, 0), + '200005': datetime.datetime(2000, 5, 1, 0, 0)} + + for date_str, expected in compat.iteritems(cases): + result1, _, _ = tools.parse_time_string(date_str, freq='M') + result2 = tools._to_datetime(date_str, freq='M') + self.assertEqual(result1, expected) + self.assertEqual(result2, expected) + + def test_parsers_quarterly_with_freq(self): + + msg = 'Incorrect quarterly string is given, quarter must be between 1 and 4: 2013Q5' + with tm.assertRaisesRegexp(tslib.DateParseError, msg): + tools.parse_time_string('2013Q5') + + # GH 5418 + msg = 'Unable to retrieve month information from given freq: INVLD-L-DEC-SAT' + with tm.assertRaisesRegexp(tslib.DateParseError, msg): + tools.parse_time_string('2013Q1', freq='INVLD-L-DEC-SAT') + + cases = {('2013Q2', None): datetime.datetime(2013, 4, 1), + ('2013Q2', 'A-APR'): datetime.datetime(2012, 8, 1), + ('2013-Q2', 'A-DEC'): datetime.datetime(2013, 4, 1)} + + for (date_str, freq), exp in compat.iteritems(cases): + result, _, _ = tools.parse_time_string(date_str, freq=freq) + self.assertEqual(result, exp) + class TestArrayToDatetime(tm.TestCase): def test_parsing_valid_dates(self): @@ -476,10 +652,10 @@ def test_number_looking_strings_not_into_datetime(self): # These strings don't look like datetimes so they shouldn't be # attempted to be converted arr = np.array(['-352.737091', '183.575577'], dtype=object) - self.assert_numpy_array_equal(tslib.array_to_datetime(arr), arr) + self.assert_numpy_array_equal(tslib.array_to_datetime(arr, errors='ignore'), arr) arr = np.array(['1', '2', '3', '4', '5'], dtype=object) - self.assert_numpy_array_equal(tslib.array_to_datetime(arr), arr) + self.assert_numpy_array_equal(tslib.array_to_datetime(arr, errors='ignore'), arr) def test_coercing_dates_outside_of_datetime64_ns_bounds(self): invalid_dates = [ @@ -495,13 +671,12 @@ def test_coercing_dates_outside_of_datetime64_ns_bounds(self): ValueError, tslib.array_to_datetime, np.array([invalid_date], dtype='object'), - coerce=False, - raise_=True, + errors='raise', ) self.assertTrue( np.array_equal( tslib.array_to_datetime( - np.array([invalid_date], dtype='object'), coerce=True + np.array([invalid_date], dtype='object'), errors='coerce', ), np.array([tslib.iNaT], dtype='M8[ns]') ) @@ -509,7 +684,7 @@ def test_coercing_dates_outside_of_datetime64_ns_bounds(self): arr = np.array(['1/1/1000', '1/1/2000'], dtype=object) self.assert_numpy_array_equal( - tslib.array_to_datetime(arr, coerce=True), + tslib.array_to_datetime(arr, errors='coerce'), np.array( [ tslib.iNaT, @@ -524,11 +699,11 @@ def test_coerce_of_invalid_datetimes(self): # Without coercing, the presence of any invalid dates prevents # any values from being converted - self.assert_numpy_array_equal(tslib.array_to_datetime(arr), arr) + self.assert_numpy_array_equal(tslib.array_to_datetime(arr,errors='ignore'), arr) # With coercing, the invalid dates becomes iNaT self.assert_numpy_array_equal( - tslib.array_to_datetime(arr, coerce=True), + tslib.array_to_datetime(arr, errors='coerce'), np.array( [ '2013-01-01T00:00:00.000000000-0000', diff --git a/pandas/tseries/timedeltas.py b/pandas/tseries/timedeltas.py index 624981c5536f5..886d6ff42ced6 100644 --- a/pandas/tseries/timedeltas.py +++ b/pandas/tseries/timedeltas.py @@ -9,8 +9,11 @@ from pandas.core.common import (ABCSeries, is_integer_dtype, is_timedelta64_dtype, is_list_like, isnull, _ensure_object) +from pandas.util.decorators import deprecate_kwarg -def to_timedelta(arg, unit='ns', box=True, coerce=False): +@deprecate_kwarg(old_arg_name='coerce', new_arg_name='errors', + mapping={True: 'coerce', False: 'raise'}) +def to_timedelta(arg, unit='ns', box=True, errors='raise', coerce=None): """ Convert argument to timedelta @@ -19,9 +22,12 @@ def to_timedelta(arg, unit='ns', box=True, coerce=False): arg : string, timedelta, array of strings (with possible NAs) unit : unit of the arg (D,h,m,s,ms,us,ns) denote the unit, which is an integer/float number box : boolean, default True - If True returns a Timedelta/TimedeltaIndex of the results - if False returns a np.timedelta64 or ndarray of values of dtype timedelta64[ns] - coerce : force errors to NaT (False by default) + - If True returns a Timedelta/TimedeltaIndex of the results + - if False returns a np.timedelta64 or ndarray of values of dtype timedelta64[ns] + errors : {'ignore', 'raise', 'coerce'}, default 'raise' + - If 'raise', then invalid parsing will raise an exception + - If 'coerce', then invalid parsing will be set as NaT + - If 'ignore', then invalid parsing will return the input Returns ------- @@ -34,22 +40,13 @@ def _convert_listlike(arg, box, unit): if isinstance(arg, (list,tuple)) or ((hasattr(arg,'__iter__') and not hasattr(arg,'dtype'))): arg = np.array(list(arg), dtype='O') + # these are shortcutable if is_timedelta64_dtype(arg): value = arg.astype('timedelta64[ns]') elif is_integer_dtype(arg): - - # these are shortcutable - value = arg.astype('timedelta64[{0}]'.format(unit)).astype('timedelta64[ns]') + value = arg.astype('timedelta64[{0}]'.format(unit)).astype('timedelta64[ns]', copy=False) else: - try: - value = tslib.array_to_timedelta64(_ensure_object(arg), unit=unit, coerce=coerce) - except: - - # try to process strings fast; may need to fallback - try: - value = np.array([ _get_string_converter(r, unit=unit)() for r in arg ],dtype='m8[ns]') - except: - value = np.array([ _coerce_scalar_to_timedelta_type(r, unit=unit, coerce=coerce) for r in arg ]) + value = tslib.array_to_timedelta64(_ensure_object(arg), unit=unit, errors=errors) value = value.astype('timedelta64[ns]', copy=False) if box: @@ -67,7 +64,7 @@ def _convert_listlike(arg, box, unit): return _convert_listlike(arg, box=box, unit=unit) # ...so it must be a scalar value. Return scalar. - return _coerce_scalar_to_timedelta_type(arg, unit=unit, box=box, coerce=coerce) + return _coerce_scalar_to_timedelta_type(arg, unit=unit, box=box, errors=errors) _unit_map = { 'Y' : 'Y', @@ -95,15 +92,6 @@ def _convert_listlike(arg, box, unit): 'NS' : 'ns', 'ns' : 'ns', } -_unit_scale = { - 'd' : 86400*1e9, - 'h' : 3600*1e9, - 'm' : 60*1e9, - 's' : 1e9, - 'ms' : 1e6, - 'us' : 1e3, - 'ns' : 1, - } def _validate_timedelta_unit(arg): """ provide validation / translation for timedelta short units """ @@ -114,150 +102,11 @@ def _validate_timedelta_unit(arg): return 'ns' raise ValueError("invalid timedelta unit {0} provided".format(arg)) -_short_search = re.compile( - "^\s*(?P-?)\s*(?P\d*\.?\d*)\s*(?Pd|s|ms|us|ns)?\s*$",re.IGNORECASE) -_full_search = re.compile( - "^\s*(?P-?)\s*(?P\d*?\.?\d*?)?\s*(days|d|day)?,?\s*\+?(?P
  • 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