| | |
| | """ |
| | random.py |
| | |
| | Tools related to randomness |
| | |
| | """ |
| | from __future__ import absolute_import |
| |
|
| | import os |
| | import sys |
| | import numpy as np |
| | import random |
| |
|
| | import core_scripts.other_tools.display as nii_display |
| |
|
| | __author__ = "Xin Wang" |
| | __email__ = "wangxin@nii.ac.jp" |
| | __copyright__ = "Copyright 2021, Xin Wang" |
| |
|
| | |
| | |
| | |
| |
|
| | def f_shuffle_slice_inplace(input_list, slice_start=None, slice_stop=None): |
| | """ shuffle_slice(input_list, slice_start, slice_stop) |
| | |
| | Shuffling input list (in place) in the range specified by slice_start |
| | and slice_stop. |
| | |
| | Based on Knuth shuffling |
| | https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle |
| | |
| | input |
| | ----- |
| | input_list: list |
| | slice_start: int, start idx of the range to be shuffled |
| | slice_end: int, end idx of the range to be shuffled |
| | |
| | Both slice_start and slice_end should be in the style of python index |
| | e.g., shuffle_slice(input_list, 0, N) will shuffle the slice input[0:N] |
| | |
| | When slice_start / slice_stop is None, |
| | slice_start = 0 / slice_stop = len(input_list) |
| | |
| | output |
| | ------ |
| | none: shuffling is done in place |
| | """ |
| | if slice_start is None or slice_start < 0: |
| | slice_start = 0 |
| | if slice_stop is None or slice_stop > len(input_list): |
| | slice_stop = len(input_list) |
| | |
| | idx = slice_start |
| | while (idx < slice_stop - 1): |
| | idx_swap = random.randrange(idx, slice_stop) |
| | |
| | tmp = input_list[idx_swap] |
| | input_list[idx_swap] = input_list[idx] |
| | input_list[idx] = tmp |
| | idx += 1 |
| | return |
| |
|
| | def f_shuffle_in_block_inplace(input_list, block_size): |
| | """ |
| | f_shuffle_in_block_inplace(input_list, block_size) |
| | |
| | Shuffle the input list (in place) by dividing the list input blocks and |
| | shuffling within each block |
| | |
| | Example: |
| | >>> data = [1,2,3,4,5,6] |
| | >>> random_tools.f_shuffle_in_block_inplace(data, 3) |
| | >>> data |
| | [3, 1, 2, 5, 4, 6] |
| | |
| | input |
| | ----- |
| | input_list: input list |
| | block_size: int |
| | |
| | output |
| | ------ |
| | None: shuffling is done in place |
| | """ |
| | if block_size <= 1: |
| | |
| | return |
| | else: |
| | list_length = len(input_list) |
| | |
| | for iter_idx in range( -(-list_length // block_size) ): |
| | |
| | f_shuffle_slice_inplace( |
| | input_list, iter_idx * block_size, (iter_idx+1) * block_size) |
| | return |
| |
|
| | def f_shuffle_blocks_inplace(input_list, block_size): |
| | """ |
| | f_shuffle_blocks_inplace(input_list, block_size) |
| | |
| | Shuffle the input list (in place) by dividing the list input blocks and |
| | shuffling blocks |
| | |
| | Example: |
| | >> data = np.arange(1, 7) |
| | >> f_shuffle_blocks_inplace(data, 3) |
| | >> print(data) |
| | [4 5 6 1 2 3] |
| | |
| | input |
| | ----- |
| | input_list: input list |
| | block_size: int |
| | |
| | output |
| | ------ |
| | None: shuffling is done in place |
| | """ |
| | |
| | tmp_list = input_list.copy() |
| |
|
| | block_number = len(input_list) // block_size |
| | |
| | shuffle_block_idx = [x for x in range(block_number)] |
| | random.shuffle(shuffle_block_idx) |
| |
|
| | new_idx = None |
| | for iter_idx in range(block_size * block_number): |
| | block_idx = iter_idx // block_size |
| | in_block_idx = iter_idx % block_size |
| | new_idx = shuffle_block_idx[block_idx] * block_size + in_block_idx |
| | input_list[iter_idx] = tmp_list[new_idx] |
| | return |
| |
|
| | if __name__ == "__main__": |
| | print("Definition of randomness tools") |
| |
|