Source code for utool.util_numpy

# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function
import six
import itertools
import random

try:
    import numpy as np
except ImportError as ex:
    pass
from utool import util_inject

print, rrr, profile = util_inject.inject2(__name__)


[docs]def tiled_range(range_, cols): return np.tile(np.arange(range_), (cols, 1)).T
# np.tile(np.arange(num_qf).reshape(num_qf, 1), (1, k_vsmany))
[docs]def quantum_random(): """ returns a 32 bit unsigned integer quantum random number """ import quantumrandom data16 = quantumrandom.uint16(array_length=2) assert data16.flags['C_CONTIGUOUS'] data32 = data16.view(np.dtype('uint32'))[0] return data32
def _npstate_to_pystate(npstate): """ Convert state of a NumPy RandomState object to a state that can be used by Python's Random. References: https://stackoverflow.com/questions/44313620/converting-randomstate Example: >>> # ENABLE_DOCTEST >>> from utool.util_numpy import * # NOQA >>> from utool.util_numpy import _npstate_to_pystate >>> py_rng = random.Random(0) >>> np_rng = np.random.RandomState(seed=0) >>> npstate = np_rng.get_state() >>> pystate = _npstate_to_pystate(npstate) >>> py_rng.setstate(pystate) >>> assert np_rng.rand() == py_rng.random() """ PY_VERSION = 3 version, keys, pos, has_gauss, cached_gaussian_ = npstate keys_pos = tuple(map(int, keys)) + (int(pos),) cached_gaussian_ = cached_gaussian_ if has_gauss else None pystate = (PY_VERSION, keys_pos, cached_gaussian_) return pystate def _pystate_to_npstate(pystate): """ Convert state of a Python Random object to state usable by NumPy RandomState. References: https://stackoverflow.com/questions/44313620/converting-randomstate Example: >>> # ENABLE_DOCTEST >>> from utool.util_numpy import * # NOQA >>> from utool.util_numpy import _pystate_to_npstate >>> py_rng = random.Random(0) >>> np_rng = np.random.RandomState(seed=0) >>> pystate = py_rng.getstate() >>> npstate = _pystate_to_npstate(pystate) >>> np_rng.set_state(npstate) >>> assert np_rng.rand() == py_rng.random() """ NP_VERSION = 'MT19937' version, keys_pos_, cached_gaussian_ = pystate keys, pos = keys_pos_[:-1], keys_pos_[-1] keys = np.array(keys, dtype=np.uint32) has_gauss = cached_gaussian_ is not None cached_gaussian = cached_gaussian_ if has_gauss else 0.0 npstate = (NP_VERSION, keys, pos, has_gauss, cached_gaussian) return npstate
[docs]def ensure_rng(rng, impl='numpy'): """ Returns a random number generator Example: >>> # ENABLE_DOCTEST >>> from utool.util_numpy import * # NOQA >>> import utool as ut >>> import numpy as np >>> num = 4 >>> print('--- Python as PYTHON ---') >>> py_rng = random.Random(0) >>> pp_nums = [py_rng.random() for _ in range(num)] >>> print(pp_nums) >>> print('--- Numpy as PYTHON ---') >>> np_rng = ut.ensure_rng(random.Random(0), impl='numpy') >>> np_nums = [np_rng.rand() for _ in range(num)] >>> print(np_nums) >>> print('--- Numpy as NUMPY---') >>> np_rng = np.random.RandomState(seed=0) >>> nn_nums = [np_rng.rand() for _ in range(num)] >>> print(nn_nums) >>> print('--- Python as NUMPY---') >>> py_rng = ut.ensure_rng(np.random.RandomState(seed=0), impl='python') >>> pn_nums = [py_rng.random() for _ in range(num)] >>> print(pn_nums) >>> assert np_nums == pp_nums >>> assert pn_nums == nn_nums """ if impl == 'numpy': if rng is None: rng = np.random elif isinstance(rng, int): rng = np.random.RandomState(seed=rng) elif isinstance(rng, random.Random): # Convert python to numpy random state py_rng = rng pystate = py_rng.getstate() npstate = _pystate_to_npstate(pystate) rng = np_rng = np.random.RandomState(seed=0) np_rng.set_state(npstate) elif impl == 'python': if rng is None: rng = random elif isinstance(rng, int): rng = random.Random(rng) elif isinstance(rng, np.random.RandomState): # Convert numpy to python random state np_rng = rng npstate = np_rng.get_state() pystate = _npstate_to_pystate(npstate) rng = py_rng = random.Random(0) py_rng.setstate(pystate) else: raise KeyError('unknown rng impl={}'.format(impl)) return rng
[docs]def random_indexes(max_index, subset_size=None, seed=None, rng=None): """ random unrepeated indicies Args: max_index (?): subset_size (None): (default = None) seed (None): (default = None) rng (RandomState): random number generator(default = None) Returns: ?: subst CommandLine: python -m utool.util_numpy --exec-random_indexes Example: >>> # DISABLE_DOCTEST >>> from utool.util_numpy import * # NOQA >>> max_index = 10 >>> subset_size = None >>> seed = None >>> rng = np.random.RandomState(0) >>> subst = random_indexes(max_index, subset_size, seed, rng) >>> result = ('subst = %s' % (str(subst),)) >>> print(result) """ subst_ = np.arange(0, max_index) rng = ensure_rng(seed if rng is None else rng) rng.shuffle(subst_) if subset_size is None: subst = subst_ else: subst = subst_[0 : min(subset_size, max_index)] return subst
# def list_index(search_list, to_find_list): # """ Keep this function # Searches search_list for each element in to_find_list""" # try: # toret = [np.where(search_list == item)[0][0] for item in to_find_list] # except IndexError as ex1: # print('ERROR: ' + str(ex1)) # print('item = %r' % (item,)) # raise # return toret
[docs]def npfind(arr): found = np.where(arr)[0] pos = -1 if len(found) == 0 else found[0] return pos
[docs]def index_of(item, array): 'index of [item] in [array]' return np.where(array == item)[0][0]
[docs]def spaced_indexes(len_, n, trunc=False): """ Returns n evenly spaced indexes. Returns as many as possible if trunc is true """ if n is None: return np.arange(len_) all_indexes = np.arange(len_) if trunc: n = min(len_, n) if n == 0: return np.empty(0) stride = len_ // n try: indexes = all_indexes[0:-1:stride] except ValueError: raise ValueError('cannot slice list of len_=%r into n=%r parts' % (len_, n)) return indexes
[docs]def inbounds(arr, low, high): flag_low = arr >= low flag_high = arr < high if high is not None else flag_low flag = np.logical_and(flag_low, flag_high) return flag
[docs]def intersect2d(A, B): """ intersect2d intersect rows of 2d numpy arrays DEPRICATE: use intersect2d in vtool instead Args: A (ndarray[ndim=2]): B (ndarray[ndim=2]): Returns: tuple: (C, Ax, Bx) Example: >>> # ENABLE_DOCTEST >>> from utool.util_numpy import * # NOQA >>> import utool as ut >>> A = np.array([[1, 2, 3], [1, 1, 1]]) >>> B = np.array([[1, 2, 3], [1, 2, 14]]) >>> (C, Ax, Bx) = ut.intersect2d(A, B) >>> result = str((C, Ax, Bx)) >>> print(result) (array([[1, 2, 3]]), array([0]), array([0])) """ Cset = set(tuple(x) for x in A).intersection(set(tuple(x) for x in B)) Ax = np.array([x for x, item in enumerate(A) if tuple(item) in Cset], dtype=np.int) Bx = np.array([x for x, item in enumerate(B) if tuple(item) in Cset], dtype=np.int) C = np.array(tuple(Cset)) return C, Ax, Bx
# def unique_ordered(arr): # """ pandas.unique preseves order and seems to be faster due to index overhead """ # import pandas as pd # return pd.unique(arr) # _, idx = np.unique(arr, return_index=True) # return arr[np.sort(idx)]
[docs]def deterministic_shuffle(list_, seed=0, rng=None): r""" Args: list_ (list): seed (int): Returns: list: list_ CommandLine: python -m utool.util_numpy --test-deterministic_shuffle Example: >>> # ENABLE_DOCTEST >>> from utool.util_numpy import * # NOQA >>> list_ = [1, 2, 3, 4, 5, 6] >>> seed = 1 >>> list_ = deterministic_shuffle(list_, seed) >>> result = str(list_) >>> print(result) [3, 2, 5, 1, 4, 6] """ rng = ensure_rng(seed if rng is None else rng) rng.shuffle(list_) return list_
[docs]def shuffle(list_, seed=0, rng=None): r""" Shuffles a list inplace and then returns it for convinience Args: list_ (list or ndarray): list to shuffl rng (RandomState or int): seed or random number gen Returns: list: this is the input, but returned for convinience Example: >>> # ENABLE_DOCTEST >>> from utool.util_numpy import * # NOQA >>> list1 = [1, 2, 3, 4, 5, 6] >>> list2 = shuffle(list(list1), rng=1) >>> assert list1 != list2 >>> result = str(list2) >>> print(result) [3, 2, 5, 1, 4, 6] """ rng = ensure_rng(seed if rng is None else rng) rng.shuffle(list_) return list_
[docs]def random_sample(list_, nSample, strict=False, rng=None, seed=None): """ Grabs data randomly Args: list_ (list): nSample (?): strict (bool): (default = False) rng (module): random number generator(default = numpy.random) seed (None): (default = None) Returns: list: sample_list CommandLine: python -m utool.util_numpy --exec-random_sample Example: >>> # DISABLE_DOCTEST >>> from utool.util_numpy import * # NOQA >>> list_ = np.arange(10) >>> nSample = 4 >>> strict = False >>> rng = np.random.RandomState(0) >>> seed = None >>> sample_list = random_sample(list_, nSample, strict, rng, seed) >>> result = ('sample_list = %s' % (str(sample_list),)) >>> print(result) """ rng = ensure_rng(seed if rng is None else rng) if isinstance(list_, list): list2_ = list_[:] else: list2_ = np.copy(list_) if len(list2_) == 0 and not strict: return list2_ rng.shuffle(list2_) if nSample is None and strict is False: return list2_ if not strict: nSample = min(max(0, nSample), len(list2_)) sample_list = list2_[:nSample] return sample_list
[docs]def deterministic_sample(list_, nSample, seed=0, rng=None, strict=False): """ Grabs data randomly, but in a repeatable way """ rng = ensure_rng(seed if rng is None else rng) sample_list = random_sample(list_, nSample, strict=strict, rng=rng) return sample_list
[docs]def spaced_items(list_, n, **kwargs): """ Returns n evenly spaced items """ indexes = spaced_indexes(len(list_), n, **kwargs) items = list_[indexes] return items
[docs]def sample_domain(min_, max_, nSamp, mode='linear'): """ Example: >>> # ENABLE_DOCTEST >>> import utool >>> min_ = 10 >>> max_ = 1000 >>> nSamp = 7 >>> result = utool.sample_domain(min_, max_, nSamp) >>> print(result) [10, 151, 293, 434, 576, 717, 859] """ if mode == 'linear': samples_ = np.rint(np.linspace(min_, max_, nSamp + 1)).astype(np.int64) elif mode == 'log': base = 2 logmin = np.log2(min_) / np.log2(base) logmax = np.log2(max_) / np.log2(base) samples_ = np.rint(np.logspace(logmin, logmax, nSamp + 1, base=base)).astype( np.int64 ) else: raise NotImplementedError(mode) sample = [index for index in samples_ if index < max_] return sample
[docs]def make_incrementer(): # DEPRICATE FOR ITERTOOLS.COUNT return ut.partial(six.next, itertools.count(1))
# def incrementer(_mem=[0]): # _mem[0] += 1 # return _mem[0] # return incrementer if __name__ == '__main__': """ CommandLine: python -c "import utool, utool.util_numpy; utool.doctest_funcs(utool.util_numpy, allexamples=True)" python -c "import utool, utool.util_numpy; utool.doctest_funcs(utool.util_numpy)" python -m utool.util_numpy python -m utool.util_numpy --allexamples """ import multiprocessing multiprocessing.freeze_support() # for win32 import utool as ut # NOQA ut.doctest_funcs()