# Automate table to display figures

With reference to the post Automate Poisson Football Scores Prediction, I succeded in defining the Poisson probability density function for home (μh=A) and away (μa=B) teams, but cannot create a table/matrix taking into account the next matches round thanks to the vector matchesENG and the product between p[A, x]*p[B, x] because I am not able to recognize the actual home team and away team for each match and displaying the scores. Here the complete nb.

ClearAll;
Cl = Import["https://www.soccerstats.com/homeaway.asp?league=england",
"Data"];
Chome = Drop[Drop[Cl[[2, 4, 1]]], 1];
Caway = Drop[Drop[Cl[[2, 4, 2]]], 1];
teamsENG = Chome[[All, 2]];
dataENG =
Import["https://www.soccerstats.com/results.asp?league=england&\
pmtype=bydate", "Data"];
Drop[Drop[Drop[Cases[dataENG, {_, _, _, _}, Infinity], -4], -1, None],
None, -1];
Take[Table[
If[StringContainsQ[%[[i, 2]], ":"] == True, %[[i]], ## &[]], {i, 1,
Length[%]}], Length[teamsENG]/2];
Table[StringSplit[%[[i]], "-"], {i, 1, Length[%]}];
matchesENG =
Transpose[{StringTrim[%[[All, 3, 1]]], StringTrim[%[[All, 3, 2]]]}];
A = ConstantArray[0, Length[teamsENG]];
B = ConstantArray[0, Length[teamsENG]];
Do[Do[Table[
If[matchesENG[[i, 1]] == Chome[[j, 2]] &&
matchesENG[[i, 2]] == Caway[[k, 2]],
A[[j]] =
A[[j]] +
N[((ToExpression[Chome[[j, 7]]]/
ToExpression[Chome[[j, 3]]]) + (ToExpression[
Caway[[k, 8]]]/ToExpression[Caway[[k, 3]]]))/
2], ## &[]], {k, 1, Length[teamsENG]}], {j, 1,
Length[teamsENG]}], {i, 1, Length[matchesENG]}];
Do[Do[Table[
If[matchesENG[[i, 1]] == Chome[[j, 2]] &&
matchesENG[[i, 2]] == Caway[[k, 2]],
B[[k]] =
B[[k]] +
N[((ToExpression[Chome[[j, 8]]]/
ToExpression[Chome[[j, 3]]]) + (ToExpression[
Caway[[k, 7]]]/ToExpression[Caway[[k, 3]]]))/
2], ## &[]], {k, 1, Length[teamsENG]}], {j, 1,
Length[teamsENG]}], {i, 1, Length[matchesENG]}];
μhome = Transpose[{teamsENG, A}];
μaway = Transpose[{teamsENG, B}];
ph[μh_, xh_] := PDF[PoissonDistribution[μh], xh];
Gh = Table[
If[μhome[[i, 2]] > 0, {μhome[[i, 1]],
Table[ph[μhome[[i, 2]], x], {x, 0, 10}]}, ## &[]], {i, 1,
Length[μhome]}];
pa[μa_, xa_] := PDF[PoissonDistribution[μa], xa];
Ga = Table[
If[μaway[[i, 2]] > 0, {μaway[[i, 1]],
Table[ph[μaway[[i, 2]], x], {x, 0, 10}]}, ## &[]], {i, 1,
Length[μaway]}];


I tried something like that to take next match home/away teams, but I cannot organize/display the result in a very clear and understandable manner.

X = Table[
Table[If[
matchesENG[[i, 1]] == Gh[[j, 1]] &&
matchesENG[[i, 2]] == Ga[[k, 1]],
Table[Gh[[j, 2, l]]*Ga[[k, 2, m]], {l, 1, 10}, {m, 1,
10}], ## &[]], {j, 1, Length[Gh]}, {k, 1, Length[Ga]}], {i, 1,
Length[matchesENG]}];


• How is the title of the post related to the content? Do we really have to read all the code in the first block? I really did not get your problem. Please get into the habit of writing minimal examples. – Henrik Schumacher Feb 6 '20 at 7:00
• Ok, I'll try to simplify the problem – Nate Feb 6 '20 at 18:01
• Mick, the setup in your answer below may be a better candidate for a minimal example. Perhaps you can post that answer as the question? – kglr Feb 7 '20 at 5:51
• Sure, how can I do? Actually, I tried to do it before but it was not successful so I posted it as a new question here mathematica.stackexchange.com/questions/214275/… ..I’m sorry, I am new in the forum – Nate Feb 7 '20 at 13:48

We can use matches, goalshome and goalsaway from user12590788's self-answer to define three associations:

{asmatches, ashome, asaway} = Association[Rule@@@#] & /@ {matches, goalshome, goalsaway};


Use Outer to get a table of products of associated entries:

outer = Outer[Times, ashome @ #, asaway @ #2] &;


Prepend the table with a column containing home team:

addfirstColumn = Join[List /@ {#, SpanFromAbove, SpanFromAbove}, outer@##, 2] &;


Add a row containing the visitor team name before and a blank row after each block:

kvm = Join[{{#2, SpanFromLeft, SpanFromLeft, SpanFromLeft}},
{{"", SpanFromLeft, SpanFromLeft, SpanFromLeft}}] &;


Use KeyValueMap to map kvm to asmatches:

grid = Join @@ KeyValueMap[kvm, asmatches];

Grid[grid, Alignment -> {Center, Center}, Dividers -> All, BaseStyle -> 16]


To combine all steps into a function that creates the desired grid given three lists as input:

ClearAll[makeGrid]
makeGrid[ml_, ghl_, gal_] :=  Module[{asm, ash, asa, outer,
assocs = Map[Apply[AssociationThread]@*Transpose] @ {ml, ghl, gal}},
{asm, ash, asa} = assocs;
outer = Outer[Times, ash@#, asa @#2] &;
headerC = List /@ Join[{#}, ConstantArray[SpanFromAbove, Length[ash@#] - 1]] &;
headerR = {Join[{#}, ConstantArray[SpanFromLeft, Length@asa@#]]} &;
blankR = {Join[{""}, ConstantArray[SpanFromLeft, Length@asa@#]]} &;
Join @@ KeyValueMap[kvM, asm]]


Use makeGrid[matches, goalshome, goalsaway] as first argument in Grid and add the desired grid options:

Grid[makeGrid[matches, goalshome, goalsaway],
Alignment -> {Center, Center}, BaseStyle -> 16]


same picture as above

An alternative, and simpler, approach is to create a separate grid for each pair in matches and use Labeled to label each grid:

{ashome, asaway} = Association[Rule @@@ #] & /@ {goalshome, goalsaway};

Column[matches /. {a_, b_} :> Labeled[
Grid[Outer[Times, ashome @ a, asaway @ b], Dividers -> All],
{a, b},
{Left, Top}]]


Note: Both methods work if the lengths of the goals lists are not the same for all teams:

SeedRandom[1]
matches2 = Partition[RandomSample[Array[Symbol["team" <> ToString@#] &, 10]],  2];

goalshome2 = Thread[matches2[[All, 1]] -> Table[RandomReal[1, RandomInteger[{2, 5}]], 5]];

goalsaway2 = Thread[matches2[[All, -1]] -> Table[RandomReal[1, RandomInteger[{2, 5}]], 5]];

{ashome2, asaway2} = Association[Rule @@@ #] & /@ {goalshome2, goalsaway2};

Column[matches2 /. {a_, b_} :>
Labeled[Grid[Outer[Times, ashome2@a, asaway2@b],
Dividers -> All], {a, b}, {Left, Top}], Dividers -> All]


• Amazing kglr, really thank you! Actually obtaining this grid is just an intermediate step, the final output should be to collect for each match the probabilities of the following events: 1 (home win, which means sum of all terms under matrix principal diagonal); X (draw, which means sum of all terms which makes matrix principal diagonal); 2 (away win, which means sum of all terms upper matrix principal diagonal); under/over “nr. goals” (for instance, if nr.goals=2, it means the sum of terms over/under the matrix secondary diagonal). Please, can you help me coding and display it on a table? – Nate Feb 7 '20 at 5:16
• The goal is to apped next to matches vector {team i, team j} the events probabilities vector: {1, X, 2 under 1.5, over 1.5, under 2.5, over 2.5, under 3.5, over 3.5}. Anyway, the length of goal list should be equal for all teams because every grid term represents the probability of an exact score for that match and I thought to consider a range Of six row/columns (0,1,2,3,4,5 goals) to derive probabilities of events 1,X,etc. by summing these. – Nate Feb 7 '20 at 5:42
• @Mick, maybe you can post a new question on what you want to do in the next step, using a minimal example like: for example, want to re-organize the input $\left\{\text{team1},\text{team2},\left( \begin{array}{ccc} a & b & c \\ d & e & f \\ g & h & i \\ \end{array} \right)\right\}$ into a form output = {1,X, 2...} showing how you map the input elements to the elements of desired output. – kglr Feb 7 '20 at 7:45
• Thank you kglr, I’ll try soon and then I’ll post here the link for this next step new question!!! – Nate Feb 7 '20 at 13:54
• Hi kglr, here the link for the new question topic:mathematica.stackexchange.com/questions/214443/… – Nate Feb 9 '20 at 15:54

I have a League with 6 teams and this vectors:

matches={{team1,team4},{team3,team2},{team5,team6}}

goalshome={{team1,{0.129812,0.265033,0.270555}},
{team3,{0.274812,0.354966,0.229249}},
{team5,{0.25284,0.347654,0.239012}}}

goalsaway={{team2,{0.129812,0.265033,0.270555}},
{team4,{0.274812,0.354966,0.229249}},
{team6,{0.25284,0.347654,0.239012}}}


I have to obtain automatically the following Table (assume goalshome=gh and goalsaway=ga):

                                            team 4
gh[[1,2,1]]*ga[[2,2,1]]  gh[[1,2,1]]*ga[[2,2,2]]  gh[[1,2,1]]*ga[[2,2,3]]
team 1 gh[[1,2,2]]*ga[[2,2,1]]  gh[[1,2,2]]*ga[[2,2,2]]  gh[[1,2,2]]*ga[[2,2,3]]
gh[[1,2,3]]*ga[[2,2,1]]  gh[[1,2,3]]*ga[[2,2,2]]  gh[[1,2,3]]*ga[[2,2,3]]

team 2
gh[[2,2,1]]*ga[[1,2,1]]  gh[[2,2,1]]*ga[[1,2,2]]  gh[[2,2,1]]*ga[[1,2,3]]
team 3 gh[[2,2,2]]*ga[[1,2,1]]  gh[[2,2,2]]*ga[[1,2,2]]  gh[[2,2,2]]*ga[[1,2,3]]
gh[[2,2,3]]*ga[[1,2,1]]  gh[[2,2,3]]*ga[[1,2,2]]  gh[[2,2,3]]*ga[[1,2,3]]

team 6
gh[[3,2,1]]*ga[[3,2,1]]  gh[[3,2,1]]*ga[[3,2,2]]  gh[[3,2,1]]*ga[[1,2,3]]
team 5 gh[[3,2,2]]*ga[[3,2,1]]  gh[[3,2,2]]*ga[[3,2,2]]  gh[[3,2,2]]*ga[[1,2,3]]
gh[[3,2,3]]*ga[[3,2,1]]  gh[[3,2,3]]*ga[[3,2,2]]  gh[[3,2,3]]*ga[[1,2,3]]


To do that, first I have to identify (from matches) team i VS team j in order to apply gh[[i,2,l]*ga[[j,2,m]], but I cannot code it.