3
$\begingroup$

Consider a list of lists of $ m \times n \times 3 $:

{
 {{a1, R1, c11}, {a2, R1, c12}, {a3, R1, c13}, ..., {an, R1, c1n}},
 {{a1, R2, c21}, {a2, R2, c22}, {a3, R2, c23}, ..., {an, R2, c2n}},
 ...,
 {{a1, Ri, ci1},    ... ,    {aj, Ri, cij}, ..., Null, Null, Null},
 ...,
 {{a1, Rm, cm1}, {a2, Rm, cm2}, {a3, Rm, cm3}, ..., {an, Rm, cmn}}
}

In each 1st-level list, the 2nd element $ R_i $ is fixed ($ i = 1, 2, ..., m $ for each row), the 1st element changes from $ a_1 $ to $ a_n $. Note that the data is produced by calculation and the elements of the 1st-level list may be Null, in this case, the Null should be ignored in the data processing. Here is a minimum sample data.

The question is how to find the maximum of the function $f=a_jc_{ij}$ corresponding to each $R_i$ in order to plot a curve of $f_\mathrm{max}$ vs. $R_i$ ? Thank you for any suggestions.

$\endgroup$
5
  • 3
    $\begingroup$ Try ListPlot[{#[[1, 2]], Max[First[#]*Last[#] & /@ #]} & /@ array], where array is your m by n by 3 list. $\endgroup$
    – LouisB
    Sep 2, 2020 at 5:48
  • $\begingroup$ @LouisB there may be Null in my data, straightforward usage of this command has a problem related to this. Please see my update. Sorry for the missing of the key point. $\endgroup$
    – user55777
    Sep 2, 2020 at 7:01
  • 1
    $\begingroup$ A simple modification to consider only the lists (ignoring the nulls, etc) would be ListPlot[{#[[1, 2]], Max[First[#]*Last[#] & /@ Cases[#, _List]]} & /@ array] $\endgroup$
    – LouisB
    Sep 2, 2020 at 7:12
  • $\begingroup$ @LouisB #[[1, 2]] is used to pick out $R_i$ of each row (1st-level list), so the 1 can be changed to 2, 3, and so on because each sublist in the 1st-level list has the same $R_i$. Right? But when changing it to, say, 2 the command does not work. Why? $\endgroup$
    – user55777
    Sep 2, 2020 at 7:47
  • $\begingroup$ Works for me the symbolic array in the question. Please add your actual data, or a significant sample of if, to your question so everyone can see the problem. $\endgroup$
    – LouisB
    Sep 2, 2020 at 7:55

3 Answers 3

2
$\begingroup$

In the following, we define our function f, make-up some data, find the Max of f, and finally plot the “curve” that results.

f=#[[All,1]]*#[[All,3]]&;

SeedRandom[123]
data=Table[{RandomReal[],#,RandomReal[]}&/@Range@5,5]//Transpose;

maxdatalist={#[[All,2]][[1]]&/@#,Max/@f/@#}&@data//Transpose;

ListLinePlot[maxdatalist]

Output of above code-block.

Perhaps this will give you something to work off of? Please, let me know how I can improve it if this works for you?

Edit: If this data has Null contained in it, as the further example will show, one can just remove these elements & use the previous method:

dataWnull={{{0.455719,1,0.977826},{0.0485906,1,0.628267},{0.470198,1,0.40324},{0.562943,1,0.549196},{0.392393,1,0.436287},Null,Null,Null},{{0.943215,2,0.962216},{0.277987,2,0.0902176},{0.971585,2,0.314929},{0.48161,2,0.644256},{0.56848,2,0.482909}},{{0.302348,3,0.466709},{0.876587,3,0.109107},{0.12578,3,0.27226},{0.417551,3,0.704522},{0.160465,3,0.963333},Null,Null},{{0.0616383,4,0.385645},{0.265758,4,0.91861},{0.605748,4,0.671763},{0.961331,4,0.903807},{0.0461463,4,0.496263},Null},{{0.429838,5,0.778744},{0.169916,5,0.0995785},{0.242401,5,0.491803},{0.870494,5,0.631661},{0.495921,5,0.0123512}}};

data2=DeleteCases[Null]/@dataWnull;

maxdata2list={#[[All,2]][[1]]&/@#,Max/@f/@#}&@data2//Transpose;

ListLinePlot[maxdata2list]

Same as above.

$\endgroup$
3
  • $\begingroup$ there may be Null in my data, straightforward usage of this command has a problem related to this. Please see my update. Sorry for the missing of the key point. $\endgroup$
    – user55777
    Sep 2, 2020 at 7:11
  • $\begingroup$ @user55777 can you provide the data in an easily copy & paste-able format? I think it should not be discouraged if you put this in plain-text (or within a code-block) as an edit to your question? Simply put, I’m on a mobile device & I can’t copy the data you’ve provided to my Wolfram cloud app. $\endgroup$ Sep 2, 2020 at 7:22
  • $\begingroup$ @user55777 please see my update. $\endgroup$ Sep 2, 2020 at 7:40
2
$\begingroup$
    First[#].Last[#] & /@ 
 Thread /@ {{{a1, R1, c11}, {a2, R2, c12}, {a3, R3, c13}}, {{a1, R1, 
     c21}, {a2, R2, c22}, {a3, R3, c33}}}

Need to be updated.

BTW,Where are the data?

$\endgroup$
0
2
$\begingroup$

Let's start with a symbolic array, like the one in the question

symArray = {
   {{a1, R1, c11}, {a2, R1, c12}, {a3, R1, c13}, {an, R1, c1n}}, 
   {{a1, R2, c21}, {a2, R2, c22}, {a3, R2, c23}, {an, R2, c2n}}, 
   {{a1, Ri, ci1},     Null,      {aj, Ri, ci3},     Null, Null, Null},
   {{a1, Rm, cm1}, {a2, Rm, cm2}, {a3, Rm, cm3}, {an, Rm, cmn}}};
symArray // MatrixForm;

The maximum products can be calculated from symArray as

Max[First[#]*Last[#] & /@ Cases[#, _List]] & /@ symArray;
% // Column

(*  Max[a1 c11,a2 c12,a3 c13,an c1n]
    Max[a1 c21,a2 c22,a3 c23,an c2n]
    Max[a1 ci1,aj ci3]
    Max[a1 cm1,a2 cm2,a3 cm3,an cmn]   *)

Now do it with a numeric array

SeedRandom[123]
mcols = 3; nrows = 4;
a = RandomInteger[{-10, 10}, nrows];
r = RandomSample[Range[mcols*nrows], nrows] // Sort;
c = RandomReal[{-10, 10}, {mcols, nrows}];
numArray = 
  Table[{a[[k]], r[[k]], c[[j, k]]}, {k, nrows}, {j, mcols}];
numArray[[2]] = Join[Most[numArray[[2]]], {Null, Null, Null}];
numArray // MatrixForm;

ListLinePlot[{FirstCase[#, x_List :> x[[2]]], 
    Max[First[#]*Last[#] & /@ Cases[#, _List]]} & /@ numArray]

The FirstCase is used to avoid any Nulls.

enter image description here

$\endgroup$

Your Answer

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

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