Python: Provide All Possible Sums Between Different Values of Variables

Question:

Maybe you will be able to help me to solve somewhat simple issue – I am trying to figure out how domain of possible outcomes look.

  1. Imagine I have multiple variables with different set of potential values:
A = [0.9, 0.7, 1, 0.5]
B = [0, 1]
C = [0.3, 0.6, 0.9]
D = [-1.8, 0]

I need a list of all possible sums of different values between these variables, for example:

- sum1: 0.9 + 0 + 0.3 + (-1.8) = -0.6
- sum2: 0.9 + 1 + 0.3 + (-1.8) =  0.4
- sum3: 0.9 + 0 + 0.6 + (-1.8) = -0.3

Best case scenario data should be in dataframe and if there are some true magicians scenario could be identified next to each output, for example

Scenario Sum
A0.9_B0_C0.3_D-1.8 -0.6
A0.9_B1_C0.3_D-1.8 0.4

Hope you can help me to crack this! Thanks.

Asked By: Raganosis

||

Answers:

This should work:
Note that you can re-arrange the order of the for-loops, if you want the output in a specific order.

import pandas as pd

A = [0.9, 0.7, 1, 0.5]
B = [0, 1]
C = [0.3, 0.6, 0.9]
D = [-1.8, 0]

scenario, my_sum = [], []
for a in A:
    for b in B:
        for c in C:
            for d in D:
                scenario.append(f"A{a}_B{b}_C{c}_D{d}")
                my_sum.append(round(a+b+c+d, 2))
                
result = {"Scenario":scenario, "SUM":my_sum}                
df = pd.DataFrame.from_dict(result)
print(df.head(5))

Output:

Showing only the first 5 results:

df

By re-arranging the for-loops:

for d in D:
    for c in C:
        for b in B:
            for a in A:
                scenario.append(f"A{a}_B{b}_C{c}_D{d}")
                my_sum.append(round(a+b+c+d, 2))

You get the following result for the first 5 rows:

df2

Answered By: ScottC

You can actually do this quite simply with the help of Numpy!

1) Initialise your lists as np.array:

import numpy as np

A = np.array([0.9, 0.7, 1, 0.5])
B = np.array([0, 1])
C = np.array([0.3, 0.6, 0.9])
D = np.array([-1.8, 0])

2) Create all possible combinations with np.meshgrid():

combinations = np.array(
  np.meshgrid(A,B,C,D)).T.reshape(-1,4)
) 

3) Calculate sums across all combinations (rows):

sums = combinations.sum(axis=1).reshape(-1,1)

4) Build Pandas dataframe:

import pandas as pd

arrays = ['A','B','C','D']
combinations_df = pd.DataFrame(np.hstack([combinations,sums]), columns=arrays+['sum'])
combinations_df.head()

Output:

enter image description here

By using numpy arrays instead of lists you’ll be able to make the code more readable and robust since all operations will be vectorised.

Now to get a "scenario" column scenario we can use two simple apply’s:

combinations_df['scenario'] = combinations_df[arrays].apply(
  lambda row: [f'{c[1]}{c[0]}' for c in list(zip(row,combinations_df.columns[:-1]))],
  axis=1
).apply(lambda row: '_'.join(row))
combinations_df.head()

Output:

enter image description here

Answered By: JoshJohnson
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.