3
$\begingroup$

I have an n-number of Lists of equal sizes. I want to perform different operations on different positions (sub-elements) on these lists (but avoid using For, Do etc. as using Thread, and MapThread etc. should be faster).

  1. First sub-elements are the same in all n-list and in the final output it will remain the same.
  2. Second sub-elements are added.
  3. Third sub-elements are added in quadrature and finally, we take the square root of that.

In principle, it is not limited to these operations only, but this is an example to show the question.

Using inspiration from Difference of certain elements from two lists I tried the following:

list1={{A1,A11,A12},{B1,B11,B12},{C1,C11,C12}};
list2={{A1,A21,A22},{B1,B21,B22},{C1,C21,C22}};
list3={{A1,A31,A32},{B1,B31,B32},{C1,C31,C32}};
... (n-number of lists)
allList = {list1, list2, list3} (**can be extended to n-numbers**)

MapThread[Flatten@{First[#],If[SameQ[Rest[#],{}],Nothing,{Rest[+##][[1]],Rest[Sqrt[+#^2]][[2]]}  ]}&,allList]

while I can achieve #1 and #2, I am struggling to get #3.

The expected output:

{{A1, A11 + A21 + A31, Sqrt[A12^2+A22^2+A32^2]}, 
 {B1, B11 + B21 + B31, Sqrt[B12^2+B22^2+B32^2]}, 
 {C1, C11 + C21 + C31, Sqrt[C12^2+C22^2+C32^2]}}

For a small number of lists (n=3) in this example, I can achieve this as

MapThread[Flatten@{First[#],If[SameQ[Rest[#],{}],Nothing,
{Rest[+##[[1]],Sqrt[Rest[#1][[2]]^2+Rest[#2][[2]]^2+Rest[#3][[2]]^2]}  ]}&,allList]

But I want to know if there are any general approaches similar to #2 where +## is used in order to sum up all the second elements. In this context, I was wondering how to access (if it is possible at all) Slot #1, #2, #3, ... etc. using a dummy variable #i? For example I was thinking Sqrt[Sum[Rest[#i][[2]]^2],{i,1,Length[allList]}].

$\endgroup$
0

2 Answers 2

6
$\begingroup$

It is easier to work with the Transpose of allList because all elements needed for a result row are in a single row.

We may define a function that assembles the elements:

fun = {#1[[1, 1]], Total@#1[[All, 2]], Sqrt@Total[#[[All, 3]]^2]} &;

and map it on the transposed data:

Map[fun, Transpose[allList]]

enter image description here

$\endgroup$
2
$\begingroup$

Daniel Huber's answer is much easier to understand and debug but if you want to play with MapThread, here is a solution (it's a little faster than Daniel but consumes a little more memory):

Transpose@
 MapThread[
  Map, {{First, Total, Norm}, 
   Transpose[{list1, list2, list3}, {3, 2, 1}]}]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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