How to change a specific numpy array inside a arrays of arrays? - python

I'm writing a program but I'm finding dificulties to update a numpy array.
The code:
print("p: " + str(pontoP))
print("d: " + str(deslocamento))
novoP = np.array([0,0,0])
novoP = pontoP + deslocamento
pontos[i] = novoP
print("p+d: " + str(pontos[i]))
The output:
p: [0. 1. 0.33333333]
d: [ 0. -1. 0.]
p+d: [0 0 0]
pontoP, novoP and deslocamento are 1D numpy arrays (length 3), and pontos is a 2D numpy array (size 8 x 3).
The line novoP = pontoP + deslocamento is working: the arrays are being summed element-wise. However, pontos[i] = novoP is failing to update the 2D array pontos.
What can I do? The desired result is to replace the ith array of pontos with the contents of novoP.

Thanks to #hpauli , I found that the issue was the type of numpy array. It was an int and when I tried to put a float in it, the float was being rounded.

Related

Python loop to populate a matrix

I'm trying to populate an array in python more efficiently. I have a 5x3 matrix A that I am transforming into a 3x3 matrix (Z) by calculating z11, z12, ..., z33 independently. The code below works, but it's clunky and I'm hoping to automate this into a loop so that it will take an A matrix of any size (n x m) and transform it into a Z matrix of size (m x m). If someone could help me out I would greatly appreciate it!
import numpy as np
A = np.array([[1,0,0],
[0,1,0],
[0,1,1],
[0,0,-1],
[0,0,1]])
A1=A[:,0]
A2=A[:,1]
A3=A[:,2]
C = np.array([-2,-2, -9,-6,-4])
X = np.array([-4,-4,-8])
z11 = (sum(A1*A1))*(C[0]/X[0])
z12 = (sum(A1*A2))*(C[0]/X[1])
z13 = (sum(A1*A3))*(C[0]/X[2])
z21 = (sum(A2*A1))*(C[1]/X[0])
z22 = (sum(A2*A2))*(C[1]/X[1])
z23 = (sum(A2*A3))*(C[1]/X[2])
z31 = (sum(A3*A1))*(C[2]/X[0])
z32 = (sum(A3*A2))*(C[2]/X[1])
z33 = (sum(A3*A3))*(C[2]/X[2])
Z = np.array([[z11,z12,z13],
[z21,z22,z23],
[z31,z32,z33]])
We can use the broadcasting to achieve the same. First let's increase A by one dimension using A[:, None] and then multiply it with A. Since shape of A[:, None] is (3, 1, 5) and shape of A is (3, 5), numpy first repeats(intuitively) the array corresponding to dimension where both array don't match and then does the multiplication. This way each column of A gets multiplied with every other column(to makes sure that columns are multiplied, I have used transpose) Then we can take sum along the last axis and multiply with C[:, None] to achieve the desired output.
Use:
m = A.shape[1]
B = A[:, None].T * A.T
Z = np.sum(B, axis = -1).astype(float)*C[:m, None]/X
Output:
>>> Z
array([[0.5 , 0. , 0. ],
[0. , 1. , 0.25 ],
[0. , 2.25 , 3.375]])

What does the Sine of an array do in Python?

Suppose I have a numpy array in Python created by the np.linspace function which returns an i amount of numbers evenly spaced out in a given range. In this case the range is 0 to 2.
import numpy as np
i = 10
t = np.linspace(2, i)
x = np.sin(t)
print(t)
print(x)
The output is 2 arrays. One for t, and one for sin(t):
[0. 0.22222222 0.44444444 0.66666667 0.88888889 1.11111111
1.33333333 1.55555556 1.77777778 2. ]
[0. 0.22039774 0.42995636 0.6183698 0.77637192 0.8961922
0.9719379 0.99988386 0.9786557 0.90929743]
The t array increases by 0.22222222 every time. I initially thought that the x array would be the sin of each index in the t array. So for example, x[2] = sin(t[2]) = 7.757e-3. But this is clearly not the case.
So what does the Sine of an array do in Python?
numpy.sin() helps to calculate trignmetric sine for all elements in x.
note:- All the elements in x should be in radian
import numpy as np
i = 10
t = np.radians(np.linspace(2, i))
x = np.sin(t)
print(t)
print(x)

