Python for loop sum function trouble - python

Not sure what is wrong with this function but would appriciate any help I could get on it. New to python and a bit confused.
def summer(tables):
"""
MODIFIES the table to add a column summing the previous elements in the row.
Example: Suppose that a is
[['First', 'Second', 'Third'], [0.1, 0.3, 0.5], [0.6, 0.2, 0.7], [0.5, 1.1, 0.1]]
then place_sums(a) modifies the table a so that it is now
[['First', 'Second', 'Third', 'Sum'],
[0.1, 0.3, 0.5, 0.8], [0.6, 0.2, 0.7, 1.5], [0.5, 1.1, 0.1, 1.7]]
Parameter table: the nested list to process
"""
numrows = len(tables)
sums = []
for n in range(numrows):
sums = [sum(item) for item in tables]
return sums

This is what you are looking for. You don't need to create a new list. You just need to update your variable tables. Also putting a return statement inside your loop just make it run one iteration. You should look at how for loop work and what the return statement actually does.
def summer(tables):
"""
MODIFIES the table to add a column summing the previous elements in the row.
Example: Suppose that a is
[['First', 'Second', 'Third'], [0.1, 0.3, 0.5], [0.6, 0.2, 0.7], [0.5, 1.1, 0.1]]
then place_sums(a) modifies the table a so that it is now
[['First', 'Second', 'Third', 'Sum'],
[0.1, 0.3, 0.5, 0.8], [0.6, 0.2, 0.7, 1.5], [0.5, 1.1, 0.1, 1.7]]
Parameter table: the nested list to process
"""
tables[0].append('Sum')
for i in range(1, len(tables)):
tables[i].append(sum(tables[i]))

Related

Two different beaviour for .tolist() IndexError

