1
$\begingroup$

First of all I´m new to Mathematica; I´m trying to exchange distinct values of a list with values of another list (piecewise). I thought ReplacePart in combination with Position will do it, but it doesn´t yield the wanted result.

Here is an example:

original data:

data = Table[RandomInteger[]*100, {x, 0, 20}, {y, 0, 20}, {z, 0, 20}];

next get the position:

posSelect = Position[data, a_ /; a == 100, {3}, Heads -> False];

generate 2nd list:

lengthSelect = Length[Extract[data, posSelect]];
newVal = RandomInteger[1, lengthSelect];

updated list

data2 = data
data2 = ReplacePart[data, posSelect -> newVal];

data2 now contains at each selected position the entire elements of newVal. What is wrong with this approach? How to correctly exchange these selected values with the values of the 2nd list?

$\endgroup$
  • $\begingroup$ fyi, instead of posSelect = Position[data, a_ /; a == 100, {3}, Heads -> False]; you just write posSelect = Position[data, 100, {3}, Heads -> False]; $\endgroup$ – Nasser Jul 16 '14 at 10:32
  • $\begingroup$ @MikeHoneychurch No, that doesn't work because posSelect is not a list of integers but rather a list of lists of integers, so you'll have to Map your way around this one. $\endgroup$ – Teake Nutma Jul 16 '14 at 10:50
2
$\begingroup$

If you just want to replace every occurrence of 100 with a random choice of 0 or 1, this suffices:

data = Table[RandomInteger[]*100, {2}, {2}, {2}]

{{{100, 100}, {0, 0}}, {{100, 100}, {0, 100}}}

data /. (100 :> RandomInteger[])

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

Note that I've limited the data array to 2x2x2 instead of 20x20x20 for simplicity. However, if you want to stick a second list of values, you can do this:

newVal = RandomInteger[1, Count[data, 100, {3}]]

{0, 1, 1, 1, 0}

index = 0;
data2 = data /. (100 :> newVal[[ ++index ]])

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

Or alternatively, if you have a healthy aversion against loop variables, you can do the following:

positions = Position[data, 100]

{{1, 1, 1}, {1, 1, 2}, {2, 1, 1}, {2, 1, 2}, {2, 2, 2}}

data2 = ReplacePart[data, Thread[positions -> newVal] ]

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

This is the closest to what you actually asked. Turns out you were only missing a call to Thread :).

$\endgroup$
  • $\begingroup$ Nice job covering the bases. $\endgroup$ – Mr.Wizard Jul 16 '14 at 13:31
  • $\begingroup$ Nice alternatives +1 $\endgroup$ – brama Aug 8 '14 at 4:19

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.