# Manipulate a list: replace random position of a specific integer n times by 0

I have this matrix with 3 sublists:

d = {{1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0}, {0, 1, 1, 1, 0, 0, 1, 0, 1, 1,
1}, {0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0}};


For learning purposes, I try to replace integer 1 (randomly 3 times) in each sublist with 0.

The output can be like this after replace number 1 in a random position of each sublist by 0 tree times:

new d = {{1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0}, {0, 1, 0, 0, 0, 0, 1, 0, 1, 0,
1}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}


Any help appreciated.

Use ReplacePart:

d = {{1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0}, {0, 1, 1, 1, 0, 0, 1, 0, 1, 1,
1}, {0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0}};

f = ReplacePart[#, RandomSample[Position[#, 1], 3] -> 0]&

Print[f /@ d]
(* {{1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0}, {0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}} *)


Try it online!

If you want it to work on lists that contain fewer than 3 1s, replacing them all with 0s, use UpTo[3] instead of 3.

• That's great.#lirtosiast. One question more, please. How I can use If function. I want to pick randomly 3 elements from each sublist in matrix d and replace by if 0->1, or 1->0 – Ben Aawf Jul 18 at 21:39
• @BenAawf MapAt (used in klgr's answer) is more general than ReplacePart; you can do for instance f = MapAt[1-#&, #, RandomSample[Position[#, 0 | 1], 3]]&, which does your replacement and leaves all elements not 0 or 1 unchanged. – lirtosiast Jul 18 at 21:43
MapAt[0 &, #, RandomSample[Position[#, 1], UpTo@3]] & /@ d


{{0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}

Module[{s= SparseArray[RandomSample[Position[#, 1], UpTo@3] -> 0, Length@#, 1]}, s #] & /@ d


{{0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}

SubsetMap[{0, 0, 0} &, #, RandomSample[Position[#, 1], UpTo@3]] & /@ d


{{1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0}, {0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}

• wooow that's so helpful thank you so much @kglr – Ben Aawf Jul 18 at 22:06

A function that takes a list and replaces a random 1 by a 0:

replaceone[L_] := ReplacePart[L, RandomChoice[Position[L, 1]][[1]] -> 0]


Apply it three times to all sublists of d:

Nest[replaceone, #, 3] & /@ d
(*    {{0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0},
{0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}    *)


I guess I'll throw my hat in the ring.

f[list_, numtorep_, numofreps_] := Block[
{data = list},
Apply[
(data[[##]] = 0) &,
RandomSample[#, numofreps] & /@ GatherBy[Position[list, numtorep], First],
{2}
];
data
]

d = {{1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0}, {0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1}, {0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0}}
f[d, 1, 3]


{{1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0}, {0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1}, {0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0}}

{{0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0}, {0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}