5
$\begingroup$

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

$\endgroup$
  • 1
    $\begingroup$ "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. $\endgroup$ – VF1 Mar 21 '14 at 15:14
  • $\begingroup$ @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) $\endgroup$ – rm -rf Mar 21 '14 at 15:16
  • $\begingroup$ Edited for clarity. Added constraint insertion is by column. $\endgroup$ – Pam Mar 21 '14 at 15:17
8
$\begingroup$

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 ;;]]]
$\endgroup$
  • $\begingroup$ This one's really fast (and the cleanest solution, too) - good job! $\endgroup$ – VF1 Mar 21 '14 at 17:01
  • $\begingroup$ @VF1 Great you like it, thanks ;) $\endgroup$ – Kuba Mar 21 '14 at 17:36
  • $\begingroup$ I really like this solution. its very clean and does the job well… $\endgroup$ – Pam Mar 21 '14 at 17:59
2
$\begingroup$

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]
$\endgroup$
  • $\begingroup$ VF1. Thanks. I tried the MapThread method as well… I was almost going to accept this as the solution… $\endgroup$ – Pam Mar 21 '14 at 18:01
0
$\begingroup$

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:

$\endgroup$
  • $\begingroup$ 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] $\endgroup$ – VF1 Mar 21 '14 at 15:34
0
$\begingroup$

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

$\endgroup$
  • $\begingroup$ 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. $\endgroup$ – VF1 Mar 21 '14 at 17:00
  • $\begingroup$ @VF1 - I wondered. It will be interesting to see the timings. $\endgroup$ – Chris Degnen Mar 21 '14 at 18:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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