Issue
I'm trying to calculate the sum of squared errors and i'm using a nested loop.
I'm new to Python and i apologize, but i encounter the error:
File "...", line 13, in <module>
for y in values_subtraction_mean:
TypeError: 'numpy.float64' object is not iterable
The problem is with the second loop, when i have to calculate result
in:
for y in values_subtraction_mean: result = sum(math.sqrt(y))
In the second loop, it should show all values of values_subtraction_mean
, so it should show 2.2, -0.8, 0.2, 1.2, -2.8
. Next for each value above, a sqrt should be calculated and get 4.84, 0.64, 0.04, 1.44, 7.84
. In the end you have to sum all these numbers and get 14.8
What am I doing wrong?
from numpy import mean
import math
values = [5, 2, 3, 4, 0]
mean = mean(values)
for x in values:
values_subtraction_mean = x - mean
print(values_subtraction_mean)
#2.2, -0.8, 0.2, 1.2, -2.8
for y in values_subtraction_mean:
result = sum(math.sqrt(y))
print(result)
#sqrt: 4.84, 0.64, 0.04, 1.44, 7.84
#sum and result: 14.8
I tried using this, but it doesn't solve the problem:
import numpy as np
values = np.array([5, 2, 3, 4, 0])
I tried not using numpy, calculating the mean with: sum(values) / len(values)
, but it doesn't work either and i get error:
TypeError: 'float' object is not iterable
Solution
You seem to have problems understanding basic python iteration, let alone numpy. So lets look at your code in detail
In [1]: import numpy as np
...: import math
...:
...: values = [5, 2, 3, 4, 0]
...:
...: mean = np.mean(values)
...:
...: for x in values:
...: values_subtraction_mean = x - mean
...: print(values_subtraction_mean)
...:
...: for y in values_subtraction_mean:
...: result = sum(math.sqrt(y))
...: print(result)
...:
2.2
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[1], line 12
9 values_subtraction_mean = x - mean
10 print(values_subtraction_mean)
---> 12 for y in values_subtraction_mean:
13 result = sum(math.sqrt(y))
14 print(result)
TypeError: 'numpy.float64' object is not iterable
So the error is in that for y in values...:
line. The for x in values:
works because values
is a list. Inside that loop it calculates the mean
(with a numpy mean function):
In [2]: mean
Out[2]: 2.8
In [3]: type(mean)
Out[3]: numpy.float64
In [4]: values_subtraction_mean
Out[4]: 2.2
In [5]: x
Out[5]: 5
You substracted the mean from one element of the list, and then tried to iterate on that value. The y
loop is nested inside the x
loop. Plus the x
loop isn't accumulating any of those x-mean
values.
The following line will have problems as well
sum(math.sqrt(y))
math
functions only work on scalars, not lists or arrays. But python sum
requires an iterable (e.g. a list). So I don't quite get what you intend here.
Corrected iteration - sort of
The standard way to iterate on a list is to append the results to a list. Changing your code:
In [9]: values = [5, 2, 3, 4, 0]
...:
...: mean = np.mean(values)
...: values_sublist = []
...: for x in values:
...: values_sublist.append(x - mean)
...: print(values_sublist)
...: result = []
...: for y in values_sublist:
...: result.append(math.sqrt(y))
...: print(result)
[2.2, -0.7999999999999998, 0.20000000000000018, 1.2000000000000002, -2.8]
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[9], line 10
8 result = []
9 for y in values_sublist:
---> 10 result.append(math.sqrt(y))
11 print(result)
ValueError: math domain error
values_sublist
is all the list values minus their mean. So the y
loop works. But it runs into another problem - it can't take the sqrt of a negative number!
numpy version
In [10]: values
Out[10]: [5, 2, 3, 4, 0]
In [11]: mean=np.mean(values)
In [12]: mean
Out[12]: 2.8
In [13]: np.array(values)-mean
Out[13]: array([ 2.2, -0.8, 0.2, 1.2, -2.8])
In [14]: np.sqrt(np.array(values)-mean)
C:\Users\14256\AppData\Local\Temp\ipykernel_8020\509743582.py:1: RuntimeWarning: invalid value encountered in sqrt
np.sqrt(np.array(values)-mean)
Out[14]: array([1.4832397 , nan, 0.4472136 , 1.09544512, nan])
It's possible to do this without the python loops, if values
is a numpy array. Now the negative values produce a nan
value, and a warning. There's no point to doing the sum
on the array with nan
.
complex values
We can deal with the sqrt
issue by making values a complex
dtype array:
In [15]: values_c = np.array(values,complex); values_c
Out[15]: array([5.+0.j, 2.+0.j, 3.+0.j, 4.+0.j, 0.+0.j])
In [16]: np.mean(values_c)
Out[16]: (2.8000000000000003+0j)
In [17]: values_c - np.mean(values_c)
Out[17]: array([ 2.2+0.j, -0.8+0.j, 0.2+0.j, 1.2+0.j, -2.8+0.j])
In [18]: np.sqrt(values_c - np.mean(values_c))
Out[18]:
array([1.4832397 +0.j , 0. +0.89442719j,
0.4472136 +0.j , 1.09544512+0.j ,
0. +1.67332005j])
In [19]: np.sum(_)
Out[19]: (3.0258984079294224+2.5677472440680673j)
Though I'm not sure that's what you need.
square instead of sqrt
But wait, the "sqrt" values that you want are actually the square values, not square root.
In [20]: values = [5, 2, 3, 4, 0]
...: mean = np.mean(values)
...: values_sublist = []
...: for x in values:
...: values_sublist.append(x - mean)
...: print(values_sublist)
...: result = []
...: for y in values_sublist:
...: result.append(y**2)
...: print(result); print(sum(result))
[2.2, -0.7999999999999998, 0.20000000000000018, 1.2000000000000002, -2.8]
[4.840000000000001, 0.6399999999999997, 0.04000000000000007, 1.4400000000000004, 7.839999999999999]
14.8
Now your two loops work just fine.
And written as one numpy expression:
In [21]: np.sum((np.array(values)-np.mean(values))**2)
Out[21]: 14.8
We could also use a list comprehension in place of the for loops - though we still have to use np.mean
, or a loop equivalent. So it isn't a pure list calculation:
In [22]: values
Out[22]: [5, 2, 3, 4, 0]
In [23]: mean
Out[23]: 2.8
In [24]: sum((x-mean)**2 for x in values)
Out[24]: 14.8
That sqrt and complex code may be a distraction, but I'll leave that in because I think it may be instructive. It's part of debugging your code.
Answered By - hpaulj
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.