1054a1230c49dc49d09c015ed83f9aeb3a96b87daLuis Lozano# We did not author this file nor mantain it. Skip linting it.
2054a1230c49dc49d09c015ed83f9aeb3a96b87daLuis Lozano#pylint: skip-file
34467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif# Copyright (c) 1999-2007 Gary Strangman; All Rights Reserved.
44467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif#
54467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif# Permission is hereby granted, free of charge, to any person obtaining a copy
64467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif# of this software and associated documentation files (the "Software"), to deal
74467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif# in the Software without restriction, including without limitation the rights
84467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
94467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif# copies of the Software, and to permit persons to whom the Software is
104467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif# furnished to do so, subject to the following conditions:
115dd0459f8a7207ddcee26baa4917c2a6e20fba67Luis Lozano#
124467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif# The above copyright notice and this permission notice shall be included in
134467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif# all copies or substantial portions of the Software.
145dd0459f8a7207ddcee26baa4917c2a6e20fba67Luis Lozano#
154467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
164467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
174467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
184467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
194467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
204467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
214467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif# THE SOFTWARE.
224467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif#
234467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif# Comments and/or additions are welcome (send e-mail to:
244467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif# strang@nmr.mgh.harvard.edu).
25f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano#
26f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano"""pstat.py module
274467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
284467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif#################################################
294467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif#######  Written by:  Gary Strangman  ###########
304467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif#######  Last modified:  Dec 18, 2007 ###########
314467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif#################################################
324467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
334467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifThis module provides some useful list and array manipulation routines
344467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifmodeled after those found in the |Stat package by Gary Perlman, plus a
354467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifnumber of other useful list/file manipulation functions.  The list-based
364467f004e7f0854963bec90daff1879fbd9d2fecAhmad Shariffunctions include:
374467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
384467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      abut (source,*args)
394467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      simpleabut (source, addon)
404467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      colex (listoflists,cnums)
414467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      collapse (listoflists,keepcols,collapsecols,fcn1=None,fcn2=None,cfcn=None)
424467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      dm (listoflists,criterion)
434467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      flat (l)
444467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      linexand (listoflists,columnlist,valuelist)
454467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      linexor (listoflists,columnlist,valuelist)
464467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      linedelimited (inlist,delimiter)
47f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      lineincols (inlist,colsize)
484467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      lineincustcols (inlist,colsizes)
494467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      list2string (inlist)
504467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      makelol(inlist)
514467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      makestr(x)
524467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      printcc (lst,extra=2)
534467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      printincols (listoflists,colsize)
544467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      pl (listoflists)
554467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      printl(listoflists)
564467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      replace (lst,oldval,newval)
574467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      recode (inlist,listmap,cols='all')
584467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      remap (listoflists,criterion)
594467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      roundlist (inlist,num_digits_to_round_floats_to)
604467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      sortby(listoflists,sortcols)
614467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      unique (inlist)
624467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      duplicates(inlist)
634467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      writedelimited (listoflists, delimiter, file, writetype='w')
644467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
654467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifSome of these functions have alternate versions which are defined only if
664467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifNumeric (NumPy) can be imported.  These functions are generally named as
674467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifabove, with an 'a' prefix.
684467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
694467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      aabut (source, *args)
704467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      acolex (a,indices,axis=1)
714467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      acollapse (a,keepcols,collapsecols,sterr=0,ns=0)
724467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      adm (a,criterion)
734467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      alinexand (a,columnlist,valuelist)
744467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      alinexor (a,columnlist,valuelist)
754467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      areplace (a,oldval,newval)
764467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      arecode (a,listmap,col='all')
774467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      arowcompare (row1, row2)
784467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      arowsame (row1, row2)
794467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      asortrows(a,axis=0)
804467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      aunique(inarray)
814467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif      aduplicates(inarray)
824467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
834467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifCurrently, the code is all but completely un-optimized.  In many cases, the
844467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifarray versions of functions amount simply to aliases to built-in array
854467f004e7f0854963bec90daff1879fbd9d2fecAhmad Shariffunctions/methods.  Their inclusion here is for function name consistency.
864467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
874467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
884467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif## CHANGE LOG:
894467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif## ==========
904467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif## 07-11-26 ... edited to work with numpy
914467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif## 01-11-15 ... changed list2string() to accept a delimiter
924467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif## 01-06-29 ... converted exec()'s to eval()'s to make compatible with Py2.1
934467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif## 01-05-31 ... added duplicates() and aduplicates() functions
944467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif## 00-12-28 ... license made GPL, docstring and import requirements
954467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif## 99-11-01 ... changed version to 0.3
964467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif## 99-08-30 ... removed get, getstrings, put, aget, aput (into io.py)
974467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif## 03/27/99 ... added areplace function, made replace fcn recursive
984467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif## 12/31/98 ... added writefc function for ouput to fixed column sizes
994467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif## 12/07/98 ... fixed import problem (failed on collapse() fcn)
1004467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif##              added __version__ variable (now 0.2)
1014467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif## 12/05/98 ... updated doc-strings
1024467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif##              added features to collapse() function
1034467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif##              added flat() function for lists
1045dd0459f8a7207ddcee26baa4917c2a6e20fba67Luis Lozano##              fixed a broken asortrows()
1054467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif## 11/16/98 ... fixed minor bug in aput for 1D arrays
1064467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif##
1074467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif## 11/08/98 ... fixed aput to output large arrays correctly
1084467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
1094467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifimport stats  # required 3rd party module
1104467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifimport string, copy
1114467f004e7f0854963bec90daff1879fbd9d2fecAhmad Shariffrom types import *
1124467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
1134467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif__version__ = 0.4
1144467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
1154467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif###===========================  LIST FUNCTIONS  ==========================
1164467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif###
1174467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif### Here are the list functions, DEFINED FOR ALL SYSTEMS.
1184467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif### Array functions (for NumPy-enabled computers) appear below.
1194467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif###
1204467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
121f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano
122f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozanodef abut(source, *args):
123f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  """
1244467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifLike the |Stat abut command.  It concatenates two lists side-by-side
1254467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifand returns the result.  '2D' lists are also accomodated for either argument
1264467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif(source or addon).  CAUTION:  If one list is shorter, it will be repeated
1274467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifuntil it is as long as the longest list.  If this behavior is not desired,
1284467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifuse pstat.simpleabut().
1294467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
1304467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   abut(source, args)   where args=any # of lists
1314467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns: a list of lists as long as the LONGEST list past, source on the
1324467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif         'left', lists in <args> attached consecutively on the 'right'
1334467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
1344467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
135f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  if type(source) not in [ListType, TupleType]:
136f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    source = [source]
137f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  for addon in args:
138f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if type(addon) not in [ListType, TupleType]:
139f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      addon = [addon]
140f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if len(addon) < len(source):  # is source list longer?
141f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      if len(source) % len(addon) == 0:  # are they integer multiples?
142f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        repeats = len(source) / len(addon)  # repeat addon n times
143f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        origadd = copy.deepcopy(addon)
144f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        for i in range(repeats - 1):
145f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          addon = addon + origadd
146f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      else:
147f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        repeats = len(source) / len(addon) + 1  # repeat addon x times,
148f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        origadd = copy.deepcopy(addon)  #    x is NOT an integer
149f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        for i in range(repeats - 1):
150f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          addon = addon + origadd
151f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          addon = addon[0:len(source)]
152f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    elif len(source) < len(addon):  # is addon list longer?
153f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      if len(addon) % len(source) == 0:  # are they integer multiples?
154f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        repeats = len(addon) / len(source)  # repeat source n times
155f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        origsour = copy.deepcopy(source)
156f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        for i in range(repeats - 1):
157f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          source = source + origsour
158f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      else:
159f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        repeats = len(addon) / len(source) + 1  # repeat source x times,
160f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        origsour = copy.deepcopy(source)  #   x is NOT an integer
161f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        for i in range(repeats - 1):
162f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          source = source + origsour
163f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        source = source[0:len(addon)]
164f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano
165f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    source = simpleabut(source, addon)
166f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  return source
167f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano
168f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano
169f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozanodef simpleabut(source, addon):
170f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  """
1714467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifConcatenates two lists as columns and returns the result.  '2D' lists
1724467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifare also accomodated for either argument (source or addon).  This DOES NOT
1734467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifrepeat either list to make the 2 lists of equal length.  Beware of list pairs
1744467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifwith different lengths ... the resulting list will be the length of the
1754467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifFIRST list passed.
1764467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
1774467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   simpleabut(source,addon)  where source, addon=list (or list-of-lists)
1784467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns: a list of lists as long as source, with source on the 'left' and
1794467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif                 addon on the 'right'
1804467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
181f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  if type(source) not in [ListType, TupleType]:
182f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    source = [source]
183f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  if type(addon) not in [ListType, TupleType]:
184f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    addon = [addon]
185f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  minlen = min(len(source), len(addon))
186f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  list = copy.deepcopy(source)  # start abut process
187f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  if type(source[0]) not in [ListType, TupleType]:
188f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if type(addon[0]) not in [ListType, TupleType]:
189f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      for i in range(minlen):
190f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        list[i] = [source[i]] + [addon[i]]  # source/addon = column
1914467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    else:
192f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      for i in range(minlen):
193f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        list[i] = [source[i]] + addon[i]  # addon=list-of-lists
194f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  else:
195f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if type(addon[0]) not in [ListType, TupleType]:
196f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      for i in range(minlen):
197f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        list[i] = source[i] + [addon[i]]  # source=list-of-lists
198f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    else:
199f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      for i in range(minlen):
200f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        list[i] = source[i] + addon[i]  # source/addon = list-of-lists
201f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  source = list
202f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  return source
2034467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
2044467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
205f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozanodef colex(listoflists, cnums):
206f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  """
2074467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifExtracts from listoflists the columns specified in the list 'cnums'
2084467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif(cnums can be an integer, a sequence of integers, or a string-expression that
2094467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifcorresponds to a slice operation on the variable x ... e.g., 'x[3:]' will colex
2104467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifcolumns 3 onward from the listoflists).
2114467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
2124467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   colex (listoflists,cnums)
2134467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns: a list-of-lists corresponding to the columns from listoflists
2144467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif         specified by cnums, in the order the column numbers appear in cnums
2154467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
216f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  global index
217f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  column = 0
218f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  if type(cnums) in [ListType, TupleType]:  # if multiple columns to get
219f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    index = cnums[0]
220f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    column = map(lambda x: x[index], listoflists)
221f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    for col in cnums[1:]:
222f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      index = col
223f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      column = abut(column, map(lambda x: x[index], listoflists))
224f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  elif type(cnums) == StringType:  # if an 'x[3:]' type expr.
225f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    evalstring = 'map(lambda x: x' + cnums + ', listoflists)'
226f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    column = eval(evalstring)
227f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  else:  # else it's just 1 col to get
228f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    index = cnums
229f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    column = map(lambda x: x[index], listoflists)
230f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  return column
231f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano
232f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano
233f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozanodef collapse(listoflists,
234f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano             keepcols,
235f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano             collapsecols,
236f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano             fcn1=None,
237f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano             fcn2=None,
238f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano             cfcn=None):
239f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  """
2404467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifAverages data in collapsecol, keeping all unique items in keepcols
2414467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif(using unique, which keeps unique LISTS of column numbers), retaining the
2424467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifunique sets of values in keepcols, the mean for each.  Setting fcn1
2434467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifand/or fcn2 to point to a function rather than None (e.g., stats.sterr, len)
2444467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifwill append those results (e.g., the sterr, N) after each calculated mean.
2454467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifcfcn is the collapse function to apply (defaults to mean, defined here in the
2464467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifpstat module to avoid circular imports with stats.py, but harmonicmean or
2474467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifothers could be passed).
2484467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
249f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis LozanoUsage:    collapse
250f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano(listoflists,keepcols,collapsecols,fcn1=None,fcn2=None,cfcn=None)
2514467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns: a list of lists with all unique permutations of entries appearing in
2524467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif     columns ("conditions") specified by keepcols, abutted with the result of
2534467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif     cfcn (if cfcn=None, defaults to the mean) of each column specified by
2544467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif     collapsecols.
2554467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
256f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano
257f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  def collmean(inlist):
258f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    s = 0
259f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    for item in inlist:
260f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      s = s + item
261f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    return s / float(len(inlist))
262f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano
263f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  if type(keepcols) not in [ListType, TupleType]:
264f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    keepcols = [keepcols]
265f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  if type(collapsecols) not in [ListType, TupleType]:
266f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    collapsecols = [collapsecols]
267f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  if cfcn == None:
268f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    cfcn = collmean
269f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  if keepcols == []:
270f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    means = [0] * len(collapsecols)
271f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    for i in range(len(collapsecols)):
272f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      avgcol = colex(listoflists, collapsecols[i])
273f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      means[i] = cfcn(avgcol)
274f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      if fcn1:
275f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        try:
276f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          test = fcn1(avgcol)
277f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        except:
278f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          test = 'N/A'
279f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          means[i] = [means[i], test]
280f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      if fcn2:
281f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        try:
282f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          test = fcn2(avgcol)
283f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        except:
284f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          test = 'N/A'
285f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        try:
286f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          means[i] = means[i] + [len(avgcol)]
287f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        except TypeError:
288f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          means[i] = [means[i], len(avgcol)]
289f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    return means
290f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  else:
291f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    values = colex(listoflists, keepcols)
292f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    uniques = unique(values)
293f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    uniques.sort()
294f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    newlist = []
295f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if type(keepcols) not in [ListType, TupleType]:
296f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      keepcols = [keepcols]
297f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    for item in uniques:
298f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      if type(item) not in [ListType, TupleType]:
299f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        item = [item]
300f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      tmprows = linexand(listoflists, keepcols, item)
301f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      for col in collapsecols:
302f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        avgcol = colex(tmprows, col)
303f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        item.append(cfcn(avgcol))
304f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        if fcn1 <> None:
305f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          try:
306f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano            test = fcn1(avgcol)
307f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          except:
308f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano            test = 'N/A'
309f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          item.append(test)
310f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        if fcn2 <> None:
311f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          try:
312f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano            test = fcn2(avgcol)
313f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          except:
314f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano            test = 'N/A'
315f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          item.append(test)
316f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        newlist.append(item)
317f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    return newlist
318f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano
319f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano
320f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozanodef dm(listoflists, criterion):
321f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  """
3224467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns rows from the passed list of lists that meet the criteria in
3234467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifthe passed criterion expression (a string as a function of x; e.g., 'x[3]>=9'
3244467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifwill return all rows where the 4th column>=9 and "x[2]=='N'" will return rows
3254467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifwith column 2 equal to the string 'N').
3264467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
3274467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   dm (listoflists, criterion)
3284467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns: rows from listoflists that meet the specified criterion.
3294467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
330f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  function = 'filter(lambda x: ' + criterion + ',listoflists)'
331f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  lines = eval(function)
332f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  return lines
3334467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
3344467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
3354467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifdef flat(l):
336f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  """
3374467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns the flattened version of a '2D' list.  List-correlate to the a.ravel()()
3384467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifmethod of NumPy arrays.
3394467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
3404467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:    flat(l)
3414467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
342f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  newl = []
343f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  for i in range(len(l)):
344f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    for j in range(len(l[i])):
345f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      newl.append(l[i][j])
346f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  return newl
3474467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
3484467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
349f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozanodef linexand(listoflists, columnlist, valuelist):
350f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  """
3514467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns the rows of a list of lists where col (from columnlist) = val
3524467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif(from valuelist) for EVERY pair of values (columnlist[i],valuelists[i]).
3534467f004e7f0854963bec90daff1879fbd9d2fecAhmad Shariflen(columnlist) must equal len(valuelist).
3544467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
3554467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   linexand (listoflists,columnlist,valuelist)
3564467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns: the rows of listoflists where columnlist[i]=valuelist[i] for ALL i
3574467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
358f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  if type(columnlist) not in [ListType, TupleType]:
359f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    columnlist = [columnlist]
360f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  if type(valuelist) not in [ListType, TupleType]:
361f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    valuelist = [valuelist]
362f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  criterion = ''
363f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  for i in range(len(columnlist)):
364f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if type(valuelist[i]) == StringType:
365f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      critval = '\'' + valuelist[i] + '\''
366f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    else:
367f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      critval = str(valuelist[i])
368f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    criterion = criterion + ' x[' + str(columnlist[
369f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        i]) + ']==' + critval + ' and'
370f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  criterion = criterion[0:-3]  # remove the "and" after the last crit
371f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  function = 'filter(lambda x: ' + criterion + ',listoflists)'
372f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  lines = eval(function)
373f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  return lines
3744467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
3754467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
376f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozanodef linexor(listoflists, columnlist, valuelist):
377f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  """
3784467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns the rows of a list of lists where col (from columnlist) = val
3794467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif(from valuelist) for ANY pair of values (colunmlist[i],valuelist[i[).
3804467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifOne value is required for each column in columnlist.  If only one value
3814467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifexists for columnlist but multiple values appear in valuelist, the
3824467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifvaluelist values are all assumed to pertain to the same column.
3834467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
3844467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   linexor (listoflists,columnlist,valuelist)
3854467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns: the rows of listoflists where columnlist[i]=valuelist[i] for ANY i
3864467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
387f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  if type(columnlist) not in [ListType, TupleType]:
388f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    columnlist = [columnlist]
389f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  if type(valuelist) not in [ListType, TupleType]:
390f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    valuelist = [valuelist]
391f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  criterion = ''
392f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  if len(columnlist) == 1 and len(valuelist) > 1:
393f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    columnlist = columnlist * len(valuelist)
394f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  for i in range(len(columnlist)):  # build an exec string
395f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if type(valuelist[i]) == StringType:
396f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      critval = '\'' + valuelist[i] + '\''
397f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    else:
398f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      critval = str(valuelist[i])
399f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    criterion = criterion + ' x[' + str(columnlist[i]) + ']==' + critval + ' or'
400f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  criterion = criterion[0:-2]  # remove the "or" after the last crit
401f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  function = 'filter(lambda x: ' + criterion + ',listoflists)'
402f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  lines = eval(function)
403f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  return lines
4044467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
4054467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
406f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozanodef linedelimited(inlist, delimiter):
407f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  """
4084467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns a string composed of elements in inlist, with each element
4094467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifseparated by 'delimiter.'  Used by function writedelimited.  Use '\t'
4104467f004e7f0854963bec90daff1879fbd9d2fecAhmad Shariffor tab-delimiting.
4114467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
4124467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   linedelimited (inlist,delimiter)
4134467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
414f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  outstr = ''
415f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  for item in inlist:
416f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if type(item) <> StringType:
417f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      item = str(item)
418f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    outstr = outstr + item + delimiter
419f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  outstr = outstr[0:-1]
420f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  return outstr
4214467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
4224467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
423f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozanodef lineincols(inlist, colsize):
424f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  """
4254467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns a string composed of elements in inlist, with each element
4264467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifright-aligned in columns of (fixed) colsize.
4274467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
4284467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   lineincols (inlist,colsize)   where colsize is an integer
4294467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
430f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  outstr = ''
431f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  for item in inlist:
432f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if type(item) <> StringType:
433f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      item = str(item)
434f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    size = len(item)
435f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if size <= colsize:
436f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      for i in range(colsize - size):
437f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        outstr = outstr + ' '
438f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      outstr = outstr + item
439f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    else:
440f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      outstr = outstr + item[0:colsize + 1]
441f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  return outstr
4424467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
4434467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
444f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozanodef lineincustcols(inlist, colsizes):
445f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  """
4464467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns a string composed of elements in inlist, with each element
4474467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifright-aligned in a column of width specified by a sequence colsizes.  The
4484467f004e7f0854963bec90daff1879fbd9d2fecAhmad Shariflength of colsizes must be greater than or equal to the number of columns
4494467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifin inlist.
4504467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
4514467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   lineincustcols (inlist,colsizes)
4524467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns: formatted string created from inlist
4534467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
454f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  outstr = ''
455f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  for i in range(len(inlist)):
456f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if type(inlist[i]) <> StringType:
457f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      item = str(inlist[i])
458f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    else:
459f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      item = inlist[i]
460f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    size = len(item)
461f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if size <= colsizes[i]:
462f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      for j in range(colsizes[i] - size):
463f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        outstr = outstr + ' '
464f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      outstr = outstr + item
465f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    else:
466f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      outstr = outstr + item[0:colsizes[i] + 1]
467f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  return outstr
4684467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
4694467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
470f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozanodef list2string(inlist, delimit=' '):
471f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  """
4724467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifConverts a 1D list to a single long string for file output, using
4734467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifthe string.join function.
4744467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
4754467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   list2string (inlist,delimit=' ')
4764467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns: the string created from inlist
4774467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
478f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  stringlist = map(makestr, inlist)
479f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  return string.join(stringlist, delimit)
4804467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
4814467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
4824467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifdef makelol(inlist):
483f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  """
4844467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifConverts a 1D list to a 2D list (i.e., a list-of-lists).  Useful when you
4854467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifwant to use put() to write a 1D list one item per line in the file.
4864467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
4874467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   makelol(inlist)
4884467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns: if l = [1,2,'hi'] then returns [[1],[2],['hi']] etc.
4894467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
490f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  x = []
491f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  for item in inlist:
492f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    x.append([item])
493f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  return x
4944467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
4954467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
496f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozanodef makestr(x):
497f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  if type(x) <> StringType:
498f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    x = str(x)
499f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  return x
5004467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
5014467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
502f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozanodef printcc(lst, extra=2):
503f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  """
5044467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifPrints a list of lists in columns, customized by the max size of items
5054467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifwithin the columns (max size of items in col, plus 'extra' number of spaces).
5064467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUse 'dashes' or '\\n' in the list-of-lists to print dashes or blank lines,
5074467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifrespectively.
5084467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
5094467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   printcc (lst,extra=2)
5104467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns: None
5114467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
512f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  if type(lst[0]) not in [ListType, TupleType]:
513f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    lst = [lst]
514f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  rowstokill = []
515f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  list2print = copy.deepcopy(lst)
516f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  for i in range(len(lst)):
517f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if lst[i] == [
518f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        '\n'
519f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    ] or lst[i] == '\n' or lst[i] == 'dashes' or lst[i] == '' or lst[i] == ['']:
520f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      rowstokill = rowstokill + [i]
521f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  rowstokill.reverse()  # delete blank rows from the end
522f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  for row in rowstokill:
523f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    del list2print[row]
524f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  maxsize = [0] * len(list2print[0])
525f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  for col in range(len(list2print[0])):
526f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    items = colex(list2print, col)
527f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    items = map(makestr, items)
528f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    maxsize[col] = max(map(len, items)) + extra
529f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  for row in lst:
530f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if row == ['\n'] or row == '\n' or row == '' or row == ['']:
531f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      print
532f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    elif row == ['dashes'] or row == 'dashes':
533f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      dashes = [0] * len(maxsize)
534f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      for j in range(len(maxsize)):
535f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        dashes[j] = '-' * (maxsize[j] - 2)
536f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      print lineincustcols(dashes, maxsize)
537f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    else:
538f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      print lineincustcols(row, maxsize)
539f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  return None
5404467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
5414467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
542f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozanodef printincols(listoflists, colsize):
543f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  """
5444467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifPrints a list of lists in columns of (fixed) colsize width, where
5454467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifcolsize is an integer.
5464467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
5474467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   printincols (listoflists,colsize)
5484467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns: None
5494467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
550f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  for row in listoflists:
551f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    print lineincols(row, colsize)
552f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  return None
5534467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
5544467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
555f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozanodef pl(listoflists):
556f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  """
5574467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifPrints a list of lists, 1 list (row) at a time.
5584467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
5594467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   pl(listoflists)
5604467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns: None
5614467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
562f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  for row in listoflists:
563f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if row[-1] == '\n':
564f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      print row,
565f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    else:
566f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      print row
567f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  return None
5684467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
5694467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
5704467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifdef printl(listoflists):
571f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  """Alias for pl."""
572f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  pl(listoflists)
573f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  return
5744467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
5754467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
576f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozanodef replace(inlst, oldval, newval):
577f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  """
5784467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReplaces all occurrences of 'oldval' with 'newval', recursively.
5794467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
5804467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   replace (inlst,oldval,newval)
5814467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
582f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  lst = inlst * 1
583f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  for i in range(len(lst)):
584f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if type(lst[i]) not in [ListType, TupleType]:
585f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      if lst[i] == oldval:
586f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        lst[i] = newval
587f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    else:
588f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      lst[i] = replace(lst[i], oldval, newval)
589f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  return lst
5904467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
5914467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
592f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozanodef recode(inlist, listmap, cols=None):
593f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  """
5944467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifChanges the values in a list to a new set of values (useful when
5954467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifyou need to recode data from (e.g.) strings to numbers.  cols defaults
5964467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifto None (meaning all columns are recoded).
5974467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
5984467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   recode (inlist,listmap,cols=None)  cols=recode cols, listmap=2D list
5994467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns: inlist with the appropriate values replaced with new ones
6004467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
601f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  lst = copy.deepcopy(inlist)
602f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  if cols != None:
603f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if type(cols) not in [ListType, TupleType]:
604f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      cols = [cols]
605f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    for col in cols:
606f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      for row in range(len(lst)):
607f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        try:
608f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          idx = colex(listmap, 0).index(lst[row][col])
609f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          lst[row][col] = listmap[idx][1]
610f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        except ValueError:
611f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          pass
612f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  else:
613f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    for row in range(len(lst)):
614f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      for col in range(len(lst)):
615f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        try:
616f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          idx = colex(listmap, 0).index(lst[row][col])
617f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          lst[row][col] = listmap[idx][1]
618f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        except ValueError:
619f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          pass
620f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  return lst
6214467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
6224467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
623f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozanodef remap(listoflists, criterion):
624f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  """
6254467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifRemaps values in a given column of a 2D list (listoflists).  This requires
6264467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifa criterion as a function of 'x' so that the result of the following is
627f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozanoreturned ... map(lambda x: 'criterion',listoflists).
6284467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
6294467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   remap(listoflists,criterion)    criterion=string
6304467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns: remapped version of listoflists
6314467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
632f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  function = 'map(lambda x: ' + criterion + ',listoflists)'
633f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  lines = eval(function)
634f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  return lines
6354467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
6364467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
637f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozanodef roundlist(inlist, digits):
638f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  """
6394467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifGoes through each element in a 1D or 2D inlist, and applies the following
6404467f004e7f0854963bec90daff1879fbd9d2fecAhmad Shariffunction to all elements of FloatType ... round(element,digits).
6414467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
6424467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   roundlist(inlist,digits)
6434467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns: list with rounded floats
6444467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
645f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  if type(inlist[0]) in [IntType, FloatType]:
646f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    inlist = [inlist]
647f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  l = inlist * 1
648f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  for i in range(len(l)):
649f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    for j in range(len(l[i])):
650f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      if type(l[i][j]) == FloatType:
651f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        l[i][j] = round(l[i][j], digits)
652f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  return l
653f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano
654f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano
655f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozanodef sortby(listoflists, sortcols):
656f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  """
6574467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifSorts a list of lists on the column(s) specified in the sequence
6584467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifsortcols.
6594467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
6604467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   sortby(listoflists,sortcols)
6614467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns: sorted list, unchanged column ordering
6624467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
663f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  newlist = abut(colex(listoflists, sortcols), listoflists)
664f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  newlist.sort()
665f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  try:
666f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    numcols = len(sortcols)
667f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  except TypeError:
668f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    numcols = 1
669f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  crit = '[' + str(numcols) + ':]'
670f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  newlist = colex(newlist, crit)
671f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  return newlist
672f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano
673f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano
674f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozanodef unique(inlist):
675f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  """
6764467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns all unique items in the passed list.  If the a list-of-lists
6774467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifis passed, unique LISTS are found (i.e., items in the first dimension are
6784467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifcompared).
6794467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
6804467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   unique (inlist)
6814467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns: the unique elements (or rows) in inlist
6824467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
683f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  uniques = []
684f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  for item in inlist:
685f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if item not in uniques:
686f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      uniques.append(item)
687f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  return uniques
688f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano
6894467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
6904467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifdef duplicates(inlist):
691f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  """
6924467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns duplicate items in the FIRST dimension of the passed list.
6934467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
6944467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   duplicates (inlist)
6954467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
696f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  dups = []
697f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  for i in range(len(inlist)):
698f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if inlist[i] in inlist[i + 1:]:
699f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      dups.append(inlist[i])
700f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  return dups
7014467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
7024467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
7034467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifdef nonrepeats(inlist):
704f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  """
7054467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns items that are NOT duplicated in the first dim of the passed list.
7064467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
7074467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   nonrepeats (inlist)
7084467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
709f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  nonrepeats = []
710f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  for i in range(len(inlist)):
711f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if inlist.count(inlist[i]) == 1:
712f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      nonrepeats.append(inlist[i])
713f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  return nonrepeats
7144467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
7154467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif#===================   PSTAT ARRAY FUNCTIONS  =====================
7164467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif#===================   PSTAT ARRAY FUNCTIONS  =====================
7174467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif#===================   PSTAT ARRAY FUNCTIONS  =====================
7184467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif#===================   PSTAT ARRAY FUNCTIONS  =====================
7194467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif#===================   PSTAT ARRAY FUNCTIONS  =====================
7204467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif#===================   PSTAT ARRAY FUNCTIONS  =====================
7214467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif#===================   PSTAT ARRAY FUNCTIONS  =====================
7224467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif#===================   PSTAT ARRAY FUNCTIONS  =====================
7234467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif#===================   PSTAT ARRAY FUNCTIONS  =====================
7244467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif#===================   PSTAT ARRAY FUNCTIONS  =====================
7254467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif#===================   PSTAT ARRAY FUNCTIONS  =====================
7264467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif#===================   PSTAT ARRAY FUNCTIONS  =====================
7274467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif#===================   PSTAT ARRAY FUNCTIONS  =====================
7284467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif#===================   PSTAT ARRAY FUNCTIONS  =====================
7294467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif#===================   PSTAT ARRAY FUNCTIONS  =====================
7304467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif#===================   PSTAT ARRAY FUNCTIONS  =====================
7314467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
732f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozanotry:  # DEFINE THESE *ONLY* IF numpy IS AVAILABLE
733f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  import numpy as N
7344467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
735f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  def aabut(source, *args):
7364467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    """
7374467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifLike the |Stat abut command.  It concatenates two arrays column-wise
7384467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifand returns the result.  CAUTION:  If one array is shorter, it will be
7394467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifrepeated until it is as long as the other.
7404467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
7414467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   aabut (source, args)    where args=any # of arrays
7424467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns: an array as long as the LONGEST array past, source appearing on the
7434467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif         'left', arrays in <args> attached on the 'right'.
7444467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
745f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if len(source.shape) == 1:
746f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      width = 1
747f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      source = N.resize(source, [source.shape[0], width])
7484467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    else:
749f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      width = source.shape[1]
7504467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    for addon in args:
751f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      if len(addon.shape) == 1:
752f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        width = 1
753f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        addon = N.resize(addon, [source.shape[0], width])
754f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      else:
755f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        width = source.shape[1]
756f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      if len(addon) < len(source):
757f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        addon = N.resize(addon, [source.shape[0], addon.shape[1]])
758f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      elif len(source) < len(addon):
759f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        source = N.resize(source, [addon.shape[0], source.shape[1]])
760f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      source = N.concatenate((source, addon), 1)
7614467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    return source
7624467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
763f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  def acolex(a, indices, axis=1):
7644467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    """
7654467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifExtracts specified indices (a list) from passed array, along passed
7664467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifaxis (column extraction is default).  BEWARE: A 1D array is presumed to be a
7674467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifcolumn-array (and that the whole array will be returned as a column).
7684467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
7694467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   acolex (a,indices,axis=1)
7704467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns: the columns of a specified by indices
7714467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
772f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if type(indices) not in [ListType, TupleType, N.ndarray]:
773f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      indices = [indices]
7744467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    if len(N.shape(a)) == 1:
775f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      cols = N.resize(a, [a.shape[0], 1])
7764467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    else:
777f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      #        print a[:3]
778f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      cols = N.take(a, indices, axis)
7794467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif#        print cols[:3]
7804467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    return cols
7814467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
782f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  def acollapse(a, keepcols, collapsecols, fcn1=None, fcn2=None, cfcn=None):
7834467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    """
7844467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifAverages data in collapsecol, keeping all unique items in keepcols
7854467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif(using unique, which keeps unique LISTS of column numbers), retaining
7864467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifthe unique sets of values in keepcols, the mean for each.  If stderror or
7874467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifN of the mean are desired, set either or both parameters to 1.
7884467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
7894467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   acollapse (a,keepcols,collapsecols,fcn1=None,fcn2=None,cfcn=None)
7904467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns: unique 'conditions' specified by the contents of columns specified
7914467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif         by keepcols, abutted with the mean(s) of column(s) specified by
7924467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif         collapsecols
7934467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
7944467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
795f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    def acollmean(inarray):
796f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      return N.sum(N.ravel(inarray))
797f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano
798f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if type(keepcols) not in [ListType, TupleType, N.ndarray]:
799f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      keepcols = [keepcols]
800f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if type(collapsecols) not in [ListType, TupleType, N.ndarray]:
801f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      collapsecols = [collapsecols]
8024467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
8034467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    if cfcn == None:
804f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      cfcn = acollmean
8054467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    if keepcols == []:
806f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      avgcol = acolex(a, collapsecols)
807f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      means = N.sum(avgcol) / float(len(avgcol))
808f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      if fcn1 <> None:
809f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        try:
810f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          test = fcn1(avgcol)
811f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        except:
812f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          test = N.array(['N/A'] * len(means))
813f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        means = aabut(means, test)
814f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      if fcn2 <> None:
815f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        try:
816f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          test = fcn2(avgcol)
817f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        except:
818f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          test = N.array(['N/A'] * len(means))
819f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        means = aabut(means, test)
820f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      return means
821f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    else:
822f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      if type(keepcols) not in [ListType, TupleType, N.ndarray]:
823f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        keepcols = [keepcols]
824f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      values = colex(a, keepcols)  # so that "item" can be appended (below)
825f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      uniques = unique(values)  # get a LIST, so .sort keeps rows intact
826f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      uniques.sort()
827f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      newlist = []
828f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      for item in uniques:
829f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        if type(item) not in [ListType, TupleType, N.ndarray]:
830f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          item = [item]
831f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        tmprows = alinexand(a, keepcols, item)
832f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        for col in collapsecols:
833f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          avgcol = acolex(tmprows, col)
834f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          item.append(acollmean(avgcol))
835f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          if fcn1 <> None:
8364467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif            try:
837f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano              test = fcn1(avgcol)
8384467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif            except:
839f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano              test = 'N/A'
840f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano            item.append(test)
841f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          if fcn2 <> None:
8424467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif            try:
843f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano              test = fcn2(avgcol)
8444467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif            except:
845f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano              test = 'N/A'
846f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano            item.append(test)
847f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          newlist.append(item)
848f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      try:
849f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        new_a = N.array(newlist)
850f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      except TypeError:
851f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        new_a = N.array(newlist, 'O')
852f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      return new_a
853f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano
854f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  def adm(a, criterion):
8554467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    """
8564467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns rows from the passed list of lists that meet the criteria in
8574467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifthe passed criterion expression (a string as a function of x).
8584467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
8594467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   adm (a,criterion)   where criterion is like 'x[2]==37'
8604467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
861f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    function = 'filter(lambda x: ' + criterion + ',a)'
8624467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    lines = eval(function)
8634467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    try:
864f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      lines = N.array(lines)
8654467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    except:
866f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      lines = N.array(lines, dtype='O')
8674467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    return lines
8684467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
869f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  def isstring(x):
870f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if type(x) == StringType:
871f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      return 1
8724467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    else:
873f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      return 0
8744467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
875f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  def alinexand(a, columnlist, valuelist):
8764467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    """
8774467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns the rows of an array where col (from columnlist) = val
8784467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif(from valuelist).  One value is required for each column in columnlist.
8794467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
8804467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   alinexand (a,columnlist,valuelist)
8814467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns: the rows of a where columnlist[i]=valuelist[i] for ALL i
8824467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
883f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if type(columnlist) not in [ListType, TupleType, N.ndarray]:
884f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      columnlist = [columnlist]
885f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if type(valuelist) not in [ListType, TupleType, N.ndarray]:
886f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      valuelist = [valuelist]
8874467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    criterion = ''
8884467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    for i in range(len(columnlist)):
889f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      if type(valuelist[i]) == StringType:
890f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        critval = '\'' + valuelist[i] + '\''
891f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      else:
892f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        critval = str(valuelist[i])
893f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      criterion = criterion + ' x[' + str(columnlist[
894f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          i]) + ']==' + critval + ' and'
895f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    criterion = criterion[0:-3]  # remove the "and" after the last crit
896f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    return adm(a, criterion)
897f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano
898f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  def alinexor(a, columnlist, valuelist):
8994467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    """
9004467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns the rows of an array where col (from columnlist) = val (from
9014467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifvaluelist).  One value is required for each column in columnlist.
9024467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifThe exception is if either columnlist or valuelist has only 1 value,
9034467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifin which case that item will be expanded to match the length of the
9044467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifother list.
9054467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
9064467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   alinexor (a,columnlist,valuelist)
9074467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns: the rows of a where columnlist[i]=valuelist[i] for ANY i
9084467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
909f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if type(columnlist) not in [ListType, TupleType, N.ndarray]:
910f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      columnlist = [columnlist]
911f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if type(valuelist) not in [ListType, TupleType, N.ndarray]:
912f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      valuelist = [valuelist]
9134467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    criterion = ''
9144467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    if len(columnlist) == 1 and len(valuelist) > 1:
915f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      columnlist = columnlist * len(valuelist)
9164467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    elif len(valuelist) == 1 and len(columnlist) > 1:
917f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      valuelist = valuelist * len(columnlist)
9184467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    for i in range(len(columnlist)):
919f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      if type(valuelist[i]) == StringType:
920f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        critval = '\'' + valuelist[i] + '\''
921f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      else:
922f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        critval = str(valuelist[i])
923f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      criterion = criterion + ' x[' + str(columnlist[
924f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          i]) + ']==' + critval + ' or'
925f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    criterion = criterion[0:-2]  # remove the "or" after the last crit
926f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    return adm(a, criterion)
927f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano
928f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  def areplace(a, oldval, newval):
9294467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    """
9304467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReplaces all occurrences of oldval with newval in array a.
9314467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
9324467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   areplace(a,oldval,newval)
9334467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
934f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    return N.where(a == oldval, newval, a)
9354467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
936f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  def arecode(a, listmap, col='all'):
9374467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    """
9384467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifRemaps the values in an array to a new set of values (useful when
9394467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifyou need to recode data from (e.g.) strings to numbers as most stats
9404467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifpackages require.  Can work on SINGLE columns, or 'all' columns at once.
9414467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif@@@BROKEN 2007-11-26
9424467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
9434467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   arecode (a,listmap,col='all')
9444467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns: a version of array a where listmap[i][0] = (instead) listmap[i][1]
9454467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
9464467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    ashape = a.shape
9474467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    if col == 'all':
948f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      work = a.ravel()
9494467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    else:
950f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      work = acolex(a, col)
951f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      work = work.ravel()
9524467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    for pair in listmap:
953f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      if type(pair[
954f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          1]) == StringType or work.dtype.char == 'O' or a.dtype.char == 'O':
955f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        work = N.array(work, dtype='O')
956f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        a = N.array(a, dtype='O')
957f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        for i in range(len(work)):
958f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          if work[i] == pair[0]:
959f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano            work[i] = pair[1]
960f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        if col == 'all':
961f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          return N.reshape(work, ashape)
962f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        else:
963f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          return N.concatenate(
964f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano              [a[:, 0:col], work[:, N.newaxis], a[:, col + 1:]], 1)
965f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      else:  # must be a non-Object type array and replacement
966f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        work = N.where(work == pair[0], pair[1], work)
967f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        return N.concatenate(
968f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano            [a[:, 0:col], work[:, N.newaxis], a[:, col + 1:]], 1)
969f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano
970f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  def arowcompare(row1, row2):
9714467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    """
9724467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifCompares two rows from an array, regardless of whether it is an
9734467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifarray of numbers or of python objects (which requires the cmp function).
9744467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif@@@PURPOSE? 2007-11-26
9754467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
9764467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   arowcompare(row1,row2)
9774467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns: an array of equal length containing 1s where the two rows had
9784467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif         identical elements and 0 otherwise
9794467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
980f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    return
981f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if row1.dtype.char == 'O' or row2.dtype == 'O':
9825dd0459f8a7207ddcee26baa4917c2a6e20fba67Luis Lozano      cmpvect = N.logical_not(
9835dd0459f8a7207ddcee26baa4917c2a6e20fba67Luis Lozano          abs(N.array(map(cmp, row1, row2))))  # cmp fcn gives -1,0,1
9844467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    else:
985f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      cmpvect = N.equal(row1, row2)
9864467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    return cmpvect
9874467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
988f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  def arowsame(row1, row2):
9894467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    """
9904467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifCompares two rows from an array, regardless of whether it is an
9914467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifarray of numbers or of python objects (which requires the cmp function).
9924467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
9934467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   arowsame(row1,row2)
9944467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns: 1 if the two rows are identical, 0 otherwise.
9954467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
996f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    cmpval = N.alltrue(arowcompare(row1, row2))
9974467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    return cmpval
9984467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
999f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  def asortrows(a, axis=0):
10004467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    """
10014467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifSorts an array "by rows".  This differs from the Numeric.sort() function,
10024467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifwhich sorts elements WITHIN the given axis.  Instead, this function keeps
10034467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifthe elements along the given axis intact, but shifts them 'up or down'
10044467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifrelative to one another.
10054467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
10064467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   asortrows(a,axis=0)
10074467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns: sorted version of a
10084467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
1009f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    return N.sort(a, axis=axis, kind='mergesort')
10104467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
1011f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  def aunique(inarray):
10124467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    """
10134467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns unique items in the FIRST dimension of the passed array. Only
10144467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifworks on arrays NOT including string items.
10154467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
10164467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   aunique (inarray)
10174467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
10184467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    uniques = N.array([inarray[0]])
1019f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if len(uniques.shape) == 1:  # IF IT'S A 1D ARRAY
1020f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      for item in inarray[1:]:
1021f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        if N.add.reduce(N.equal(uniques, item).ravel()) == 0:
1022f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          try:
1023f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano            uniques = N.concatenate([uniques, N.array[N.newaxis, :]])
1024f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          except TypeError:
1025f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano            uniques = N.concatenate([uniques, N.array([item])])
1026f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    else:  # IT MUST BE A 2+D ARRAY
1027f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      if inarray.dtype.char != 'O':  # not an Object array
10284467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif        for item in inarray[1:]:
1029f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          if not N.sum(N.alltrue(N.equal(uniques, item), 1)):
1030f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano            try:
1031f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano              uniques = N.concatenate([uniques, item[N.newaxis, :]])
1032f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano            except TypeError:  # the item to add isn't a list
1033f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano              uniques = N.concatenate([uniques, N.array([item])])
1034f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          else:
1035f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano            pass  # this item is already in the uniques array
1036f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      else:  # must be an Object array, alltrue/equal functions don't work
1037f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        for item in inarray[1:]:
1038f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          newflag = 1
1039f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          for unq in uniques:  # NOTE: cmp --> 0=same, -1=<, 1=>
1040f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano            test = N.sum(abs(N.array(map(cmp, item, unq))))
1041f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano            if test == 0:  # if item identical to any 1 row in uniques
1042f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano              newflag = 0  # then not a novel item to add
1043f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano              break
1044f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          if newflag == 1:
1045f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano            try:
1046f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano              uniques = N.concatenate([uniques, item[N.newaxis, :]])
1047f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano            except TypeError:  # the item to add isn't a list
1048f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano              uniques = N.concatenate([uniques, N.array([item])])
10494467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    return uniques
10504467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
1051f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  def aduplicates(inarray):
10524467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    """
10534467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifReturns duplicate items in the FIRST dimension of the passed array. Only
10544467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharifworks on arrays NOT including string items.
10554467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
10564467f004e7f0854963bec90daff1879fbd9d2fecAhmad SharifUsage:   aunique (inarray)
10574467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif"""
10584467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    inarray = N.array(inarray)
1059f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    if len(inarray.shape) == 1:  # IF IT'S A 1D ARRAY
1060f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      dups = []
1061f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      inarray = inarray.tolist()
1062f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      for i in range(len(inarray)):
1063f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        if inarray[i] in inarray[i + 1:]:
1064f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          dups.append(inarray[i])
1065f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      dups = aunique(dups)
1066f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano    else:  # IT MUST BE A 2+D ARRAY
1067f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      dups = []
1068f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      aslist = inarray.tolist()
1069f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      for i in range(len(aslist)):
1070f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano        if aslist[i] in aslist[i + 1:]:
1071f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano          dups.append(aslist[i])
1072f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      dups = unique(dups)
1073f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano      dups = N.array(dups)
10744467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif    return dups
10754467f004e7f0854963bec90daff1879fbd9d2fecAhmad Sharif
1076f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozanoexcept ImportError:  # IF NUMERIC ISN'T AVAILABLE, SKIP ALL arrayfuncs
1077f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano  pass
1078