Elements from list are overwritten in python - python

I've been struggling for some days trying to figure out why my items from a python list are overwritten. Basically I have to implement a function that rotates 8 times a matrix.
def rotate_ring(matrix, offset):
dim = len(matrix[0])
print(dim)
last_element = matrix[offset][offset]
for j in range(1 + offset, dim - offset):
matrix[offset][j-1] = matrix[offset][j]
matrix[offset][dim-1-offset] = matrix[1+offset][dim-1-offset]
for i in range(1 + offset, dim - offset):
matrix[i-1][dim-1-offset] = matrix[i][dim-1-offset]
matrix[dim-1-offset][dim-1-offset] = matrix[dim-1-offset][dim-2-offset]
for j in range(1+offset, dim-offset):
matrix[dim-1-offset][dim-j] = matrix[dim-1-offset][dim-j-1]
matrix[dim-1-offset][offset] = matrix[dim-2-offset][offset]
for i in range(1+offset, dim-offset):
matrix[dim-i][offset] = matrix[dim-i-1][offset]
matrix[1+offset][offset] = last_element
return matrix
def rotate_matrix(matrix):
dim = len(matrix[0])
for offset in range(0, int(dim/2)):
matrix = rotate_ring(matrix, offset)
return matrix
The functions above are the functions that rotate the matrix and they do because I checked them. After these functions were implemented, I implemented another function
def compass_filter(kernel):
#result = np.zeros(gray.shape, dtype=np.float)
#result = np.zeros(gray.shape, dtype=np.float)
results = []
results.append(kernel)
for i in range(0,7):
kernel = rotate_matrix(kernel) #rotate the kernel
print(kernel)
results.append(kernel) #appending to results
return results
that iterates, 8 times (because I always have 8 kernels) and append the kernels to a list. The problem that I have encountered is that the new rotated kernel is printed:
, but when I print the final list all I see is the last kernel printed 8 times. Does anybody what is the problem? I have also tried to do another list in the for loop just for the new element and then append it to the list that is outside the loop. Thank you!

Please change the function compass filter as follows:
def compass_filter(kernel):
results = []
results.append(kernel)
for i in range(7):
kernel_ = np.array([rotate_matrix(kernel)])
print(kernel_)
results.append(kernel_)
return results

Related

Numpy is not swapping elements

I am trying to swap two indices in the 2D array of NumPy. Unfortunately, only one element is getting swapped. Here is the code:
n = len(A)
perMatrix = np.zeros((n,n))
np.fill_diagonal(perMatrix, 1)
perMatrix = A
# swapping the row
print(perMatrix)
temp = perMatrix[switchIndex1]
print(temp)
# perMatrix[switchIndex1][0] = 14
perMatrix[switchIndex1], perMatrix[switchIndex2] = perMatrix[switchIndex2], perMatrix[switchIndex1]
print(perMatrix)
Here's what the code is outputting:
You could just add (on the line after perMatrix is created):
sigma = [switchIndex1, switchIndex2]
tau = [switchIndex2, switchIndex1]
perMatrix[sigma,:] = perMatrix[tau,:]

Python 3 - IndexError: list index out of range when trying to find determinant of a matrix

