2
$\begingroup$

Let's say we have a matrix (or an arbitrary 2+D list) x and an integer vector l of the same length. What is the most elegant way to get a list {x[[1,l[[1]]]], x[[2, l[[2]]]],...}? The best solution I can think about is

x[[#, l[[#]]]]&/@Range@Length@x

, but I'm sure there should be a much easier/more elegant way.

$\endgroup$
  • $\begingroup$ Can you give an example of list x and vector l? It's not completely clear to me what "l" is. It also seems to me that l needs an additional condition, i.e. it's elements must be less or equal then the 2+D dimension of the matrix $\endgroup$ – Fraccalo Jul 2 '18 at 10:59
  • $\begingroup$ x is an arbitrary matrix, e.g. x = RandomReal[{0., 1.}, {3, 3}]. l is a list of integers with the same length as x, e.g. l={1,2,2}. Yes, this additional condition is required if we want the code to be evaluated without errors. $\endgroup$ – Ihor Jul 2 '18 at 11:03
5
$\begingroup$

This might not be the most elegant way to do that, but it is descently efficient to use Extract:

m = 1000;
n = 2000;
x = RandomReal[{-1, 1}, {m, n}];
l = RandomInteger[{1, n}, m];

a = x[[#, l[[#]]]] & /@ Range@Length@x; // AbsoluteTiming // First
b = Flatten@MapIndexed[x[[#2, #1]] &, l]; // AbsoluteTiming // First
c = Extract[x, Transpose[{Range[Length[l]], l}]]; // AbsoluteTiming // First
a == b == c

0.140761

0.002416

0.000067

True

$\endgroup$
5
$\begingroup$
MapIndexed[x[[#2, #1]] &, l]

An example:

SeedRandom[90]; x = RandomReal[{0., 1.}, {3, 3}]
l = {1, 2, 2};
MapIndexed[x[[#2, #1]] &, l]

{{0.647385, 0.307327, 0.702473}, {0.656437, 0.675096, 0.0759657}, {0.733796, 0.139355, 0.0910026}}

{{0.647385}, {0.675096}, {0.139355}}

$\endgroup$
4
$\begingroup$

How about

MapThread[#1[[#2]]&, {x,l}]

or equivalently

MapThread[
  With[{f = #1, x = #2}, 
    Construct[f[[#]] &, x]] &, {x, l}]
$\endgroup$

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.