开发者

List indexing in mathematica

Let S be a vector with unique elements, and s a subset of it, also with unique elements; e.g., S={1,2,3,4,5,6} and s={1,3,4,6}. Now given another vector c={7,8,9,7}, how can I create a vector C=[7,0,8,9,0,7], i.e., if S[[i]] is an element in s, then C[[i]] is equal to the element in c with the same index as S[[i]] in s, else zero.

What I have right now looks like

C=Array[0&,Length[S]];
j=1;
For[i=1,i<=Length[S],i++,If[MemberQ[s,S[[i]]],C[[i]]=c[[j]];j=j+1;]]; 

This works, but coming from a MATLAB background, I hate for loops and the above operation is a trivial indexing operation in matlab. I'm sure there is a smarter way to accomplish this, a la m开发者_开发问答athematica style. Does anyone have suggestions?


You are replacing elements of S with either an element in c or with 0, so:

ss = {1, 2, 3, 4, 5, 6}
s = {1, 3, 4, 6}
c = {7, 8, 9, 7}
r = Append[MapThread[Rule, {s, c}], Rule[_, 0]]
answer = Map[Replace[#, r] &, ss]


This is faster than what has been posted so far:

ss = {1, 2, 3, 4, 5, 6};   s = {1, 3, 4, 6};   c = {7, 8, 9, 7};

Replace[ss, Dispatch@Append[Thread[s -> c], _ -> 0], 1]


ss = {1, 2, 3, 4, 5, 6};
s = {1, 3, 4, 6};
c = {7, 8, 9, 7};
ss /. Join[MapThread[Rule, {s, c}],Thread[Rule[Complement[ss, s], 0]]]

EDIT or:

answer = 0 ss; answer[[Position[ss, #, 1] & /@ s // Flatten]] = c;


Here's one way. There are probably many others.

s = {1, 2, 3, 4, 5, 6};
subS = {1, 3, 4, 6};
c = {7, 8, 9, 7};
d= s /. {x_Integer :> If[MemberQ[subS, x], c[[Position[subS, x][[1, 1]]]], 0]}

I used lower case variable names throughout as is customary for user-defined symbols.

Mathematica uses curly braces are used for vectors, lists, matrices, and tables.


If S is always of the form {1, 2, ..., n}, (e.g., Range[n]) then this solution using SparseArray is about twice as fast as @Mr. Wizard's answer in my testing for very large lists:

Normal[SparseArray[Thread[s -> c], n, 0]]
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