I am trying to find determinant with a nested list representing a two-dimensional matrix. But it is infinitely calling the getMinor() function and continuously deleting from the same list, which should not happend because I am creating new list every time. Below is the code. Also all the functions are defined in a class named 'Matrix()'.
def __init__(self):
self.matrix_list = []
self.no_of_row = 0
self.no_of_col = 0
def getMinor(self, matrix, j):
del matrix[0]
for i in range(len(matrix)):
del matrix[i][j]
m = Matrix()
m.matrix_list = matrix[:]
m.no_of_row = len(m.matrix_list)
#print(m.no_of_row)
print(m.matrix_list)
m.no_of_col = len(m.matrix_list[0])
return m.detMatrix()
def detMatrix(self):
if self.no_of_row == 2 and self.no_of_col == 2:
return self.matrix_list[0][0] * self.matrix_list[1][1] - self.matrix_list[0][1] * self.matrix_list[1][0]
else:
matrix = self.matrix_list[:]
det = 0
for i in range(self.no_of_col):
det += ((-1)**i) * self.matrix_list[0][i] * self.getMinor(matrix, i)
return det
You have two problems. One is alluded to by user2357112 who unfortunately didn't bother to explain. When you use the expression x[:] you get a shallow copy of the list x. Often there is no practical difference between deep and shallow copies; for example if x contains numbers or strings. But in your case the elements of x are lists. Each element of the new list, x[:], will be the same sub-list that was in the original x - not a copy. When you delete one element of those nested lists (del matrix[i][j]), you are therefore deleting some of your original data.
The second problem is that you aren't handling the recursion properly. You create a new variable, matrix, in the function detMatrix. Even if you make a deep copy here, that won't fix the problem. You pass matrix to getMinor, which deletes some data from it. Now in the next step through your for loop, you have messed up the data. You need to make a deep copy inside the function getMinor.
Here is a program that runs, at least. I didn't check your algebra :-)
I will also add that it's very inefficient. The idea of making a copy and then deleting pieces from the copy doesn't make much sense. I didn't address this.
import copy
class Matrix:
def __init__(self):
self.matrix_list = []
self.no_of_row = 0
self.no_of_col = 0
def getMinor(self, matrix_list, j):
print("Entry:", matrix_list)
matrix = copy.deepcopy(matrix_list)
del matrix[0]
for i in range(len(matrix)):
del matrix[i][j]
print("After deletions", matrix_list)
m = Matrix()
m.matrix_list = matrix[:]
m.no_of_row = len(m.matrix_list)
m.no_of_col = len(m.matrix_list[0])
x = m.detMatrix()
print(m.matrix_list, m.no_of_row, m.no_of_col)
return x
def detMatrix(self):
if self.no_of_row == 2 and self.no_of_col == 2:
return self.matrix_list[0][0] * self.matrix_list[1][1] - self.matrix_list[0][1] * self.matrix_list[1][0]
else:
det = 0
for i in range(self.no_of_col):
det += ((-1)**i) * self.matrix_list[0][i] * self.getMinor(self.matrix_list, i)
return det
m = Matrix()
m.matrix_list.append([0.0,1.0,2.0,3.0])
m.matrix_list.append([1.0,2.0,3.0,4.0])
m.matrix_list.append([2.0,3.0,4.0,5.0])
m.matrix_list.append([3.0,5.0,7.0,9.0])
m.no_of_row = 4
m.no_of_col = 4
print(m.detMatrix())

Loop and extract window

I am trying to create a function (or series of functions), that perform the following operations:
Having an input array(A), for each cell A[i,j], extract a window (W), of custom size, where the value 'min' will be:
min = np.min(W)
The output matrix (H) will store the values as:
H[i,j] = A[i,j] - min(W)
For an easier understanding of the issue, I attached a picture (Example):
My current code is this:
def res_array(matrix, size):
result = []
sc.generic_filter(matrix, nothing, size, extra_arguments=(result,), mode = 'nearest')
mat_out = result
return mat_out
def local(window):
H = np.empty_like(window)
w = res_array(window, 3)
win_min = np.apply_along_axis(min, 1, w)
# This is where I think it's broken
for k in win_min:
for i in range(window.shape[0]):
for j in range(window.shape[1]):
h[i, j] = window[i,j] - k
k += 1
return h
def nothing(window, out):
list = []
for i in range(window.shape[0]):
list.append(window[i])
out.append(list)
return 0
test = np.ones((10, 10)) * np.arange(10)
a = local(test)
I need the code to pass to the next value in 'for k in win_min', for each cell of the input matrix A, or test.
Edit: I thought of something like directly accessing the index of the 'win_min', and increment by one, like I saw here: Increment the value inside a list element, but I don't know how to do that.
Thanks for any help!
N=4 #matrix size
a=random((N,N)) #input
#--window size
wl=1 #left
wr=1 #right
wt=1 #top
wb=1 #bottom
#---
H=np.zeros((N,N)) #output
def h(k,l): #individual cell function
#--- checks to not run out of array
k1=max(k-wt,0)
k2=min(k+wb+1,N)
l1=max(l-wl,0)
l2=min(l+wr,N)
#---
return a[k,l]-np.amin(a[k1:k2,l1:l2])
H=array([[h(k,l) for l in range(N)] for k in range(N)]) #running over all matrix elements
print a
print H

Matrices Class Calculator Python

