def norm_zero_one(array, dim=None): """ normalizes a numpy array from 0 to 1 based in its extent Args: array (ndarray): dim (int): Returns: ndarray: CommandLine: python -m utool.util_alg --test-norm_zero_one Example: >>> # ENABLE_DOCTEST >>> from utool.util_alg import * # NOQA >>> array = np.array([ 22, 1, 3, 2, 10, 42, ]) >>> dim = None >>> array_norm = norm_zero_one(array, dim) >>> result = np.array_str(array_norm, precision=3) >>> print(result) [ 0.512 0. 0.049 0.024 0.22 1. ] """ if not util_type.is_float(array): array = array.astype(np.float32) array_max = array.max(dim) array_min = array.min(dim) array_exnt = np.subtract(array_max, array_min) array_norm = np.divide(np.subtract(array, array_min), array_exnt) return array_norm
def num_fmt(num, max_digits=None): r""" Weird function. Not very well written. Very special case-y Args: num (int or float): max_digits (int): Returns: str: CommandLine: python -m utool.util_num --test-num_fmt Example: >>> # DISABLE_DOCTEST >>> from utool.util_num import * # NOQA >>> # build test data >>> num_list = [0, 0.0, 1.2, 1003232, 41431232., .0000000343, -.443243] >>> max_digits = None >>> # execute function >>> result = [num_fmt(num, max_digits) for num in num_list] >>> # verify results >>> print(result) ['0', '0.0', '1.2', '1,003,232', '41431232.0', '0.0', '-0.443'] """ if num is None: return 'None' def num_in_mag(num, mag): return mag > num and num > (-1 * mag) if max_digits is None: # TODO: generalize if num_in_mag(num, 1): if num_in_mag(num, .1): max_digits = 4 else: max_digits = 3 else: max_digits = 1 if util_type.is_float(num): num_str = ('%.' + str(max_digits) + 'f') % num # Handle trailing and leading zeros num_str = num_str.rstrip('0').lstrip('0') if num_str.startswith('.'): num_str = '0' + num_str if num_str.endswith('.'): num_str = num_str + '0' return num_str elif util_type.is_int(num): return int_comma_str(num) else: return '%r'
def num_fmt(num, max_digits=None): r""" Weird function. Not very well written. Very special case-y Args: num (int or float): max_digits (int): Returns: str: CommandLine: python -m utool.util_num --test-num_fmt Example: >>> # DISABLE_DOCTEST >>> from utool.util_num import * # NOQA >>> # build test data >>> num_list = [0, 0.0, 1.2, 1003232, 41431232., .0000000343, -.443243] >>> max_digits = None >>> # execute function >>> result = [num_fmt(num, max_digits) for num in num_list] >>> # verify results >>> print(result) ['0', '0.0', '1.2', '1,003,232', '41431232.0', '0.0', '-0.443'] """ if num is None: return "None" def num_in_mag(num, mag): return mag > num and num > (-1 * mag) if max_digits is None: # TODO: generalize if num_in_mag(num, 1): if num_in_mag(num, 0.1): max_digits = 4 else: max_digits = 3 else: max_digits = 1 if util_type.is_float(num): num_str = ("%." + str(max_digits) + "f") % num # Handle trailing and leading zeros num_str = num_str.rstrip("0").lstrip("0") if num_str.startswith("."): num_str = "0" + num_str if num_str.endswith("."): num_str = num_str + "0" return num_str elif util_type.is_int(num): return int_comma_str(num) else: return "%r"
def make_csv_table(column_list=[], column_lbls=None, header='', column_type=None, row_lbls=None, transpose=False, precision=2, use_lbl_width=True, comma_repl='<com>', raw=False, new=False, standardize=False): """ Creates a csv table with aligned columns make_csv_table Args: column_list (list): column_lbls (None): header (str): column_type (None): row_lbls (None): transpose (bool): Returns: str: csv_text Example: >>> # ENABLE_DOCTEST >>> from utool.util_csv import * # NOQA >>> column_list = [[1, 2, 3], ['A', 'B', 'C']] >>> column_lbls = ['num', 'alpha'] >>> header = '# Test CSV' >>> column_type = (int, str) >>> row_lbls = None >>> transpose = False >>> csv_text = make_csv_table(column_list, column_lbls, header, column_type, row_lbls, transpose) >>> result = csv_text >>> print(result) # Test CSV # num_rows=3 # num, alpha 1, A 2, B 3, C """ import utool as ut assert comma_repl.find(',') == -1, 'comma_repl cannot contain a comma!' if transpose: column_lbls, row_lbls = row_lbls, column_lbls column_list = list(map(list, zip(*column_list))) if row_lbls is not None: if isinstance(column_list, np.ndarray): column_list = column_list.tolist() if isinstance(row_lbls, np.ndarray): row_lbls = row_lbls.tolist() column_list = [row_lbls] + column_list column_lbls = ['ROWLBL'] + list(map(six.text_type, column_lbls)) if column_type is not None: column_type = [six.text_type] + column_type if len(column_list) == 0: print('[csv] No columns') return header column_len = [len(col) for col in column_list] num_data = column_len[0] if num_data == 0: #print('[csv.make_csv_table()] No data. (header=%r)' % (header,)) return header if any([num_data != clen for clen in column_len]): print('[csv] column_lbls = %r ' % (column_lbls, )) print('[csv] column_len = %r ' % (column_len, )) print('[csv] inconsistent column lengths') return header if column_type is None: column_type = list(map(type, ut.get_list_column(column_list, 0))) #column_type = [type(col[0]) for col in column_list] csv_rows = [] if new: csv_rows.append(header) elif not raw: csv_rows.append(header) if not standardize: csv_rows.append('# num_rows=%r' % num_data) column_maxlen = [] column_str_list = [] if column_lbls is None: column_lbls = [''] * len(column_list) def _toint(c): if c is None: return 'None' try: if np.isnan(c): return 'nan' except TypeError as ex: print('------') print('[csv] TypeError %r ' % ex) print('[csv] _toint(c) failed') print('[csv] c = %r ' % c) print('[csv] type(c) = %r ' % type(c)) print('------') raise return ('%d') % int(c) import uuid textable_types = [uuid.UUID, six.text_type] try: if standardize: def csv_format(r): text = ut.repr2(r, precision=precision) #text = six.text_type(r) # Check if needs escape escape_chars = ['"', ' ', ','] if any([c in text for c in escape_chars]): # escape quotes with quotes text = text.replace('"', '""') # encapsulate with quotes text = '"' + text + '"' return text for col, lbl, coltype in zip(column_list, column_lbls, column_type): col_str = [csv_format(r) for r in col] column_str_list.append(col_str) pass else: # Loop over every column for col, lbl, coltype in zip(column_list, column_lbls, column_type): # Loop over every row in the column (using list comprehension) if coltype is list or util_type.is_list(coltype): col_str = [ six.text_type(c).replace(',', ' ').replace('.', '<dot>') for c in col ] elif (coltype is float or util_type.is_float(coltype) or coltype == np.float32 or util_type.is_valid_floattype(coltype)): precision_fmtstr = '%.' + six.text_type(precision) + 'f' col_str = [ 'None' if r is None else precision_fmtstr % float(r) for r in col ] #col_ = [r if r is None else float(r) for r in col] #col_str = [ut.repr2(r, precision=2) for r in col_] elif coltype is int or util_type.is_int( coltype) or coltype == np.int64: col_str = [_toint(c) for c in (col)] elif coltype in textable_types or util_type.is_str(coltype): col_str = [ six.text_type(c).replace(',', comma_repl) for c in col ] else: print('[csv] is_unknown coltype=%r' % (coltype, )) try: col_str = [six.text_type(c) for c in (col)] except UnicodeDecodeError: try: col_str = [ut.ensure_unicode(c) for c in (col)] except Exception: col_str = [repr(c) for c in (col)] column_str_list.append(col_str) for col_str, lbl in zip(column_str_list, column_lbls): col_lens = [len(s) for s in (col_str)] max_len = max(col_lens) if use_lbl_width: # The column label counts towards the column width max_len = max(len(lbl), max_len) column_maxlen.append(max_len) except Exception as ex: #ut.embed() ut.printex(ex, keys=['col', 'lbl', 'coltype']) raise def _fmtfn(maxlen): return ''.join(['%', six.text_type(maxlen + 2), 's']) fmtstr = ','.join([_fmtfn(maxlen) for maxlen in column_maxlen]) try: if new: csv_rows.append('# ' + fmtstr % tuple(column_lbls)) elif not raw: csv_rows.append('# ' + fmtstr % tuple(column_lbls)) #csv_rows.append('# ' + fmtstr % column_lbls) except Exception as ex: #print(len(column_list)) #ut.embed() ut.printex(ex, keys=['fmtstr', 'column_lbls']) raise for row in zip(*column_str_list): csv_rows.append(' ' + fmtstr % row) csv_text = '\n'.join(csv_rows) return csv_text
def make_csv_table(column_list=[], column_lbls=None, header='', column_type=None, row_lbls=None, transpose=False, precision=2, use_lbl_width=True, comma_repl='<comma>'): """ Creates a csv table with aligned columns make_csv_table Args: column_list (list): column_lbls (None): header (str): column_type (None): row_lbls (None): transpose (bool): Returns: str: csv_text Example: >>> # ENABLE_DOCTEST >>> from utool.util_csv import * # NOQA >>> column_list = [[1, 2, 3], ['A', 'B', 'C']] >>> column_lbls = ['num', 'alpha'] >>> header = '# Test CSV' >>> column_type = (int, str) >>> row_lbls = None >>> transpose = False >>> csv_text = make_csv_table(column_list, column_lbls, header, column_type, row_lbls, transpose) >>> result = csv_text >>> print(result) # Test CSV # num_rows=3 # num, alpha 1, A 2, B 3, C """ import utool as ut assert comma_repl.find(',') == -1, 'comma_repl cannot contain a comma!' if transpose: column_lbls, row_lbls = row_lbls, column_lbls column_list = list(map(list, zip(*column_list))) #import utool as ut #ut.embed() #column_lbls = row_lbls[0] #row_list = if row_lbls is not None: if isinstance(column_list, np.ndarray): column_list = column_list.tolist() if isinstance(row_lbls, np.ndarray): row_lbls = row_lbls.tolist() column_list = [row_lbls] + column_list column_lbls = ['ROWLBL'] + list(map(str, column_lbls)) if column_type is not None: column_type = [str] + column_type if len(column_list) == 0: print('[csv] No columns') return header column_len = [len(col) for col in column_list] num_data = column_len[0] if num_data == 0: #print('[csv.make_csv_table()] No data. (header=%r)' % (header,)) return header if any([num_data != clen for clen in column_len]): print('[csv] column_lbls = %r ' % (column_lbls,)) print('[csv] column_len = %r ' % (column_len,)) print('[csv] inconsistent column lengths') return header if column_type is None: column_type = list(map(type, ut.get_list_column(column_list, 0))) #column_type = [type(col[0]) for col in column_list] csv_rows = [] csv_rows.append(header) csv_rows.append('# num_rows=%r' % num_data) column_maxlen = [] column_str_list = [] if column_lbls is None: column_lbls = [''] * len(column_list) def _toint(c): if c is None: return 'None' try: if np.isnan(c): return 'nan' except TypeError as ex: print('------') print('[csv] TypeError %r ' % ex) print('[csv] _toint(c) failed') print('[csv] c = %r ' % c) print('[csv] type(c) = %r ' % type(c)) print('------') raise return ('%d') % int(c) try: # Loop over every column for col, lbl, coltype in zip(column_list, column_lbls, column_type): # Loop over every row in the column (using list comprehension) if coltype is list or util_type.is_list(coltype): #print('list') #col_str = [str(c).replace(',', comma_repl).replace('.', '<dot>') for c in iter(col)] col_str = [str(c).replace(',', ' ').replace('.', '<dot>') for c in col] elif (coltype is float or util_type.is_float(coltype) or coltype == np.float32 or util_type.is_valid_floattype(coltype)): precision_fmtstr = '%.' + str(precision) + 'f' col_str = ['None' if r is None else precision_fmtstr % float(r) for r in col] elif coltype is int or util_type.is_int(coltype) or coltype == np.int64: col_str = [_toint(c) for c in iter(col)] elif coltype is str or coltype is unicode or util_type.is_str(coltype): col_str = [str(c).replace(',', comma_repl) for c in col] else: print('[csv] is_unknown coltype=%r' % (coltype,)) col_str = [str(c) for c in iter(col)] col_lens = [len(s) for s in iter(col_str)] max_len = max(col_lens) if use_lbl_width: # The column label counts towards the column width max_len = max(len(lbl), max_len) column_maxlen.append(max_len) column_str_list.append(col_str) except Exception as ex: #ut.embed() ut.printex(ex, keys=['col', 'lbl', 'coltype']) raise _fmtfn = lambda maxlen: ''.join(['%', str(maxlen + 2), 's']) fmtstr = ','.join([_fmtfn(maxlen) for maxlen in column_maxlen]) try: csv_rows.append('# ' + fmtstr % tuple(column_lbls)) #csv_rows.append('# ' + fmtstr % column_lbls) except Exception as ex: #print(len(column_list)) #ut.embed() ut.printex(ex, keys=['fmtstr', 'column_lbls']) raise for row in zip(*column_str_list): csv_rows.append(' ' + fmtstr % row) csv_text = '\n'.join(csv_rows) return csv_text