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
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, and n
, the number in a[0]
(i.e. the first row of a
) you want to shift right to the end of a[0]
.
idx
is assigned the index in a[0]
where n
occurs.
The elements in the list to_relocate
are all the elements in a[0]
to the right of n
.
a[0] = [0.] * (len(a[0]) - (idx + 1)) + a[0][:idx + 1]
shifts elements of a[0]
right, filling the left with zeros.
We then randomly place the items in to_relocate
to an element in any row of a
other than row 0.
While doing so, in the set do_not_remove
, we record the indices of a
corresponding to elements that are replaced by elements in to_relocate
so that we do not attempt to place more than one element in to_relocate
at the same location in a
.
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]]