Issue
I have the following array of shape (A, B) where A=4 and B=2 here:
[[1 1] [2 2] [3 3] [4 4]]
I want to modify the array so each row consists of randomly selected values from the other rows, with no repetition within the same row. An example result would be:
[[3 2] [1 3] [2 4] [3 1]]
I tried to use np.random.shuffle and np.random.choice but I can't figure out how to exclude the row itself and how to replace values per value instead of per row. np.random.shuffle leads to:
[[4 4] [2 2] [3 3] [1 1]]
and np.random.choice gives me errors because my array is 2D and not 1D
I'm a beginner and I feel like this should be obvious but I've been racking my brain all day... Any help would be very much appreciated
Solution
Assuming that the values for an A=N
matrix are always to be the values 1 to N, the following will generate a random matrix where the values come from that set but no row contains the one-based index of that row.
import random
N = 4
nums = list(range(1, N+1))
a = []
for irow in range(1, N+1):
nums.remove(irow)
a.append([random.choice(nums), random.choice(nums)])
nums.append(irow)
print(a)
generates
[[3, 4], [4, 4], [4, 1], [1, 2]]
If you want to be sure that each column contains all of the possible values, but again with no value appearing in the row with the value equaling its one-based index. The following (based of @BRivera's solution described in Find the permutations where no element stays in place) should do the trick
import random
def generate_all_moved_permutation_tree(level, nums):
if len(nums) == 0:
raise RunTimeError('generate_permutation_tree must be called with a non-empty nums list')
if len(nums) == 1:
if level == nums[0]:
return None
else:
return {nums[0]: {}}
allowed_nums = list(nums)
if level in allowed_nums:
allowed_nums.remove(level)
result = {}
for n in allowed_nums:
sublevel_nums = list(nums)
if n in sublevel_nums:
sublevel_nums.remove(n)
subtree = generate_all_moved_permutation_tree(level+1, sublevel_nums)
if subtree is not None:
result[n] = subtree
if len(result) == 0:
return None
return result
def pick_an_all_moved_permutation(all_moved_permutation_tree):
n = random.choice(list(all_moved_permutation_tree))
l = [n]
sub_tree = all_moved_permutation_tree[n]
if len(sub_tree) > 0:
l.extend(pick_an_all_moved_permutation(sub_tree))
return l
Examples
>>> t = generate_all_moved_permutation_tree(1, range(1,4))
>>> print(t)
{2: {3: {1: {}}}, 3: {1: {2: {}}}}
>>> t = generate_all_moved_permutation_tree(1, range(1,5))
>>> print(list(zip(pick_an_all_moved_permutation(t), pick_an_all_moved_permutation(t))))
[(2, 4), (3, 1), (4, 2), (1, 3)]
>>> print(list(zip(pick_an_all_moved_permutation(t), pick_an_all_moved_permutation(t))))
[(3, 4), (1, 1), (4, 2), (2, 3)]
>>> print(list(zip(pick_an_all_moved_permutation(t), pick_an_all_moved_permutation(t))))
[(3, 2), (4, 1), (1, 4), (2, 3)]
Answered By - Malcolm
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.