Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

This is strongly related to the following Questions:

I am looking for an efficient method to insert an array into an array. Let’s assume that both arrays have similar number of rows. Let’s further assume insertion is by column.

a = {{a1, b1, c1, d1, e1}, {a2, b2, c2, d2, e2}, {a3, b3, c3, d3, e3}}; (*example may be larger*)
b = {{x1, y1, z1}, {x2, y2, z2}, {x3, y3, z3}}; (*example may be larger*)

Q1: What is the fastest method to insert b into a at a position p. Let’s assume that both arrays have similar number of rows. Let’s further assume insertion is by column.

My current method is as follows:

insertarray[a_, b_, pos_] :=
FlattenAt[
Transpose@Insert[Transpose@a, b[[##]], pos ] & [Range[Length@a]], 
Table[{i, pos}, {i, 1, Length@a}]];

which allows me to do

insert array

Q2: Some times I have to intersperse columns of b into a at multiple positions. How do I best extend insertarray so that:

insertarray[a,b,{1,2,5}]//MatrixForm

enter image description here

share|improve this question
1  
"Insertion" is not very well defined as shown unless a and b both have the same length. If this is the case, you should tell everyone that constraint. –  VF1 Mar 21 at 15:14
    
@VF1 a and b both have the same number of column elements... but yes, it would be better to be explicit whether the insertion is by row or column (esp. with square matrices) –  rm -rf Mar 21 at 15:16
    
Edited for clarity. Added constraint insertion is by column. –  Pam Mar 21 at 15:17

4 Answers 4

up vote 7 down vote accepted

Q1

Join[a[[;; , ;; 1]], b, a[[;; , 2 ;;]], 2]

enter image description here

One may want to create function

insCol[a_, b_, n_] := Join[a[[;; , ;; n - 1]], b, a[[;; , n ;;]], 2]

insRow[a_, b_, n_] := Join[a[[;; n - 1]], b, a[[n ;;]]]
share|improve this answer
    
This one's really fast (and the cleanest solution, too) - good job! –  VF1 Mar 21 at 17:01
    
@VF1 Great you like it, thanks ;) –  Kuba Mar 21 at 17:36
    
I really like this solution. its very clean and does the job well… –  Pam Mar 21 at 17:59

After a few attempts, the following gives a noticeable if unremarkable improvement over insertarray:

columnInsert[a_, b_, pos_] := 
  MapThread[Join[#1[[;; pos - 1]], #2, #1[[pos ;;]]] &, {a, b}];

Your second functionality doensn't actually need anything fancy, just some swaps afterwards:

SetAttributes[columnInsert`swap, HoldFirst];
columnInsert`swap[mat_, first_, list_] :=
 Module[{i = first}, 
  Scan[columnInsert`tmp = mat[[All, i]]; 
     mat[[All, i++]] = mat[[All, #]]; 
     mat[[All, #]] = columnInsert`tmp; &, list]; mat]
columnInsert[a_, b_, pos_List] := 
 Module[{res = columnInsert[a, b, First@pos]},
  columnInsert`swap[res, First@pos, pos]; res]
share|improve this answer
    
VF1. Thanks. I tried the MapThread method as well… I was almost going to accept this as the solution… –  Pam Mar 21 at 18:01

I haven't had a chance to test if this is faster (probably not), but I find it easier to read:

Block[{x, T = Transpose}, Insert[T@a, x, 2] /. x -> Sequence @@ T@b // T]

or alternately:

MapThread[Flatten[## ~Insert~ 2] &, {a, b}]

Both give the following:

share|improve this answer
    
You beat me to the second one. I didn't find it much faster, though. One thing that sped it up slightly is Flatten[..., 1] –  VF1 Mar 21 at 15:34

Inserting b at column p :-

a = {{a1, b1, c1, d1, e1}, {a2, b2, c2, d2, e2}, {a3, b3, c3, d3, e3}};
b = {{x1, y1, z1}, {x2, y2, z2}, {x3, y3, z3}};

p = 4;

c = ReleaseHold@MapThread[Insert, {a, Hold[Sequence @@ #] & /@ b, Table[p, {Length@a}]}];

MatrixForm[c]

enter image description here

share|improve this answer
    
I tried something along these lines, but I found the additional ReleaseHold was too expensive - the whole expression needed to be traversed again for Holds. –  VF1 Mar 21 at 17:00
    
@VF1 - I wondered. It will be interesting to see the timings. –  Chris Degnen Mar 21 at 18:39

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.