2011-03-29 7 views
5

Sea S sea un vector con elementos únicos, y s un subconjunto de él, también con elementos únicos; por ejemplo, S={1,2,3,4,5,6} y s={1,3,4,6}. Ahora dado otro vector c={7,8,9,7}, ¿cómo puedo crear un vector C=[7,0,8,9,0,7], es decir, si S[[i]] es un elemento en s, entonces C[[i]] es igual al elemento en c con el mismo índice como S[[i]] en s, otro cero.Indización de lista en mathematica

Lo que tengo en este momento se ve como

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;]]; 

Esto funciona, pero viniendo de un fondo de MATLAB, odio for bucles y la operación anterior es una operación de indexación trivial en MATLAB. Estoy seguro de que hay una manera más inteligente de lograr esto, un estilo la mathematica. ¿Alguien tiene sugerencias?

+1

Esto no está relacionado con las respuestas a continuación, pero 'C = Array [0 & ...]' se expresa mejor como 'C = ConstantArray [0, Longitud [S]] ', y diez veces más rápido para arrancar. –

Respuesta

4

Esto es más rápido que lo que se ha publicado hasta ahora:

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

Replace[ss, [email protected][Thread[s -> c], _ -> 0], 1] 
+1

+1 para Reemplazar y su último argumento. No estoy seguro si el envío tiene sentido. Depende de la longitud de la lista. –

+0

@Sjoerd Una prueba rápida indica que tiene poca penalización en listas cortas, y es drásticamente más rápido con listas largas. ¿Por qué no incluirlo? –

+0

@Wizard, eso fue rápido. ¿Podrías explicar qué hace ese último argumento '1'? Miré hacia arriba en la documentación y decía que era 'levelspec', pero no había más ejemplos para ilustrar. Jugando con él, cualquier valor distinto de cero parecía dar la misma respuesta. –

5
elementos

va a sustituir de S, ya sea con un elemento en C o con 0, así que:

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] 
1

Aquí está una manera. Probablemente haya muchos otros.

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]} 

He utilizado nombres de variables de minúscula en todo el sentido de los símbolos definidos por el usuario.

Las llaves usadas de Mathematica se utilizan para vectores, listas, matrices y tablas.

+0

@ d'o-o'b Hice una pequeña modificación a la propuesta original: eliminé 'Cases' después de darme cuenta de que de hecho estaba actuando en cada elemento de s. – DavidC

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]]] 

EDITAR o:

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

Si S es siempre de la forma {1, 2, ..., n}, (por ejemplo, Range[n]) entonces esta solución que usa SparseArray es aproximadamente dos veces más rápida que @Mr. La respuesta de asistente en mi prueba para listas muy grandes:

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

¿Se puede incorporar 'Posición 'en este enfoque? – tomd

+0

¿Para qué es 'Posición 'necesaria? –

+0

Estaba pensando en el caso en que subS es un subconjunto ordenado de ss, pero donde los elementos de ss no están necesariamente ordenados. Tal vez el OP implica lo contrario? Si, por ejemplo, ssalt = {2, 4, 1, 5, 6, 3} y subSalt = {4, 1, 6, 3}, entonces (por ejemplo) 'Replace [ssalt, Dispatch @ Append [Thread [subSalida -> c], _ -> 0], 1] == Normal [SparseArray [ Subproceso [Flatten @ Position [ssalt, #] &/@ subSaltar -> c], 6, 0]] '. (¿Es la suposición de que subS es un subconjunto ordenado siempre justificado? Supongo que sí) – tomd