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?