2
$\begingroup$

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]}];

Please, any help?

| improve this question | | | | |
$\endgroup$
  • 1
    $\begingroup$ 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. $\endgroup$ – Henrik Schumacher Feb 6 at 7:00
  • $\begingroup$ Ok, I'll try to simplify the problem $\endgroup$ – Mick Feb 6 at 18:01
  • $\begingroup$ 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? $\endgroup$ – kglr Feb 7 at 5:51
  • $\begingroup$ 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 $\endgroup$ – Mick Feb 7 at 13:48
2
$\begingroup$

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}}, 
    addfirstColumn @ ##, 
   {{"", SpanFromLeft, SpanFromLeft, SpanFromLeft}}] &;

Use KeyValueMap to map kvm to asmatches:

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

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

enter image description here

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, 
    headerC, headerR, blankR, kvM,
    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@#]]} &;
  kvM = Join[headerR@#2, Join[headerC @#, outer@##, 2], blankR@#2] &;
  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}]]

enter image description here

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]

enter image description here

| improve this answer | | | | |
$\endgroup$
  • $\begingroup$ 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? $\endgroup$ – Mick Feb 7 at 5:16
  • $\begingroup$ 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. $\endgroup$ – Mick Feb 7 at 5:42
  • 1
    $\begingroup$ @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. $\endgroup$ – kglr Feb 7 at 7:45
  • $\begingroup$ Thank you kglr, I’ll try soon and then I’ll post here the link for this next step new question!!! $\endgroup$ – Mick Feb 7 at 13:54
  • $\begingroup$ Hi kglr, here the link for the new question topic:mathematica.stackexchange.com/questions/214443/… $\endgroup$ – Mick Feb 9 at 15:54
0
$\begingroup$

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.

| improve this answer | | | | |
$\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.