Can anybody explain me this simple Python code? - python

I have simple function which returns matrix of zeros and ones. I can't understand how line: out[range(n), vec] = 1 works. Vector v can have values from 0 to 9.
import numpy as np
def one_hot_encode(vec, vals=10):
n = len(vec)
out = np.zeros((n, vals))
out[range(n), vec] = 1
return out
v = [1,2,3,1,3,5,7,8,9,1,2,3,4,5,6,7,8,9,0,1,2,3,1,3,5,7,8,9,1,2,3]
one_hot_encode(v, 10)

the line line: out[range(n), vec] = 1 is placing the one corresponding to vec values i.e. if vec has first value 1 then in out matrix first row and second column(value +1) will be assigned as 1. if 4rt value is 1 then 4rt row and second column will be assigned 1.

Related

Matlab operation to Python

I'm having trouble translating this operation from MatLab to Python:
xup(1:ncomp,1)=aa(1+k:ncomp+k).';
"aa" is a vector of 1x1000 elements.
"ncomp" = 128
"k" is a variable for a loop cycle.
The problem is ... I don't understand how does it work.
I'm posting the whole section of the algorithm:
while(testnorm>0.0001 && epoca<maxit)
k=0;
xup=[];
while(k<=npatt)
xup(1:ncomp,1)=aa(1+k:ncomp+k).';
if (funz==1)
gy=tanh(alpha.*xup.'*w);
else
gy=sign(xup.'*w).*log(1+abs(alpha*xup.'*w));
end
w=w+lr.*(xup*gy-w*triu((xup.'*w).'*gy));
w = w / norm(w);
k=k+1;
end
[...]
end
can you help ?
Essentially what this
xup(1:ncomp,1)=aa(1+k:ncomp+k).';
line is doing; It is fetching data from vector aa, starting from index 1+k to ncomp+k index(i.e ncomp total elements) and transposing(from single row to ncomp rows) those elements. Now this transposed data is being inserted into the xup as ncomp rows, where each row has a single element. The similar python code would be
import numpy as np
aa = np.array([i for i in range(1000)])
ncomp = 128
k = 0
xup = [[0] for i in range(ncomp)]
while(k<10):
data = (np.transpose(aa[k:ncomp+k]))
for i in range(ncomp):
xup[i] = data[i]
k += 1
print(xup[:128])

How can I solve the error: 'int' object does not support item assignment

def foo(x, a, b, i, j):
k = j
ct = 0
while k > i-1:
if x[k] <= b and not (x[k] <= a):
ct = ct + 1
k = k - 1
return ct
x = (11,10,10,5,10,15,20,10,7,11)
y = [10000000000000000000]
m = 0
while m < 10000000000000000000:
y[m] = m
m = m +1
print(foo(x,8,18,3,6))
print(foo(x,10,20,0,9))
print(foo(x,8,18,6,3))
print(foo(x,20,10,0,9))
print(foo(x,6,7,8,8))
# Please be careful with typos for the output of the following lines!
print(foo(y,
111112222233333, # five 1's, then five 2's, then five 3's
999998888877777, # five 9's, then five 8's, then five 7's
222223333344444, # five 2's, then five 3's, then five 4's
905003340009900023))
---------------------------------------------------------------------------
TypeError Traceback (most recent call
last) <ipython-input-17-d3d2cd54b367> in <module>()
14
15 while m < 10000000000000000000:
---> 16 y[m] = m
17 m = m +1
18
TypeError: 'int' object does not support item assignment
In python, when you write y = [10000000000000000000], you are creating an array with a single item in index 0, which has 10000000000000000000 as value. And, maybe, your idea was to define an array with 10000000000000000000 items in it?
If that is the case, what you want to do is: y = [] to initialize an array/list. In python, you don't specify the size of arrays, they are dynamic. But you need to use methods to remove or to add new items. You can change an existing item by using index, though.
If you fix that, you will still get an Exception where the arrow is pointing at, in the Traceback, because you are trying to modify the value of an index that does not exist. Since you instantiated the array as y = [10000000000000000000], you only have a value in index 0. It works the first time, because the loop starts at index 0, when it sets y[0] = 0. But when m get incremented and it tries y[1] = 1, the array does not have that index, which will raise IndexError: list assignment index out of range.
If you want to initialize an array with 10000000000000000000 items in it, you could do:
y = []
for i in range(10000000000000000000):
y.append(i)
or
y = [i for i in range(10000000000000000000)]
More about range() function: https://docs.python.org/3/library/functions.html#func-range
More about array/list: https://docs.python.org/3/tutorial/datastructures.html

Creating multiple matrices with nested loop using numpy

import numpy as np
import random
x = np.linspace(-3.0,3.0,25)
b = 3; a = -3; n = 24
N = np.matrix(np.zeros(shape=(4,24)));
G = [] #want to save the 2 4by 24 matrices in G
s = []; g = []
Y = []
random.seed(4)
for j in range(0,2):
Y.append(np.random.randint(-6.0,6.0,size=(4,1)))
h = (b-a)/float(n)
s.append(0.5*h*((1+(np.cos((np.pi*(a-Y[j]))/3.0)))))
g.append(0.5*h*(1+(np.cos((np.pi*(b-Y[j]))/3.0))))
for k in range(0,Y[j].shape[0]):
for l in range(1, x.shape[0]-1):
N[k,l] = h*(1 + (np.cos((np.pi*(x[l]-Y[j][k]))/3.0)))
N[k,0] = s[j][k]
N = np.concatenate((N,g[j]),axis=1)
print(N)
Please, I need help. When I run this code, it produces just a single 4by25 matrix but it is suppose to be 2 4by25 matrix. I dont know why. My goal is to have the 2 4by25 matrices stored to variable G so that when i call G[0], it produces the first 4by25 and G[1] produces the second 4by25. Here Y outputs 2 4by1 coulmn vectors.
How is your code supposed to append 2 matrices to G? You are totally missing that part.
I don't really get what values you're looking for, so I can't tell you if values are added correctly, anyway you should add this line:
G.append(N)
(I'm just assuming you are appending N because it is the only 2x24 matrix)
Before the end of the first cylce, result should be something like:
for j in range(0,2):
Y.append(np.random.randint(-6.0,6.0,size=(4,1)))
h = (b-a)/float(n)
s.append(0.5*h*((1+(np.cos((np.pi*(a-Y[j]))/3.0)))))
g.append(0.5*h*(1+(np.cos((np.pi*(b-Y[j]))/3.0))))
for k in range(0,Y[j].shape[0]):
for l in range(1, x.shape[0]-1):
N[k,l] = h*(1 + (np.cos((np.pi*(x[l]-Y[j][k]))/3.0)))
N[k,0] = s[j][k]
N = np.concatenate((N,g[j]),axis=1)
G.append(N)

index 4 is out of bounds for axis 1 with size 4 Code with Double Sum

Hi I have the following function which produces an out of bounds error:
import numpy as np
import pylab as plt
import scipy
import math
import sympy as sy
T = sy.Symbol('T')
rho = sy.Symbol('rho')
g_T = [1,T,T**2,T*sy.log(T),T**2*sy.log(T)]
g_rho = [1,rho,rho**2,rho*sy.log(rho),rho**2*sy.log(rho)]
g_T_np = np.asarray(g_T)
g_rho_np = np.asarray(g_rho)
c = np.loadtxt("c_test.txt")
def F(T,rho):
ret = 0
for n in xrange(1,5):
for m in xrange(1,6):
inner= c[n,m]*g_T_np*g_rho_np
ret += inner
return ret
print F(T,rho)
where the .txt file is like this:
-0.529586 -0.000208559 -3.36563E-09 2.29441E-05
2.22722E-06 -0.00014526 -2.48888E-09 1.89488E-05
-6.26662E-05 0.000421028 6.17407E-09 -5.14488E-05
0.09977346 -0.000622051 -8.56485E-09 7.49956E-05
-0.01437627 -9.86754E-05 -1.59808E-09 1.22574E-05
The full error displayed is:
Traceback (most recent call last):File "EOS_test.py", line 38, in <module> print F(T,rho) File "EOS_test.py", line 31, in F inner=c[n,m]*g_T_np*g_rho_np IndexError: index 4 is out of bounds for axis 1 with size 4
How can I solve this error?
Numpy uses 0-based indexing. From the looks of it you are indexing the array from 1 (2nd position) to 4 (5th position), which is of course out of bounds for the array you are working with. The same is true for the second axis.
Secondly, you've mixed up your axes:
The first axis (0) is the index of the selected row (0 to 5)
the second axis indexes the column, i.e. the value inside a row (indexed 0 to 4)
This should work:
def F(T,rho):
ret = 0
for n in range(5):
for m in range(4):
inner= c[n,m]*g_T_np*g_rho_np
ret += inner
return ret
Your problem is in setting your xranges.
Python lists (and np arrays) are 0 indexed, so you don't want the indices [1,2,3,4,5] and [1,2,3,4,5,6], but instead want [0,1,2,3,4] and [0,1,2,3,4,5] [0,1,2,3] and [0,1,2,3,4].
Setting up your for loops like this would solve your problem:
for n in xrange(0,4):
for m in xrange(0,5):
Or, you can take advantage of xrange's default starting point, and simply list one parameter:
for n in xrange(4):
for m in xrange(5):
Also, for a "more pythonic" solution, instead of having nested for loops, look up how to iterate over an ndarray. The docs give this example:
it = np.nditer(c, flags=['f_index'])
while not it.finished:
inner= c[it[0]]*g_T_np*g_rho_np
ret += inner
it.iternext()
This avoids the whole issue of needing to know the size of the array you're importing, and is therefore much more robust.
Edit: As pdowling mentioned in his answer, the range numbers should be 4 and 5. I had left 5 and 6 in my aswer, and have now changed that.

Different results for linalg.norm in numpy

I am trying to create a feature matrix based on certain features and then finding distance b/w the items.
For testing purpose I am using only 2 points right now.
data : list of items I have
specs : feature dict of the items (I am using their values of keys as features of item)
features : list of features
This is my code by using numpy zero matrix :
import numpy as np
matrix = np.zeros((len(data),len(features)),dtype=bool)
for dataindex,item in enumerate(data):
if dataindex > 5:
break
specs = item['specs']
values = [value.lower() for value in specs.values()]
for idx,feature in enumerate(features):
if(feature in values):
matrix[dataindex,idx] = 1
print dataindex,idx
v1 = matrix[0]
v2 = matrix[1]
# print v1.shape
diff = v2 - v1
dist = np.linalg.norm(diff)
print dist
The value for dist I am getting is 1.0
This is my code by using python lists :
matrix = []
for dataindex,item in enumerate(data):
if dataindex > 5:
f = open("Matrix.txt",'w')
f.write(str(matrix))
f.close()
break
print "Item" + str(dataindex)
row = []
specs = item['specs']
values = [value.lower() for value in specs.values()]
for idx,feature in enumerate(features):
if(feature in values):
print dataindex,idx
row.append(1)
else:
row.append(0)
matrix.append(row)
v1 = np.array(matrix[0]);
v2 = np.array(matrix[1]);
diff = v2 - v1
print diff
dist = np.linalg.norm(diff)
print dist
The value of dist in this case is 4.35889894354
I have checked many time that the value 1 is being set at the same position in both cases but the answer is different.
May be I am not using numpy properly or there is an issue with the logic.
I am using numpy zero based matrix because of its memory efficiency.
What is the issue?
It's a type issue :
In [9]: norm(ones(3).astype(bool))
Out[9]: 1.0
In [10]: norm(ones(3).astype(float))
Out[10]: 1.7320508075688772
You must decide what it the good norm for your problem and eventually cast your data with astype.
norm(M) is sqrt(dot(M.ravel(),M.ravel())) , so for a boolean matrix, norm(M) is 0. if M is the False matrix,
1. otherwise. use the ord parameter of norm to tune the function.

Categories

Resources