pythoniterationnested-loopsstoring-data

Python: How to use a nested for-loop to properly store values in an array (three loops, three dimensional array)?


Using Python 3.8.1. and Numpy 1.19.4

Hey gang, I'm a bit new to Python so please bear with me.

I am performing a calculation (a model/simulation) with three variables and I need to step through a respective range for each variable. The calculation and cycling through each range seems to be working correctly when I print each iteration from within the final nested loop (k). However, when checking for the stored values in the v_ram array after the loop, the values are not correct, and seem to reflect the last iteration of the third for-loop (k=0:17), with the rest of the array populated by zeros.

phi = np.linspace(0, (14/90)*pi, 8, True)       # 0 to 28 deg in 4 deg steps = 7 + 1 values
theta_step = 20                                 # theta step size = 20 deg
theta = np.linspace(0, (2*pi)-(theta_step*(pi/180)), 18, True)       # 0 to (360-step) deg in 20 deg steps = 17 + 1


# number of simulations/length of resulting v_ram array
n_sim = len(v_sim_mag)*len(phi)*len(theta)
# Initialize the v_ram variable
v_ram = np.zeros((n_sim, 3))

for i in range(len(v_sim_mag)):
    for j in range(len(phi)):
        for k in range(len(theta)):
            v_ram[k] =  [v_sim_mag[i] * math.sin(phi[j]) * math.cos(theta[k]),
                        v_sim_mag[i] * math.sin(phi[j]) * math.sin(theta[k]),
                        v_sim_mag[i] * math.cos(phi[j])]
            print("v_ram:", v_ram[k], "v_sim_mag:", v_sim_mag[i], "phi:", phi[j], "theta:", theta[k], "i, j, k:", i, j, k)


print(v_ram)

Output: Includes last three lines of iterated for-loop print as an example, followed by a print of the array v_ram:

v_ram: [ 4.1858252 -7.25006191 15.74478445]
v_sim_mag: 17.83207132052525 phi: 0.4886921905584123 theta: 5.23598775598299 i, j, k: 14 7 15
v_ram: [ 6.41305626 -5.38119314 15.74478445]
v_sim_mag: 17.83207132052525 phi: 0.4886921905584123 theta: 5.585053606381855 i, j, k: 14 7 16
v_ram: [ 7.8667781 -2.86327307 15.74478445]
v_sim_mag: 17.83207132052525 phi: 0.4886921905584123 theta: 5.934119456780721 i, j, k: 14 7 17

v_ram_array:
[[ 8.37165039 0. 15.74478445]
[ 7.8667781 2.86327307 15.74478445]
[ 6.41305626 5.38119314 15.74478445]
...
[ 0. 0. 0. ]
[ 0. 0. 0. ]
[ 0. 0. 0. ]]

Any help is greatly appreciated, and feel free to roast my code and offer other suggestions.

UPDATE

A friend suggested another solution which worked nicely:

# number of simulations/length of resulting v_ram array
n_sim = len(v_sim_mag)*len(phi)*len(theta)
# Initialize the v_ram variable
v_ram = np.zeros((len(v_sim_mag), len(phi), len(theta), 6))

for i in range(len(v_sim_mag)):
    for j in range(len(phi)):
        for k in range(len(theta)):
            v_ram[i,j,k] =  [v_sim_mag[i] * math.sin(phi[j]) * math.cos(theta[k]),
                        v_sim_mag[i] * math.sin(phi[j]) * math.sin(theta[k]),
                        v_sim_mag[i] * math.cos(phi[j]),
                        i, j, k]

Solution

  • v_ram.shape is (2160, 3), but you only ever assign to v_ram[k] which is at most 17. Perhaps you meant something more like:

    v_ram = np.zeros((n_sim, 3))
    v_ram_index = 0
    

    with the loop core like:

    v_ram[v_ram_index] =  [
        v_sim_mag[i] * math.sin(phi[j]) * math.cos(theta[k]),
        v_sim_mag[i] * math.sin(phi[j]) * math.sin(theta[k]),
        v_sim_mag[i] * math.cos(phi[j])]
    v_ram_index += 1