Numpy is not inserting the right array into multidimensional array - python-3.x

I have a matrix
M = np.array([
[1, -2, -2, -2, 1, 2],
[0, 3, -2, -3, 1, 3],
[3, 0, 0, 1, -1, 2],
[3, -3, -2, 0, 1, 1],
[0, -3, 3, -3, -3, 2]
])
and I'm trying to replace the first row by itself modulo some number N = 2497969412496091.
I've been playing around with this in the IDE for a while, and even though
>>> M[0] % N
array([1, 2497969412496089, 2497969412496089, 2497969412496089, 1, 2], dtype=int64)
After I preform M[0] = M[0] % N and print the matrix M, I get
>>> M[0]
array([1, -746726695, -746726695, -746726695, 1, 2])
I've also tried to copy the intermediate step M[0] % N in a temporary variable and then setting it equal to M[0] but the problem still persists. What is going on here?

Your array is np.int32:
print(type(M[0][0])) # <class 'numpy.int32'>
Create the original array as np.int64 - to avoid getting integer overflow happening:
import numpy as np
M = np.array([
[1, -2, -2, -2, 1, 2],
[0, 3, -2, -3, 1, 3],
[3, 0, 0, 1, -1, 2],
[3, -3, -2, 0, 1, 1],
[0, -3, 3, -3, -3, 2]
], dtype=np.int64)
N = 2497969412496091
M[0] = M[0] % N
print(M)
Output:
[[ 1 2497969412496089 2497969412496089 2497969412496089 1 2]
[ 0 3 -2 -3 1 3]
[ 3 0 0 1 -1 2]
[ 3 -3 -2 0 1 1]
[ 0 -3 3 -3 -3 2]]

Related

3D matrix addition python

I am trying to add 3D matrix but third loop is not starting from 0.
Here shape of matrix is (2,3,3).
Code:
for i in range(0,r):
for j in range(0,c):
for l in range(0,k):
sum[i][j][k]=A1[i][j][k]+A2[i][j][k]
Output:
IndexError: index 3 is out of bounds for axis 0 with size 3
For element-wise addition of two matrices, you can simply use the + operator between two numpy arrays:
#create two matrices of random integers
matrix1 = np.random.randint(10, size=(2,3,3))
matrix2 = np.random.randint(10, size=(2,3,3))
#add the two matrices element-wise
sum_matrix = matrix1 + matrix2
print(matrix1, matrix2, sum_matrix, sep='\n__________\n')
I don't get IndexError. Maybe you post your whole code?
This is my code:
arr1 = [[[2, 4, 8], [7, 7, 1], [4, 9, 0]], [[5, 0, 0], [3, 8, 6], [0, 5, 8]]]
arr2 = [[[3, 8, 0], [1, 5, 2], [0, 3, 9]], [[9, 7, 7], [1, 2, 5], [1, 1, 3]]]
sumArr = [[[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0],[0, 0, 0]]]
for i in range(2): #can also use range(0,2)
for j in range(3):
for k in range(3):
sumArr[i][j][k]=arr1[i][j][k]+arr2[i][j][k]
print(sumArr)
By the way, is it necessary to use for loop?
If not, you can use numpy library.
import numpy as np
Convert your manual array to numpy matrix array, then do addition.
arr1 = [[[2, 4, 8], [7, 7, 1], [4, 9, 0]], [[5, 0, 0], [3, 8, 6], [0, 5, 8]]]
arr2 = [[[3, 8, 0], [1, 5, 2], [0, 3, 9]], [[9, 7, 7], [1, 2, 5], [1, 1, 3]]]
m1 = np.array(arr1)
m2 = np.array(arr2)
print("M1: \n", m1)
print("M2: \n", m2)
print("Sum: \n", m1 + m2)
You iterate with 'l' in the third loop but to access in list, you used k. As a result, your code is trying to access k-th index which doesn't exists, and you're getting an error.
Use this:
for i in range(0, r):
for j in range(0, c):
for l in range(0, k):
sum[i][j][l] = A1[i][j][l] + A2[i][j][l]

Multiclass vs. multilabel fitting

