7
$\begingroup$

I have two tables. One is given by

T1 = Table[{x, y, 0.}, {x, 0, V},{y, 0, V}]

and from a calculation I have the second, a list of points {x, y, z}

T2 = {{0, 0, 3.4}, {1, 2, 1.4}, {10, 2, 7.4}, ...}

with Length[T1] > Length[T2].

How can I efficiently replace every element {x, y, 0.} in T1 by the corresponding point {x, y, z} from T2?

$\endgroup$
2
  • $\begingroup$ But which {x,y,z} will replace the {x,y,0.}? With T1 being longer than T2 if there are more {x,y,0} in T1 than there are {x,y,z} in T2, what happens then? $\endgroup$ Commented Feb 28, 2013 at 9:42
  • $\begingroup$ @PlatoManiac: there is always only one point with the coordinates {x,y}. It has the value z. This value z has to replace the 0. in the "template" table T1. The reason why I'm trying to do it like this is the speed of Interpolation[]: When the values of T1 are integrated into a "rectangular" Table form as T1 the interpolation is much faster then for T2. $\endgroup$ Commented Feb 28, 2013 at 9:48

2 Answers 2

7
$\begingroup$
 t1 = Table[{x, y, 0.}, {x, 0, 5}, {y, 0, 5}]
 (* {{{0, 0, 0.}, {0, 1, 0.}, {0, 2, 0.}, {0, 3, 0.}, {0, 4, 0.}, {0, 5, 0.}},
     {{1, 0, 0.}, {1, 1, 0.}, {1, 2, 0.}, {1, 3, 0.}, {1, 4,  0.}, {1, 5, 0.}}, 
     {{2, 0, 0.}, {2, 1, 0.}, {2, 2, 0.}, {2, 3,  0.}, {2, 4, 0.}, {2, 5, 0.}}, 
     {{3, 0, 0.}, {3, 1, 0.}, {3, 2, 0.}, {3, 3, 0.}, {3, 4, 0.}, {3, 5, 0.}}, 
     {{4, 0, 0.}, {4, 1, 0.}, {4, 2, 0.}, {4, 3, 0.}, {4, 4, 0.}, {4, 5, 0.}}, 
     {{5, 0, 0.}, {5, 1, 0.}, {5, 2, 0.}, {5, 3, 0.}, {5, 4, 0.}, {5, 5, 0.}}} *)

Use the second table, say,

 t2 = DeleteDuplicates[RandomInteger[5, {5, 3}], #1[[;; 2]] == #2[[;; 2]] &]
 (* {{0, 5, 3}, {4, 3, 3}, {1, 4, 4}, {5, 3, 0}, {2, 5, 3}} *)

to define the replacement rules:

 rplcmntRule = {#[[1]], #[[2]], _} -> # & /@ t2
 (*  {{0, 5, _} -> {0, 5, 3}, {4, 3, _} -> {4, 3, 3}, 
      {1, 4, _} -> {1, 4, 4}, {5, 3, _} -> {5, 3, 0}, {2, 5, _} -> {2, 5, 3}}*)

and use them in ReplaceAll:

 t1 /. rplcmntRule
 (* {{{0, 0, 0.}, {0, 1, 0.}, {0, 2, 0.}, {0, 3, 0.}, {0, 4, 0.}, {0, 5, 3}}, 
     {{1, 0, 0.}, {1, 1, 0.}, {1, 2, 0.}, {1, 3, 0.}, {1, 4, 4}, {1, 5, 0.}},
     {{2, 0, 0.}, {2, 1, 0.}, {2, 2, 0.}, {2, 3, 0.}, {2, 4, 0.}, {2, 5, 3}},
     {{3, 0, 0.}, {3, 1, 0.}, {3, 2, 0.}, {3, 3, 0.}, {3, 4, 0.}, {3, 5, 0.}}, 
     {{4, 0, 0.}, {4, 1, 0.}, {4, 2, 0.}, {4, 3, 3}, {4, 4, 0.}, {4, 5, 0.}},
     {{5, 0, 0.}, {5, 1, 0.}, {5, 2, 0.}, {5, 3, 0}, {5, 4, 0.}, {5, 5, 0.}}} *)
$\endgroup$
4
  • $\begingroup$ You beat me again. :-) $\endgroup$
    – Mr.Wizard
    Commented Feb 28, 2013 at 9:50
  • $\begingroup$ Mathematica can be SO elegant, thank you kguler! $\endgroup$ Commented Feb 28, 2013 at 9:54
  • $\begingroup$ @Mr.Wizard, you should should have selected v=2:) $\endgroup$
    – kglr
    Commented Feb 28, 2013 at 10:02
  • 1
    $\begingroup$ @pawel, thank you for the accept. Please keep in mind that it is a good idea to wait for a while before accepting an answer as questions with accepted answers tend to attract less attention from potential answerers. $\endgroup$
    – kglr
    Commented Feb 28, 2013 at 10:05
9
$\begingroup$

First, you should not start user Symbol names with capital letters as these can easily conflict with internal system functions.

There are surely quite a few ways of doing this. It is not clear if you value performance over clarity, etc.

Replace by pattern

Ignoring the regularity of the data (and applicable to cases where it is not) you could use replacement rules:

v = 3;
t1 = Table[{x, y, 0.}, {x, 0, v}, {y, 0, v}];
t2 = {{0, 0, 3.4}, {1, 2, 1.4}, {3, 2, 7.4}};

rules = {#, #2, _} -> {##} & @@@ t2

t1 /. rules
{{0, 0, _} -> {0, 0, 3.4}, {1, 2, _} -> {1, 2, 1.4}, {3, 2, _} -> {3, 2, 7.4}}

{{{0, 0, 3.4}, {0, 1, 0.}, {0, 2, 0.}, {0, 3, 0.}},
 {{1, 0, 0.}, {1, 1, 0.}, {1, 2, 1.4}, {1, 3, 0.}},
 {{2, 0, 0.}, {2, 1, 0.}, {2, 2, 0.}, {2, 3, 0.}},
 {{3, 0, 0.}, {3, 1, 0.}, {3, 2, 7.4}, {3, 3, 0.}}}

Be aware that these patterns will match only if the first two elements exactly match; for an equivalence use:

rules = {x_ /; x == #, y_ /; y == #2, _} :> {x, y, #3} & @@@ t2

Replace by index

Using the regularity of the data we could make these replacements directly, using ReplacePart or for in-place modification assignments to Part. We must adjust for the fact that your indices start from zero whereas Mathematica indexes from one.

ReplacePart[t1, {# + 1, #2 + 1, 3} :> #3 & @@@ t2]
{{{0, 0, 3.4}, {0, 1, 0.}, {0, 2, 0.}, {0, 3, 0.}},
 {{1, 0, 0.}, {1, 1, 0.}, {1, 2, 1.4}, {1, 3, 0.}},
 {{2, 0, 0.}, {2, 1, 0.}, {2, 2, 0.}, {2, 3, 0.}},
 {{3, 0, 0.}, {3, 1, 0.}, {3, 2, 7.4}, {3, 3, 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.