Squared Mahalanobis distance function in Python returning array - why?

The code is:
import numpy as np
def Mahalanobis(x, covariance_matrix, mean):
x = np.array(x)
mean = np.array(mean)
covariance_matrix = np.array(covariance_matrix)
return (x-mean)*np.linalg.inv(covariance_matrix)*(x.transpose()-mean.transpose())
#variables x and mean are 1xd arrays; covariance_matrix is a dxd matrix
#the 1xd array passed to x should be multiplied by the (inverted) dxd array
#that was passed into the second argument
#the resulting 1xd matrix is to be multiplied by a dx1 matrix, the transpose of
#[x-mean], which should result in a 1x1 array (a number)
But for some reason I get a matrix for my output when I enter the parameters
Mahalanobis([2,5], [[.5,0],[0,2]], [3,6])
output:
out[]: array([[ 2. , 0. ],
[ 0. , 0.5]])
It seems my function is just giving me the inverse of the 2x2 matrix that I input in the 2nd argument.
You've made the classic mistake of assuming that the * operator is doing matrix multiplication. This is not true in Python/numpy (see http://www.scipy-lectures.org/intro/numpy/operations.html and https://docs.scipy.org/doc/numpy-dev/user/numpy-for-matlab-users.html). I broke it down into intermediate steps and used the dot function
import numpy as np
def Mahalanobis(x, covariance_matrix, mean):
x = np.array(x)
mean = np.array(mean)
covariance_matrix = np.array(covariance_matrix)
t1 = (x-mean)
print(f'Term 1 {t1}')
icov = np.linalg.inv(covariance_matrix)
print(f'Inverse covariance {icov}')
t2 = (x.transpose()-mean.transpose())
print(f'Term 2 {t2}')
mahal = t1.dot(icov.dot(t2))
#return (x-mean)*np.linalg.inv(covariance_matrix).dot(x.transpose()-mean.transpose())
return mahal
#variables x and mean are 1xd arrays; covariance_matrix is a dxd matrix
#the 1xd array passed to x should be multiplied by the (inverted) dxd array
#that was passed into the second argument
#the resulting 1xd matrix is to be multiplied by a dx1 matrix, the transpose of
#[x-mean], which should result in a 1x1 array (a number)
Mahalanobis([2,5], [[.5,0],[0,2]], [3,6])
produces
Term 1 [-1 -1]
Inverse covariance [[2. 0. ]
[0. 0.5]]
Term 2 [-1 -1]
Out[9]: 2.5
One can use scipy's mahalanobis() function to verify:
import scipy.spatial, numpy as np
scipy.spatial.distance.mahalanobis([2,5], [3,6], np.linalg.inv([[.5,0],[0,2]]))
# 1.5811388300841898
1.5811388300841898**2 # squared Mahalanobis distance
# 2.5000000000000004
def Mahalanobis(x, covariance_matrix, mean):
x, m, C = np.array(x), np.array(mean), np.array(covariance_matrix)
return (x-m)#np.linalg.inv(C)#(x-m).T
Mahalanobis([2,5], [[.5,0],[0,2]], [3,6])
# 2.5
np.isclose(
scipy.spatial.distance.mahalanobis([2,5], [3,6], np.linalg.inv([[.5,0],[0,2]]))**2,
Mahalanobis([2,5], [[.5,0],[0,2]], [3,6])
)
# True

Why isn't the shape of the array correct?

