Let's say I have a 5*5 matrix.
[[1. 2. 3. 4. 5.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0]]
For example:
I want to get '4' but '5' is in front of it. I need to relocate '5' which is unnecessary here and place it in any random available location other than the row it was in earlier.
so the matrix should look like this after the relocation
[[0. 1. 2. 3. 4.]
[0. 0. 0. 0. 0.]
[0. 5. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]
and if I need '3' it should relocate '4' and '5' to random locations.
please help me with this. Thanks
CodePudding user response:
In this answer, I assume that the matrix is implemented as a list of lists such as
a = [[1., 2., 3., 4., 5.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]]
The function below
accepts two arguments,
a
, a 2-dimensional matrix implemented as a list of lists, andn
, the number ina[0]
(i.e. the first row ofa
) you want to shift right to the end ofa[0]
.idx
is assigned the index ina[0]
wheren
occurs.The elements in the list
to_relocate
are all the elements ina[0]
to the right ofn
.a[0] = [0.] * (len(a[0]) - (idx 1)) a[0][:idx 1]
shifts elements ofa[0]
right, filling the left with zeros.We then randomly place the items in
to_relocate
to an element in any row ofa
other than row 0.While doing so, in the set
do_not_remove
, we record the indices ofa
corresponding to elements that are replaced by elements into_relocate
so that we do not attempt to place more than one element into_relocate
at the same location ina
.
from random import randrange
def change_random(n, a):
# get index of n in a[0].
idx = a[0].index(n)
# values to relocate.
to_relocate = a[0][idx 1:]
# shift a[0] right (filling left with zeros)
a[0] = [0.] * (len(a[0]) - (idx 1)) a[0][:idx 1]
# records indices corresponding to elements of a
# that have already been replaced by elements in to_relocate.
do_not_remove = set()
for num in to_relocate:
while True:
# draw indices at random from set of valid indices (not row 0)
ij = (randrange(1, len(a)), randrange(0, len(a[0])))
# if element corresponding to ij has not been previously replaced, break
if ij not in do_not_remove:
break
do_not_remove.add(ij)
a[ij[0]][ij[1]] = num
change_random(3, a)
print(a)
Sample Session:
[[0.0, 0.0, 1.0, 2.0, 3.0],
[4.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0, 0.0],
[5.0, 0.0, 0.0, 0.0, 0.0]]