2010-11-24 12 views
13

İki boyutlu bir listeye ve bir boyutlu bir listeye sahibim. 1D listesini 2B listesine ek bir sütun olarak eklemek istiyorum. Örneğin:Bir tablonun satırlarına ekleme

Table[Insert[array[[i]], column[[i]], 4], {i, Length[array]}]; 

Benim sorum: Mathematica bunu yapmanın doğru yolu nedir

array = {{a,1,2},{b,2,3},{c,3,4}}; 
column = {x,y,z}; 

final = {{a,1,2,x},{b,2,3,y},{c,3,4,z}}; 

Ben inelegantly yapmış olur? Kullanmakta olduğum döngüye ihtiyacı olduğunu düşünmüyorum. Benim çözümüm çirkin hissediyor. Örneğin

cevap

14

: Sık sık kullanmak zorunda olmadığını o kolaylaştırır

subListAppend = [email protected][[email protected]#1, #2] &; 
subListAppend[array, column] 

:

[email protected][[email protected], column] 

Ayrıca yapabilirsiniz bir işlev böylece gibidir. Ve tabii ki, sondan başka bir yere eklemek isterseniz Insert[]'u kullanabilirsiniz.

subListInsert = [email protected][[email protected]#1, #2, #3] &; 
subListInsert[array, column, 2] 
--> {{a, x, 1, 2}, {b, y, 2, 3}, {c, z, 3, 4}} 

EDIT: zorunlu hız optimizasyon tartışma başladığından bu yana, burada this ve 10000x200 dizisi kullanarak bazı sonuçlar şunlardır:

[email protected]{{array, List /@ column}}:    0.020 s 
[email protected][[email protected], column]:   0.067 s 
MapThread[Append, {array, column}]:     0.083 s 
MapThread[Insert[#1, #2, 4] &, {array, column}]: 0.095 s 
Map[Flatten, Flatten[{array, column}, {2}]]:  0.26 s 
ConstantArray based solution:      0.29 s 
Partition[[email protected][{array, column}], 4]: 0.48 s 

Ve kazanan ArrayFlatten olduğunu! ek bir değişkeni gerektirir rağmen

+1

Tamam, hile yaptığını, teşekkür ederim! Şimdi bunu anlamak için şunu seçmeliyim * neden *, ama bu benim için. –

+0

Her seferinde bir öğeye gidin (örn. Transpose @ dizisinin ne yaptığını görün) ve bunu çözeceksiniz :-). – Timo

+0

Evet, bu yardımcı oldu. Origami gibi. Mathematica ile gereksiz yere savaştığımı biliyordum. Tekrar teşekkürler. –

5

başka olasılık, daha hızlı geniş sayısal matrisleri için bilgisayarımda gibi görünüyor

result = ConstantArray[0, Dimensions[array] + {0, 1}]; 
result[[All, 1 ;; Last[Dimensions[array]]]] = array; 
result[[All, -1]] = column; 

olduğunu. Gerçek değerli girdilerle ilgileniyorsanız, hız kazanımlarını korumak için

result = ConstantArray[0.0, Dimensions[array] + {0, 1}]; 

'u kullanabilirsiniz.

da (IMO ve zarif) hızlı ama sonuç paketini açacak

MapThread[Append, {array, column}] 

da var. (Eğer örnekte olduğu gibi sembolik girişler varsa Ama, bu bir endişe değil.)

+0

Teşekkürler Brett. MapThread kullanımınız gerçekten zariftir. Transpose cevabını ilk olarak gördüğüme sevindim, çünkü kullandığı kavramların daha geniş çapta uygulanabilir olduğuna dair bir fikrim var, ancak bu çok ama çok özlü. Matrislerim ConstantArray yaklaşımı için fazladan kod satırlarını garantilemek için yeterince büyük değil ve esas olarak sembolik verileri içeriyorlar. Yine de, aynı soruna dört farklı yaklaşım: Mathematica! –

+0

İlginç, OP 'nin örneğini kullanarak yaklaşık% 35 daha iyi "Zamanlama" alıyorum ve yöntemimi kullanarak büyük (1k - 1M girişleri) matrisler için on daha iyi bir hızla karşılaşıyorum. Çekirdek seviyesindeki en farklı liste manipülasyonları, aynı (çok optimize edilmiş) kod ile gerçekleştirilir, bu yüzden MMA'yı bazı şeyleri belirli bir şekilde yapmaya zorlamak (diğer dillerdeki doğru/optimal) zorlamak çoğu kez ek yüke yol açar. – Timo

+0

Testlerimi OS X üzerinde V8 ile yapıyordum. –

2

Still: Bu nasıl hakkında

k= Partition[[email protected][{#, {x, y, z}}], 4]& 

[email protected] {{a, 1, 2}, {b, 2, 3}, {c, 3, 4}} 

(* 
-> {{a, 1, 2, x}, {b, 2, 3, y}, {c, 3, 4, z}} 
*) 
+0

Bu beş yaklaşımlar yapın. Bu bir sosis gibi: yiyebilirsin, ama nasıl yapıldığını görmek istemiyorsun :) –

3

?

pos = 4; 
MapThread[Insert[#1, #2, pos] &, {array, column}] 
3

Düzleştirilmiş bir diziyle çalıştığından, Düzten ile aktarım yapmayı severim (bazen).

veren

Map[Flatten, Flatten[{array, column}, {2}]] 

{{a, 1, 2, X}, {b, 2, 3, y}, {C, 3, 4, Z}}

Fakat eğer, diyelim ki, kolon sadece 2 elemanları veren

column2 = {x, y}; 
Map[Flatten, Flatten[{array, column2}, {2}]] 

sahiptir

{{a, 1, 2, x}, {b, 2, 3, y} ', {c, 3, 4}}

(burada çalışmaz Devrik) İşte

5

benim deneyin

In[11]:= Join[array,List/@column,2] 
Out[11]= {{a,1,2,x},{b,2,3,y},{c,3,4,z}} 

Daha önce bahsedildiği programları arasında en hızlı ile karşılaştırılabilir olabilir Üyelik kullanıyor.

pratik veya kaybolmamış yöntemlerden bazıları, burada listeye eklenecek iki olduğu gibi verimli değil
+0

+1 Çok güzel! Açık ve anlaşılır. –

+0

Bu sayfada henüz bir “Join” yönteminin kullanılmadığına şaşırdım, çünkü bunu yapmanın en doğal (ve etkili) yollarından biri gibi görünüyor. +1 –

1

olsa:

ArrayPad[array, {0,{0,1}}, List /@ column] 

PadRight[array, Dimensions[array] + {0, 1}, List /@ column]