Home > Blockchain >  How to run all integers in an array through an equation and append to a new array with a for loop?
How to run all integers in an array through an equation and append to a new array with a for loop?

Time:04-04

Maybe there is a better way to do this, but I want to take an array of values from -80 to 0, and sub them into an equation where the missing variable, T, takes each of those values from the first array and then runs the equation with that and makes a new array. See code below:

T = np.arange(-80, 2, 2)
empty = []
esw = 6.11*np.exp(53.49*(6808/T)-5.09*np.log(T))

i = 0
for i in range(T):
    6.11*np.exp(53.49*(6808/T[i])-5.09*np.log(T[i]))
    x = np.append(empty)
    i = I 1

I know this is probably some miserable code, any help would be appreciated, thanks!

CodePudding user response:

First of all, I have taken the liberty of doing a bit of math to hypothetically make your esw possible with negative numbers when the exponent is an integer, though it still won't work when T = 0 because of the division in the exponent. Note that because your exponent is 5.09, the code still doesn't work with negative T values. We now have:

esw = 6.11 * np.exp(53.49*6808/t) / t**(5.09)

where t is some value in your T array of values.

If you're trying to get esw for each value in T, you can structure your code in 2 main ways. The non-vectorised way, which is to loop through every value of T with a for loop and is a safer method, looks like this:

# If the calculation cannot be done, None will be returned.
def func(t):
  try:
    esw = 6.11 * np.exp(53.49*6808/t) / t**(5.09)
  except:
    esw = None
  return esw

# new_arr is the same size as T. Each value in new_arr is the corresponding value of T
# put through the esw calculation.
new_arr = np.apply_along_axis(func, 0, T)

Note that for the values of T you chose (between -80 and 2), all esw values are either None or infinity.

If your calculations were possible (i.e. all your T values were > 0), you could vectorise your code (a good idea because it's easier to read and also faster), like so:

new_arr = 6.11 * np.exp(53.49*6808/T) / T**(5.09)

This method is less safe because as soon as an error is encountered, the program crashes instead of returning None for that value in T. With your T values, this code crashes.

CodePudding user response:

There are some basic Python errors, suggesting that you haven't read much of a Python intro, and haven't learn to test your code (step by step).

You create an array, e.g.:

In [123]: T = np.arange(-3,2)
In [124]: T
Out[124]: array([-3, -2, -1,  0,  1])

and try to iterate:

In [125]: for i in range(T):print(i)
Traceback (most recent call last):
  Input In [125] in <cell line: 1>
    for i in range(T):print(i)
TypeError: only integer scalar arrays can be converted to a scalar index

In [126]: range(T)
Traceback (most recent call last):
  Input In [126] in <cell line: 1>
    range(T)
TypeError: only integer scalar arrays can be converted to a scalar index

range takes a number, not an array. It's a basic Python function that you should know, and use correctly. You can get a number by taking the length of the array or list, len(T):

In [127]: range(len(T))
Out[127]: range(0, 5)
In [128]: list(_)
Out[128]: [0, 1, 2, 3, 4]

You do a i=0 before, and some sort of assignment to i in the loop, which means you don't understand (or care) about how the loop assigns i.

In [129]: for i in range(4):
     ...:     print(i)
     ...:     i = i 10
     ...: 
0
1
2
3

Adding 10 to i did nothing; the for assigns the next value from the range. Again this is basic Python iteration.

As for the empty and np.append:

In [130]: empty=[]
In [131]: np.append(empty)
Traceback (most recent call last):
  Input In [131] in <cell line: 1>
    np.append(empty)
  File <__array_function__ internals>:179 in append
TypeError: _append_dispatcher() missing 1 required positional argument: 'values'

The correct way to use list append is:

In [132]: alist = []
     ...: for i in T:
     ...:     alist.append(i*2)
     ...: 
In [133]: alist
Out[133]: [-6, -4, -2, 0, 2]

List append works in-place, and it is reasonably fast. np.append is a poorly name function that should not exist. It is not a list append clone.

Since T is an array, we don't need to iterate.

In [134]: T*2
Out[134]: array([-6, -4, -2,  0,  2])

An alternative to the list append loop is a list comprehension. It's a bit faster than the iteration, though not as fast as the direct array calculation.

In [135]: [i*2 for i in T]
Out[135]: [-6, -4, -2, 0, 2]

Finally, that line

6.11*np.exp(53.49*(6808/T[i])-5.09*np.log(T[i]))

in the loop does nothing; not even assign a value to a variable (as you did outside the loop with esw=.... Did you really think it did something? Or was this just a careless mistake?

  • Related