5
$\begingroup$

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.

$\endgroup$
3
$\begingroup$

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.

$\endgroup$
  • $\begingroup$ 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 $\endgroup$ – Ben Aawf Jul 18 at 21:39
  • $\begingroup$ @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. $\endgroup$ – lirtosiast Jul 18 at 21:43
5
$\begingroup$
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}}

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

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}}    *)
$\endgroup$
1
$\begingroup$

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}}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.