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$
2
  • $\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, 2014 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$ Jul 16, 2014 at 10:50

1 Answer 1

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$
2
  • $\begingroup$ Nice job covering the bases. $\endgroup$
    – Mr.Wizard
    Jul 16, 2014 at 13:31
  • $\begingroup$ Nice alternatives +1 $\endgroup$
    – brama
    Aug 8, 2014 at 4:19

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.