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$

4 Answers 4

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$
2
  • $\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, 2019 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, 2019 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$
1
  • $\begingroup$ wooow that's so helpful thank you so much @kglr $\endgroup$
    – Ben Aawf
    Jul 18, 2019 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 and acknowledge you have read our privacy policy.

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