I looping over on dataframe df1 to look for maximum order and then I want to take discount_first to assign to max order.
For one dataset everything goes OK
new_rate_1 = []
for value in df1["maximum_order"]:
new_val = df[df["New_Order_Lines"]==value]["discount_first"]
new_val = new_val.tolist()[0]
new_rate_1.append(new_val)
new_rate_1
[-1.3,
-1.3,
0.35,
0.8,
0.75,
0.55,
0.8,
0.85,
0.4,
0.75,
0.85,
0.85,
0.55,
0.45,
0.8,
0.65,
0.55,
0.85,
0.35,
0.85,
0.9,
0.5,
0.55,
-0.6,
0.85,
0.75,
0.35,
0.15,
0.55,
0.7,
0.8,
0.85,
0.75,
0.65,
0.75,
0.75,
0.35,
0.85,
0.4,
...
....
]
for other data set i start getting error ?
IndexError: list index out of range
If I dont index the list within the look I dont get error and output looks like this
[[0.8],
[0.8],
[0.55],
[0.55],
[0.55],
[0.85],
[0.55],
[0.85],
[0.85],
[0.65],
[0.65],
[0.75],
[0.7]
.....
any suggestion/advice how can I get rid of behaviour?
Thanks in advance
How about using this
# new_val = new_val.tolist()[0]
new_val = new_val.values.flatten()[0]
Why looping at all when you can do it without a loop?
you can use isin()+tolist() method:
new_rate_1 =df.loc[df["New_Order_Lines"].isin(df1["maximum_order"]),"discount_first"].tolist()

Python - matrix multiplication code problem

I have this exercise where I get to build a simple neural network with one input layer and one hidden layer... I made the code below to perform a simple matrix multiplication, but it's not doing it properly as when I do the multiplication by hand. What am I doing wrong in my code?
#toes %win #fans
ih_wgt = ([0.1, 0.2, -0.1], #hid[0]
[-0.1, 0.1, 0.9], #hid[1]
[0.1, 0.4, 0.1]) #hid[2]
#hid[0] hid[1] #hid[2]
ho_wgt = ([0.3, 1.1, -0.3], #hurt?
[0.1, 0.2, 0.0], #win?
[0.0, 1.3, 0.1]) #sad?
weights = [ih_wgt, ho_wgt]
def w_sum(a,b):
assert(len(a) == len(b))
output = 0
for i in range(len(a)):
output += (a[i] * b[i])
return output
def vect_mat_mul(vec, mat):
assert(len(vec) == len(mat))
output = [0, 0, 0]
for i in range(len(vec)):
output[i]= w_sum(vec, mat[i])
return output
def neural_network(input, weights):
hid = vect_mat_mul(input, weights[0])
pred = vect_mat_mul(hid, weights[1])
return pred
toes = [8.5, 9.5, 9.9, 9.0]
wlrec = [0.65, 0.8, 0.8, 0.9]
nfans = [1.2, 1.3, 0.5, 1.0]
input = [toes[0],wlrec[0],nfans[0]]
pred = neural_network(input, weights)
print(pred)
the output of my code is:
[0.258, 0, 0]
The way I attempted to solve it by hand is as follows:
I multiplied the input vector [8.5, 0.65, 1.2] with the input weight matrix
ih_wgt = ([0.1, 0.2, -0.1], #hid[0]
[-0.1, 0.1, 0.9], #hid[1]
[0.1, 0.4, 0.1]) #hid[2]
[0.86, 0.295, 1.23]
the output vector is then fed into the network as an input vector which is then multiplied by the hidden weight matrix
ho_wgt = ([0.3, 1.1, -0.3], #hurt?
[0.1, 0.2, 0.0], #win?
[0.0, 1.3, 0.1]) #sad?
the correct output prediction:
[0.2135, 0.145, 0.5065]
Your help would be much appreciated!
You're almost there! Only a simple indentation thing is the reason:
def vect_mat_mul(vec, mat):
assert(len(vec) == len(mat))
output = [0, 0, 0]
for i in range(len(vec)):
output[i]= w_sum(vec, mat[i])
return output # <-- This one was inside the for loop

How to L2 Normalize a list of lists in Python using Sklearn

s2 = [[0.2, 0.2, 0.2, 0.3021651247531982, 0.24462871026284194], [0.2, 0.4892574205256839, 0.2, 0.2, 0.383258146374831], [0.3193817886456925, 0.16666666666666666, 0.16666666666666666, 0.16666666666666666, 0.3193817886456925, 0.3193817886456925], [0.2, 0.2, 0.2, 0.3021651247531982, 0.24462871026284194]]
from sklearn.preprocessing import normalize
X = normalize(s2)
this is throwing error:
ValueError: setting an array element with a sequence.
How to L2 Normalize a list of lists in Python using Sklearn.
Since I don't have enough reputation to comment; hence posting it as an answer.
Let's quickly look at your datapoint.
I have converted the given datapoint into NumPy array. Since it doesn't have the same length, so it will look like.
>>> n2 = np.array([[0.2, 0.2, 0.2, 0.3021651247531982, 0.24462871026284194], [0.2, 0.4892574205256839, 0.2, 0.2, 0.383258146374831], [0.3193817886456925, 0.16666666666666666, 0.16666666666666666, 0.16666666666666666, 0.3193817886456925, 0.3193817886456925], [0.2, 0.2, 0.2, 0.3021651247531982, 0.24462871026284194]])
>>> n2
array([list([0.2, 0.2, 0.2, 0.3021651247531982, 0.24462871026284194]),
list([0.2, 0.4892574205256839, 0.2, 0.2, 0.383258146374831]),
list([0.3193817886456925, 0.16666666666666666, 0.16666666666666666, 0.16666666666666666, 0.3193817886456925, 0.3193817886456925]),
list([0.2, 0.2, 0.2, 0.3021651247531982, 0.24462871026284194])],
dtype=object)
And you can see here that converted values are not in Sequence of Values and to achieve this you need to keep the same length for the internal list ( looks like 0.16666666666666666 is copied multiple time in your array; if not then fix the length), it will look like
>>> n3 = np.array([[0.2, 0.2, 0.2, 0.3021651247531982, 0.24462871026284194], [0.2, 0.4892574205256839, 0.2, 0.2, 0.383258146374831], [0.3193817886456925, 0.16666666666666666, 0.16666666666666666, 0.16666666666666666, 0.319381788645692], [0.2, 0.2, 0.2, 0.3021651247531982, 0.24462871026284194]])
>>> n3
array([[0.2 , 0.2 , 0.2 , 0.30216512, 0.24462871],
[0.2 , 0.48925742, 0.2 , 0.2 , 0.38325815],
[0.31938179, 0.16666667, 0.16666667, 0.16666667, 0.31938179],
[0.2 , 0.2 , 0.2 , 0.30216512, 0.24462871]])
As you can see now n3 has become a sequence of values.
and if you use normalize function, it simply works
>>> X = normalize(n3)
>>> X
array([[0.38408524, 0.38408524, 0.38408524, 0.58028582, 0.46979139],
[0.28108867, 0.6876236 , 0.28108867, 0.28108867, 0.53864762],
[0.59581303, 0.31091996, 0.31091996, 0.31091996, 0.59581303],
[0.38408524, 0.38408524, 0.38408524, 0.58028582, 0.46979139]])
How to use NumPy array to avoid this issue, please have a look at this SO link ValueError: setting an array element with a sequence
Important: I removed one element from the 3rd list in order for all lists to have the same length.
I did that cause I really believe that it's a copy-paste error. If not, comment below and I will modify my answer.
import numpy as np
s2 = [[0.2, 0.2, 0.2, 0.3021651247531982, 0.24462871026284194], [0.2, 0.4892574205256839, 0.2, 0.2, 0.383258146374831], [0.3193817886456925, 0.16666666666666666, 0.16666666666666666, 0.3193817886456925, 0.3193817886456925], [0.2, 0.2, 0.2, 0.3021651247531982, 0.24462871026284194]]
X = normalize(np.array(s2))

Is there any way to insert values in a specific list dynamically? [duplicate]

This question already has answers here:
How can I select a variable by (string) name?
(5 answers)
Closed 8 months ago.
I'm trying to insert values in a list using the name of a variable dynamically but I am not being able to do it.
lst_prio = [90, 100]
p_90 = [0.11, 0.2, 0.15, 0.6, 0.9]
p_100 = [0.1, 0.3, 0.5, 0.7, 0.8]
lst_crv = [4,3,2,5,6]
crv = [1,2,3,4,5]
lst_percs = []
for x in range(len(lst_prio)):
lst_percs.append("lst_p_"+str(lst_prio[x]))
dic =dict(zip(lst_prio,lst_percs))
for w in range(len(lst_prio)):
dic[lst_prio[w]] =[]
for i in range(len(crv)):
for j in range(len(lst_crv)):
if crv[i] == lst_crv[j]:
#Below I would like to insert the list as the append value (p_90 to p_100) dynamically based on the dictionary I've created
dic[lst_prio[w]].append(p_90[i])
The result I am getting (because I am not being able to iterate):
lst_p_90 = [0.2, 0.15, 0.6, 0.9]
lst_p_90 = [0.2, 0.15, 0.6, 0.9]
The result I would like:
lst_p_90 = [0.2, 0.15, 0.6, 0.9]
lst_p_100 = [0.3, 0.5, 0.7, 0.8]
I think I get what you meant. You want to dynamically evaluate the variable based on the name. Try this for the last lines.
if crv[i] == lst_crv[j]:
number = lst_prio[w]
p_n = locals()['p_' + str(number)]
dic[number].append(p_n[i])
Related: How to get the value of a variable given its name in a string?

Sample from a 2d probability numpy array?

Say that I have an 2d array ar like this:
0.9, 0.1, 0.3
0.4, 0.5, 0.1
0.5, 0.8, 0.5
And I want to sample from [1, 0] according to this probability array.
rdchoice = lambda x: numpy.random.choice([1, 0], p=[x, 1-x])
I have tried two methods:
1) reshape it into a 1d array first and use numpy.random.choice and then reshape it back to 2d:
np.array(list(map(rdchoice, ar.reshape((-1,))))).reshape(ar.shape)
2) use the vectorize function.
func = numpy.vectorize(rdchoice)
func(ar)
But these two ways are all too slow, and I learned that the nature of the vectorize is a for-loop and in my experiments, I found that map is no faster than vectorize.
I thought this can be done faster. If the 2d array is large it would be unbearably slow.
You should be able to do this like so:
>>> p = np.array([[0.9, 0.1, 0.3], [0.4, 0.5, 0.1], [0.5, 0.8, 0.5]])
>>> (np.random.rand(*p.shape) < p).astype(int)
Actually I can use the np.random.binomial:
import numpy as np
p = [[0.9, 0.1, 0.3],
[0.4, 0.5, 0.1],
[0.5, 0.8, 0.5]]
np.random.binomial(1, p)

Categories