Passing float to a nested for loop and storing output

≯℡__Kan透↙ 提交于 2021-01-28 11:32:03

问题


I have a strong background in Matlab, and I am trying to switch to python. I am trying to write a nested for loop with numpy array and storing output values.

My code reads like:

import numpy as np
import math

# T parameter
kk = np.arange(0, 20, 0.1)
print(len(kk))

# V parameter
pp = np.arange(1, 5, 1)
print(len(pp))

a = len(kk)
b = len(pp)

P = np.zeros((a,b))


for T in kk:
    print(T)
    for V in pp:
        print(V)
        P = math.exp(-T*V/10)

print(P)

Explanation/Question

  1. kk, pp are the vectors. In for loop(s) correct values of T and V parameters are being called. However, values of P are not being stored.

  2. I tried the following change P[T][V] = math.exp(-T*V/10), I get the following error: IndexError: only integers, slices (:), ellipsis (...), numpy.newaxis (None) and integer or boolean arrays are valid indices

Any help will be appreciated. Thank you in advance.


回答1:


In this code you define P as a 2d array. But the loop you assign the scalar result of the math.exp expression to that variable. That replaces the original P value, and also replaces the value calculated in the previous loop. This kind of loop doesn't work in MATLAB does it? Don't you have to assign the scalar value to some 'slot' in P?

P = np.zeros((a,b))
for T in kk:
    print(T)
    for V in pp:
        print(V)
        P = math.exp(-T*V/10)

A better way:

In [301]: kk = np.arange(0,20,0.1)                                                            
In [302]: kk.shape                                                                            
Out[302]: (200,)
In [303]: pp = np.arange(1, 5,1)                                                              
In [304]: pp.shape                                                                            
Out[304]: (4,)

In numpy we prefer to use fast whole-array methods. Here I use broadcasting to perform an outer like calculation of kk with pp.

In [305]: P = np.exp(-kk[:,None]*pp/10)                                                       
In [306]: P.shape                                                                             
Out[306]: (200, 4)

(I believe MATLAB added broadcasting in recent years; numpy has had it from the beginning.)

Comparing this with the iterative version:

In [309]: P1 = np.zeros((200,4)) 
     ...: for i in range(0,len(kk)): 
     ...:     for j in range(0,len(pp)): 
     ...:         T = kk[i] 
     ...:         V = pp[j] 
     ...:         P1[i,j] = math.exp(-T*V/10) 
     ...:                                                                                     
In [310]: P1.shape                                                                            
Out[310]: (200, 4)
In [311]: np.allclose(P,P1)                                                                   
Out[311]: True

A cleaner way of writing indexed iteration in Python is with enumerate:

In [312]: P1 = np.zeros((200,4)) 
     ...: for i,T in enumerate(kk): 
     ...:     for j,V in enumerate(pp): 
     ...:         P1[i,j] = math.exp(-T*V/10) 



回答2:


Based on the line where you mentioned trying P[T][V] = math.exp(-T*V/10), you might also be interested in this option:

import numpy as np
import math

# T parameter
kk = np.arange(0, 20, 0.1)
print(len(kk))

# V parameter
pp = np.arange(1, 5, 1)
print(len(pp))

a = len(kk)
b = len(pp)

P = np.zeros((a,b))

for i in range(0,len(kk)):
    for j in range(0,len(pp)):
        T = kk[i]
        V = pp[j]
        P[i][j] = math.exp(-T*V/10)

        # you can also simply do this:
        #P[i][j] = math.exp(-kk[i]*pp[j]/10)

Although it's straightforward, it's not particularly clean. Since you mentioned that you're switching to python, I'd take a look at hpaulj's answer for a more thorough explanation and as well as a nice alternative to iterating through arrays.




回答3:


You can make a dictionary if you want to see the keys and values per your comment. This might make more sense actually. I would recommend against a plethora of dynamically created variables, as with a dictionary, you can call the entire dictionary OR specific values, which you could store as variables later anyway. Obviously, it depends on the scope of your project and what solution makes sense, but you could also turn the dictionary into a pandas dataframe with pd.DataFrame() for analysis, so it gives you flexibility. You said you are new to python, so you might want to check out pandas if you haven't heard of it, but you probably have as it is one of or the most popular library.

import numpy as np
import math

P_dict = {}

# T parameter
kk = np.arange(0, 20, 0.1)
# print(len(kk))

# V parameter
pp = np.arange(1, 5, 1)
# print(len(pp))

a = len(kk)
b = len(pp)

P = np.zeros((a,b))


for T in kk:
#     print(T)
    for V in pp:
#         print(V)
        P = math.exp(-T*V/10)
        key = f'{T},{V}'
        value = P
        P_dict[key] = value

print(P_dict)

This is how you would call a value in the dict based on the key.

P_dict['19.900000000000002,3']

You can also edit this line of code to whatever format you want: key = f'{T},{V}' and call the key acording to the format as I have done in my example.

Output: 0.002554241418992996

Either way, a list or a dict prints some interesting python abstract art!



来源:https://stackoverflow.com/questions/62290107/passing-float-to-a-nested-for-loop-and-storing-output

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!