In scikit-learn tutorials, I found the following paragraphs in the section 'Multiclass vs. multilabel fitting'.
I couldn't understand why the following codes generate the given results.
First
from sklearn.svm import SVC
from sklearn.multiclass import OneVsRestClassifier
from sklearn.preprocessing import LabelBinarizer
X = [[1, 2], [2, 4], [4, 5], [3, 2], [3, 1]]
y = [0, 0, 1, 1, 2]
classif = OneVsRestClassifier(estimator=SVC(random_state=0))
classif.fit(X, y).predict(X)
array([0, 0, 1, 1, 2])
y = LabelBinarizer().fit_transform(y)
classif.fit(X, y).predict(X)
array([[1, 0, 0],
[1, 0, 0],
[0, 1, 0],
[0, 0, 0],
[0, 0, 0]])
Next
from sklearn.preprocessing import MultiLabelBinarizer
y = [[0, 1], [0, 2], [1, 3], [0, 2, 3], [2, 4]]
y = MultiLabelBinarizer().fit_transform(y)
classif.fit(X, y).predict(X)
array([[1, 1, 0, 0, 0],
[1, 0, 1, 0, 0],
[0, 1, 0, 1, 0],
[1, 0, 1, 0, 0],
[1, 0, 1, 0, 0]])
Label binarization in scikit-learn will transform your targets and represent them in a label indicator matrix. This label indicator matrix has the shape (n_samples, n_classes) and is composed as follows:
each row represents a sample
each column represents a class
each element is 1 if the sample is labeled with the class and 0 if not
In your first example, you have a target collection with 5 samples and 3 classes. That's why transforming y with LabelBinarizer results in a 5x3 matrix. In your case, [1, 0, 0] corresponds to class 0, [0, 1, 0] corresponds to class 1 and so forth. Notice that in each row there is only one element set to 1, since each sample can have one label only.
In your next example, you have a target collection with 5 samples and 5 classes. That's why transforming y with MultiLabelBinarizer results in a 5x5 matrix. In your case, [1, 1, 0, 0, 0] corresponds to the multilabel [0, 1], [0, 1, 0, 1, 0] corresponds to the multilabel [1, 3] and so forth. The key difference to the first example is that each row can have multiple elements set to 1, because each sample can have multiple labels/classes.
The predicted values you get follow the very same pattern. They are however not equivalent to the original values in y since your classification model has obviously predicted different values. You can check this with the inverse_transform() of the binarizers:
from sklearn.preprocessing import MultiLabelBinarizer
mlb = MultiLabelBinarizer()
y = np.array([[0, 1], [0, 2], [1, 3], [0, 2, 3], [2, 4]])
y_bin = mlb.fit_transform(y)
# direct transformation
[[1 1 0 0 0]
[1 0 1 0 0]
[0 1 0 1 0]
[1 0 1 1 0]
[0 0 1 0 1]]
# prediction of your classifier
y_pred = np.array([[1, 1, 0, 0, 0],
[1, 0, 1, 0, 0],
[0, 1, 0, 1, 0],
[1, 0, 1, 0, 0],
[1, 0, 1, 0, 0]])
# inverting the binarized values to the original classes
y_inv = mlb.inverse_transform(y_pred)
# output
[(0, 1), (0, 2), (1, 3), (0, 2), (0, 2)]

How to reshape an array with numpy like this:

I have this:
array([[0, 0, 1, 1, 2, 2, 3, 3],
[0, 0, 1, 1, 2, 2, 3, 3]])
And I would like to reshape my array like this:
array([[0, 0, 1, 1],
[0, 0, 1, 1],
[2, 2, 3, 3],
[2, 2, 3, 3]])
How do I do it using python numpy?
You can just split and concatenate:
a = np.array([[0, 0, 1, 1, 2, 2, 3, 3],
[0, 0, 1, 1, 2, 2, 3, 3]])
cols = a.shape[1] // 2
np.concatenate((a[:,:cols], a[:,cols:]))
#[[0 0 1 1]
# [0 0 1 1]
# [2 2 3 3]
# [2 2 3 3]]
You can simply swap rows after reshaping it.
a= np.array([[0, 0, 1, 1, 2, 2, 3, 3],
[0, 0, 1, 1, 2, 2, 3, 3]]).reshape(4,4)
a[[1,2]] = a[[2,1]]
Output:
array([[0, 0, 1, 1],
[0, 0, 1, 1],
[2, 2, 3, 3],
[2, 2, 3, 3]])

Initialize and Populate 2 Dimensional Array in Python from other Lists