In making the function to multiply the matrices my code only prints the first value of the first matrix and fills in all other position with zero. Below is the class with different functions and the multiply matrices function below it. The exception handling works and the printing function works as well. The only problem arises with
class Matrix(object):
"""Input the dimensions of your matrix"""
def __init__(self, rows = 3, cols = 3):
self.rows = rows
self.cols = cols
self.rowList = [ [0 * x for x in range(cols)] for count in range(rows)]
def setRow(self, index = 0, RowData = [0]*2):
"""Enter the index of the row you are defining followed by a string with the values seperated by commas"""
i = 0
if index >= self.cols:
print("Index is out of the bounds that you defined earlier")
return None
if len(RowData) != self.cols:
print("The Row length exceeds the column size of this matrix")
return None
else:
self.rowList[index] = RowData
def rowCount(self):
return self.rows
def columnCount(self):
return self.cols
def get(self, row, col):
return self.rowList[row][col]
def set(self, value = 0, row = 0, col = 0):
self.rowList[row][col] = value
return None
def MultiplyMatrices(A = Matrix(), B = Matrix()):
ARows = A.rowCount()
ACols = A.columnCount()
BRows = B.rowCount()
BCols = B.columnCount()
if ACols != BRows:
print("Matrices are incompatible, therefore cannot be multiplied")
return None
Result = Matrix(ARows, BCols)
for A_row in range(ARows):
for B_col in range(BCols):
Res = 0
for B_row in range(BRows):
Res = Res + A.get(A_row, B_row) * B.get(B_row, B_col)
Result.set(Res, A_row, B_col)
return Result
I think your problem is in your "for" loop.
You have
for B_row in range(BRows):
Res = Res + A.get(A_row, B_row) * B.get(B_row, B_col)
Result.set(Res, A_row, B_col)
return Result
but it should be
for A_row in range(ARows):
for B_col in range(BCols):
Res = 0
for B_row in range(BRows):
Res = Res + A.get(A_row, B_row) * B.get(B_row, B_col)
Result.set(Res, A_row, B_col)
return Result
The way you have things written, your code will return the Result matrix after only calculating the first entry value. I assume you have the other values defaulting to 0, which would explain why the rest of the entries in your Result matrix print as 0.
By the way, one thing you might want to consider is including this Multiply Matrix function in your Matrix class. If you define a class function using this signature
def __mul__(self):
"Your code here"
then when you create two instances of your matrix class, call them A and B, then you can multiply them within your program simply by typing A*B.
You seem to have a two indentation errors so that your MultiplyMatrices won't work correctly. Here's the corrected code:
for A_row in range(ARows):
for B_col in range(BCols):
Res = 0
for B_row in range(BRows):
Res = Res + A.get(A_row, B_row) * B.get(B_row, B_col)
Result.set(Res, A_row, B_col) # this edited so it's the sum over B_row
return Result # this set so it's after all three loops have completed
As a side note, I don't see how your default values (A = Matrix(), B = Matrix()) are ever going to work out well for you. It would almost always be better to just raise an exception if you don't get the needed in input rather than silently returning a matrix of all zeros.
Also, in case you're not already aware, you should know that there's an advanced set of tools for working with matrices in Python called Numpy.

Can a python list hold a multi-dimentional array as its element?

I am trying to do image processing using python.
I try to create a list which holds numpy.ndarrays.
My code looks like this,
def Minimum_Close(Shade_Corrected_Image, Size):
uint32_Shade_Corrected_Image = pymorph.to_int32(Shade_Corrected_Image)
Angles = []
[Row, Column] = Shade_Corrected_Image.shape
Angles = [i*15 for i in range(12)]
Image_Close = [0 for x in range(len(Angles))]
Image_Closing = numpy.zeros((Row, Column))
for s in range(len(Angles)):
Struct_Element = pymorph.seline(Size, Angles[s])
Image_Closing = pymorph.close(uint32_Shade_Corrected_Image,Struct_Element )
Image_Close[s] = Image_Closing
Min_Close_Image = numpy.zeros(Shade_Corrected_Image.shape)
temp_array = [][]
Temp_Cell = numpy.zeros((Row, Column))
for r in range (1, Row):
for c in range(1,Column):
for Cell in Image_Close:
Temp_Cell = Image_Close[Cell]
temp_array[Cell] = Temp_Cell[r][c]
Min_Close_Image[r][c] = min(temp_array)
Min_Close_Image = Min_Close_Image - Shade_Corrected_Image
return Min_Close_Image
While running this code I'm getting error:
Temp_Cell = Image_Close[Cell]
TypeError: only integer arrays with one element can be converted to an index
How can I make a data structure which holds different multi-dimensional arrays and then traverse through it??
Making a list of arrays is not necessary when you're using numpy.
I suggest rewriting the whole function like this:
def Minimum_Close(shade_corrected_image, size):
uint32_shade_corrected_image = pymorph.to_int32(shade_corrected_image)
angles = np.arange(12) * 15
def pymorph_op(angle):
struct_element = pymorph.seline(size, angle)
return pymorph.close(uint32_shade_corrected_image, struct_element)
image_close = np.dstack(pymorph_op(a) for a in angles)
min_close_image = np.min(image_close, axis=-1) - shade_corrected_image
return min_close_image
I lower cased variable names so that they stop getting highlighted as classes.
What about:
for cnt,Cell in enumerate(Image_Close):
Temp_Cell = Image_Close[cnt]

Categories

Resources