I'm having some array operation issues. Here's an example:
A = np.ones((5,2))
B = np.ones((5,2)) * 2
X = np.zeros((5,1))
C = A[:,0] + B[:,0]
D = C + X
The shapes I'm getting are:
shape(A[:,0]) = (5,)
shape(B[:,0]) = (5,)
shape(X) = (5,1)
shape(C) = (5,)
shape(D) = (5,5)
When I extract a column from an array, the output is from shape (5,), not (5,1). Is there any way to correct that without having to reshape arrays all the time?
When I add D = C + X, the result is an (5,5) array, but should be (5,1).
Solution 1
D = X + C.reshape(shape(X))
shape(D)
#(5, 1)
print(D)
#[[ 3.]
# [ 3.]
# [ 3.]
# [ 3.]
# [ 3.]]
Solution 2 (better) numpy-convert-row-vector-to-column-vector
C = A[:,0:1] + B[:,0:1]
Why,
C and X have different shapes, and you sum row with number, geting a matrix with shape (5,5)
print(C)
#[ 3. 3. 3. 3. 3.]
print(X)
#[[ 0.]
# [ 0.]
# [ 0.]
# [ 0.]
# [ 0.]]
When broadcasting an array like C with (5,) with a 2d array, numpy adds dimensions at the start as needed, (1,5). So a (1,5) + (5,1) => (5,5).
To get a (5,1) result, you need, in one way or other, make C a (5,1) array.
C[:,None] + X # None or np.newaxis is an easy way
C.reshape(5,1) + X # equivalent
or index A with a list or slice
C = A[:,[0]] + B[:,[0]]
A[:,0] removes a dimension, producing a (5,) array.
Note, MATLAB adds the default dimensions to the end; numpy because it has a default C order, does so at the start. Adding dimensions like that requires minimal change, just changing the shape.
Functions like np.sum have a keepdimensions parameter to avoid this sort of dimension reduction.

Trying to implement linear regression in python

I am implementing linear regression in Python, and I think I am doing something wrong while converting matrix to numpy array, but cannot seem to figure it out.
Any help will be appreciated.
I am loading data from a csv file that has 100 columns. y is the last column. I am not using col 1 and 2 for regression.
communities=np.genfromtxt("communities.csv", delimiter = ",", dtype=float)
xdata = communities[1:,2:99]
x = np.array([np.concatenate((v,[1]))for v in xdata])
y = communities[1:,99]
Function definition
def standRegress(xArr, yArr):
xMat = mat(xArr); yMat = mat(yArr).T
xTx = xMat.T*xMat
if linalg.det(xTx)==0.0:
print"singular matrix"
return
ws = xTx.I*(xMat.T*yMat)
return ws
calling the function
w = standRegress(x,y)
xMat = mat(x) #shape(1994L,98L)
yMat = mat(y) #shape (1L, 1994L)
yhat = xMat*w #shape (1994L, 1L)
Next I am trying to calculate RMSE and this is where I am having problem
yMatT = yMat.T #shape(1994L, 1L)
err = yhat - yMatT #shape(1994L, 1L)
error = np.array(err)
total_error = np.dot(error,error)
rmse = np.sqrt(total_error/len(p))
I get an error while I am doing the dot product and thus not able to calculate rmse. I will appreciate if someone can help me find my mistake.
Error:
---> 11 np.dot(error,error)
12 #test = (error)**2
13 #test.sum()/len(y)
ValueError: matrices are not aligned
I'm not quite sure what the last dot is supposed to do. But you can't multiple error with itself this way. dot does a matrix multiplication, thus the dimensions have to align.
See, e.g., the following example:
import numpy as np
A = np.ones((3, 4))
B = np.ones((3, 4))
print np.dot(A, B)
This yields the error ValueError: matrices are not aligned.
What is possible, however, is:
print np.dot(A.T, B)
Output:
[[ 3. 3. 3. 3.]
[ 3. 3. 3. 3.]
[ 3. 3. 3. 3.]
[ 3. 3. 3. 3.]]
In your example error is just a column vector - but stored as a 2D array:
A = np.ones((3, 1))
B = np.ones((3, 1))
print np.dot(A, B)
Same error.
So you can either transpose one argument - as shown above - or extract one column as a 1D array:
print np.dot(A[:, 0], B[:, 0])
Output:
3.0

Categories

Resources