Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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?

share|improve this question
    
fyi, instead of posSelect = Position[data, a_ /; a == 100, {3}, Heads -> False]; you just write posSelect = Position[data, 100, {3}, Heads -> False]; –  Nasser Jul 16 at 10:32
    
@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. –  Teake Nutma Jul 16 at 10:50

1 Answer 1

up vote 2 down vote accepted

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 :).

share|improve this answer
    
Nice job covering the bases. –  Mr.Wizard Jul 16 at 13:31
    
Nice alternatives +1 –  brama Aug 8 at 4:19

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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