I want to create 2 dimensional array and populate it with the following information.
n = 7
j = [0, 1, 2, 3, 4, 5, 6]
k = [0, 2, 4, 3, 3, 2, 1]
l = [0 , 46, 52, 30, 36 ,56, 40]
so, the the first list of the List L should b [0,0,0], second list of list L should be [1,2,46], third should of List L should be the list [2, 4, 52] and so on. But its not working and it keep overriding the values
#!/usr/bin/python3.6
from operator import itemgetter
n = 7
j = [0, 1, 2, 3, 4, 5, 6]
k = [0, 2, 4, 3, 3, 2, 1]
l = [0 , 46, 52, 30, 36 ,56, 40]
L = [[0]*3]*n
print(L)
x = 0
y = 0
z = 0
while x < len(j):
L[x][0] = j[x]
x = x + 1
while y < len(k):
L[y][1] = k[y]
y = y + 1
while z < len(l):
L[z][2] = l[z]
z = z + 1
print (L)
The current output is
Initialization of L, and thats ok
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
And L after modification, which is very wrong
[[6, 1, 40], [6, 1, 40], [6, 1, 40], [6, 1, 40], [6, 1, 40], [6, 1, 40], [6, 1, 40]]
First and foremost:
L = [[0]*3]*n
is the wrong way to initialize a 2D list. If I set l[0][0] to 1, look what happens:
n = 7
L = [[0]*3]*n
L[0][0] = 1
print(L)
Output:
[[1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0]]
To properly initialize a 2D list, do:
L = [[0] * 3 for _ in range(n)]
If you change it to this, your code will work.
But actually, your problem can be solved in a much simpler way. Just use zip:
j = [0, 1, 2, 3, 4, 5, 6]
k = [0, 2, 4, 3, 3, 2, 1]
l = [0, 46, 52, 30, 36, 56, 40]
result = [list(x) for x in zip(j, k, l)]
print(result)
Output:
[[0, 0, 0],
[1, 2, 46],
[2, 4, 52],
[3, 3, 30],
[4, 3, 36],
[5, 2, 56],
[6, 1, 40]]

Python Exponential function

I have defined the following symbolic matrix:
def DFT(d):
a = symbols('pi')
DFT = Matrix(d, d, lambda i,j: exp((2*I/d)*i*j*a))
return(DFT)
Now, I would like to simplify the exponential to the corresponding 1,-1,I,-I when its argument is an intiger or half integer value, but for the rest of the cases I would like to keep the symbolic expression.
Is there any method that I could use? How should I do it?
Regards!
If I use the predefined symbol sympy.pi instead of a in the definition of DFT, it simplifies the values automatically:
In [27]: from sympy import *
In [28]: def DFT(d):
...: DFT = Matrix(d, d, lambda i,j: exp((2*I/d)*i*j*pi))
...: return(DFT)
...:
In [29]: DFT(4)
Out[29]:
Matrix([
[1, 1, 1, 1],
[1, I, -1, -I],
[1, -1, 1, -1],
[1, -I, -1, I]])
In [30]: DFT(6)
Out[30]:
Matrix([
[1, 1, 1, 1, 1, 1],
[1, exp(I*pi/3), exp(2*I*pi/3), -1, exp(4*I*pi/3), exp(5*I*pi/3)],
[1, exp(2*I*pi/3), exp(4*I*pi/3), 1, exp(8*I*pi/3), exp(10*I*pi/3)],
[1, -1, 1, -1, 1, -1],
[1, exp(4*I*pi/3), exp(8*I*pi/3), 1, exp(16*I*pi/3), exp(20*I*pi/3)],
[1, exp(5*I*pi/3), exp(10*I*pi/3), -1, exp(20*I*pi/3), exp(25*I*pi/3)]])
In [31]: DFT(8)
Out[31]:
Matrix([
[1, 1, 1, 1, 1, 1, 1, 1],
[1, exp(I*pi/4), I, exp(3*I*pi/4), -1, exp(5*I*pi/4), -I, exp(7*I*pi/4)],
[1, I, -1, -I, 1, I, -1, -I],
[1, exp(3*I*pi/4), -I, exp(9*I*pi/4), -1, exp(15*I*pi/4), I, exp(21*I*pi/4)],
[1, -1, 1, -1, 1, -1, 1, -1],
[1, exp(5*I*pi/4), I, exp(15*I*pi/4), -1, exp(25*I*pi/4), -I, exp(35*I*pi/4)],
[1, -I, -1, I, 1, -I, -1, I],
[1, exp(7*I*pi/4), -I, exp(21*I*pi/4), -1, exp(35*I*pi/4), I, exp(49*I*pi/4)]])

Resources