kwarray.util_random

Handle and interchange between different random number generators (numpy, python, torch, …). Also defines useful random iterator functions and ensure_rng().

Module Contents

Functions

seed_global(seed, offset=0)

Seeds the python, numpy, and torch global random states

shuffle(items, rng=None)

Shuffles a list inplace and then returns it for convinience

random_combinations(items, size, num=None, rng=None)

Yields num combinations of length size from items in random order

random_product(items, num=None, rng=None)

Yields num items from the cartesian product of items in a random order.

_npstate_to_pystate(npstate)

Convert state of a NumPy RandomState object to a state

_pystate_to_npstate(pystate)

Convert state of a Python Random object to state usable

_coerce_rng_type(rng)

Internal method that transforms input seeds into an integer form.

ensure_rng(rng, api='numpy')

Coerces input into a random number generator.

Attributes

_SEED_MAX

kwarray.util_random._SEED_MAX
kwarray.util_random.seed_global(seed, offset=0)

Seeds the python, numpy, and torch global random states

Parameters
  • seed (int) – seed to use

  • offset (int, optional) – if specified, uses a different seed for each global random state separated by this offset.

kwarray.util_random.shuffle(items, rng=None)

Shuffles a list inplace and then returns it for convinience

Parameters
  • items (list or ndarray) – list to shuffle

  • rng (RandomState or int) – seed or random number gen

Returns

this is the input, but returned for convinience

Return type

list

Example

>>> 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]
kwarray.util_random.random_combinations(items, size, num=None, rng=None)

Yields num combinations of length size from items in random order

Parameters
  • items (List) – pool of items to choose from

  • size (int) – number of items in each combination

  • num (None, default=None) – number of combinations to generate

  • rng (int | RandomState, default=None) – seed or random number generator

Yields

Tuple – a random combination of items of length size.

Example

>>> import ubelt as ub
>>> items = list(range(10))
>>> size = 3
>>> num = 5
>>> rng = 0
>>> # xdoctest: +IGNORE_WANT
>>> combos = list(random_combinations(items, size, num, rng))
>>> print('combos = {}'.format(ub.repr2(combos, nl=1)))
combos = [
    (0, 6, 9),
    (4, 7, 8),
    (4, 6, 7),
    (2, 3, 5),
    (1, 2, 4),
]

Example

>>> import ubelt as ub
>>> items = list(zip(range(10), range(10)))
>>> # xdoctest: +IGNORE_WANT
>>> combos = list(random_combinations(items, 3, num=5, rng=0))
>>> print('combos = {}'.format(ub.repr2(combos, nl=1)))
combos = [
    ((0, 0), (6, 6), (9, 9)),
    ((4, 4), (7, 7), (8, 8)),
    ((4, 4), (6, 6), (7, 7)),
    ((2, 2), (3, 3), (5, 5)),
    ((1, 1), (2, 2), (4, 4)),
]
kwarray.util_random.random_product(items, num=None, rng=None)

Yields num items from the cartesian product of items in a random order.

Parameters
  • items (List[Sequence]) – items to get caresian product of packed in a list or tuple. (note this deviates from api of itertools.product())

  • num (int, default=None) – maximum number of items to generate. If None, all

  • rng (random.Random | np.random.RandomState | int) – random number generator

Yields

Tuple – a random item in the cartesian product

Example

>>> import ubelt as ub
>>> items = [(1, 2, 3), (4, 5, 6, 7)]
>>> rng = 0
>>> # xdoctest: +IGNORE_WANT
>>> products = list(random_product(items, rng=0))
>>> print(ub.repr2(products, nl=0))
[(3, 4), (1, 7), (3, 6), (2, 7),... (1, 6), (2, 5), (2, 4)]
>>> products = list(random_product(items, num=3, rng=0))
>>> print(ub.repr2(products, nl=0))
[(3, 4), (1, 7), (3, 6)]

Example

>>> # xdoctest: +REQUIRES(--profile)
>>> rng = ensure_rng(0)
>>> items = [np.array([15, 14]), np.array([27, 26]),
>>>          np.array([21, 22]), np.array([32, 31])]
>>> num = 2
>>> for _ in range(100):
>>>     list(random_product(items, num=num, rng=rng))
kwarray.util_random._npstate_to_pystate(npstate)

Convert state of a NumPy RandomState object to a state that can be used by Python’s Random. Derived from 1.

References

1

https://stackoverflow.com/questions/44313620/convert-randomstate

Example

>>> 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()
kwarray.util_random._pystate_to_npstate(pystate)

Convert state of a Python Random object to state usable by NumPy RandomState. Derived from 2.

References

2

https://stackoverflow.com/questions/44313620/convert-randomstate

Example

>>> 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()
kwarray.util_random._coerce_rng_type(rng)

Internal method that transforms input seeds into an integer form.

kwarray.util_random.ensure_rng(rng, api='numpy')

Coerces input into a random number generator.

This function is useful for ensuring that your code uses a controlled internal random state that is independent of other modules.

If the input is None, then a global random state is returned.

If the input is a numeric value, then that is used as a seed to construct a random state.

If the input is a random number generator, then another random number generator with the same state is returned. Depending on the api, this random state is either return as-is, or used to construct an equivalent random state with the requested api.

Parameters
  • rng (int | float | numpy.random.RandomState | random.Random | None) – if None, then defaults to the global rng. Otherwise this can be an integer or a RandomState class

  • api (str, default=’numpy’) – specify the type of random number generator to use. This can either be ‘numpy’ for a numpy.random.RandomState object or ‘python’ for a random.Random object.

Returns

rng -

either a numpy or python random number generator, depending on the setting of api.

Return type

(numpy.random.RandomState | random.Random)

Example

>>> rng = ensure_rng(None)
>>> ensure_rng(0).randint(0, 1000)
684
>>> ensure_rng(np.random.RandomState(1)).randint(0, 1000)
37

Example

>>> 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 = ensure_rng(random.Random(0), api='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 = ensure_rng(np.random.RandomState(seed=0), api='python')
>>> pn_nums = [py_rng.random() for _ in range(num)]
>>> print(pn_nums)
>>> assert np_nums == pp_nums
>>> assert pn_nums == nn_nums

Example

>>> # Test that random modules can be coerced
>>> import random
>>> import numpy as np
>>> ensure_rng(random, api='python')
>>> ensure_rng(random, api='numpy')
>>> ensure_rng(np.random, api='python')
>>> ensure_rng(np.random, api='numpy')
Ignore:
>>> np.random.seed(0)
>>> np.random.randint(0, 10000)
2732
>>> np.random.seed(0)
>>> np.random.mtrand._rand.randint(0, 10000)
2732
>>> np.random.seed(0)
>>> ensure_rng(None).randint(0, 10000)
2732
>>> np.random.randint(0, 10000)
9845
>>> ensure_rng(None).randint(0, 10000)
3264