2011-03-29 13 views
5

S, benzersiz öğeleri olan bir vektörü ve s bir alt kümesini, aynı zamanda benzersiz öğelerle de yapın; ör. S={1,2,3,4,5,6} ve s={1,3,4,6}. S[[i]]s bir eleman ise, şimdi bir vektör C=[7,0,8,9,0,7] oluşturabilir nasıl bir vektör c={7,8,9,7} verilen diğer bir deyişle, daha sonra C[[i]] başka s içinde S[[i]], sıfır ile aynı dizin ile c eleman eşittir. Bu çalışır, ancak bir MATLAB geçmişten gelerek, ben for döngüler nefret ve yukarıdaki işlem Matlab'de önemsiz bir indeksleme operasyonuMathematica'da dizin oluşturma

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

gibi ne var

şu anda görünüyor. Eminim bunu başarmak için daha akıllı bir yol var, bir matematiksel stili. Önerisi olan var mı? böylece c veya 0'dan bir unsuru biriyle S

+1

Bu aşağıdaki yanıtları ile ilgili değil, ama 'C = Array daha iyi C = ConstantArray [0, Uzunluk' şeklinde ifade [0 & ...] 'edilir [S]] 've önyükleme yapmak için on kat daha hızlı. –

cevap

4

Bu şimdiye kadar yayınlanan edilmiştir ne daha hızlıdır:

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. Gönderimin anlamlı olup olmadığından emin değil. Listenin uzunluğuna göre değişir. –

+0

@Sjoerd Kısa bir test, kısa listelerde çok az ceza olduğunu gösterir ve uzun listelerde daha hızlıdır. Neden içermez? –

+0

@Wizard, bu hızlıydı. Bu son argümanın ne yaptığını açıklar mısınız? Dokümantasyona baktım ve bunun "levelspec" olduğunu söyledi, ancak gösterilecek başka örnek yoktu. Onunla oynamak, bunun için sıfır olmayan herhangi bir değer aynı cevabı veriyor gibi görünüyordu. –

5

Sen değiştiriyorsanız elemanları:

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

İşte bir yoludur. Muhtemelen başka birçok var.

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

Kullanıcı tanımlı semboller için geleneksel olduğu gibi, küçük harf değişken isimlerini kullandım.

Mathematica, vektörler, listeler, matrisler ve tablolar için kaşlı ayraçlar kullanır.

+0

@ d'o-o'b Özgün öneride küçük bir değişiklik yaptım: 'Kasalar' ın, aslında her bir eleman üzerinde etkili olduğunu fark ettikten sonra ortadan kaldırdım. Değiştir ve son argümanı için – 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]]] 

DÜZENLEME ya:

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

S Eğer formda {1, 2, ..., n}, (örneğin Range[n] arasında her zaman) Daha sonra SparseArray kullanarak bu çözüm, @Mr kadar iki kat daha hızlıdır. Büyücü çok büyük listeleri için benim test cevap:

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

"Konum" bu yaklaşıma dahil edilebilir mi? – tomd

+0

'Position' nedir? –

+0

SubS'nin ss'nin belirli bir alt kümesi olduğu, ancak ss öğelerinin zorunlu olarak sipariş edilmediği durumlarda düşünmekteydim. Belki OP aksi ima eder? Eğer diyelim ki, ssalt = {2, 4, 1, 5, 6, 3} ve subSalt = {4, 1, 6, 3} sonra (örneğin) 'Değiştir [ssalt, Dispatch @ Ek [Konu [subSalt -> c], _ -> 0], 1] == Normal [SparseArray [Düzleştir @ Konum [ssalt, #] &/@ subSalt -> c], 6, 0]] '. (SubS'nin her zaman gerekçelendirilmiş bir altkümenin olduğu varsayımı var mı? Sanırım) – tomd

İlgili konular