I am trying to define a function that transposes a matrix. This is my code:
def Transpose (A):
B = list(zip(*A))
return B
Now when I call the function somewhere in the program like such:
Matrix = [[1,2,3],[4,5,6],[7,8,9]]
Transpose(Matrix)
print(Matrix)
The matrix comes out unchanged. What am I doing wrong?
Your function returns a new value that does not affect your matrix (zip does not change it's parameters). You are not doing anything wrong, that is the correct way of doing things.
Just change it to:
print(Transpose(Matrix))
or
Matrix = Transpose(Matrix)
Note: You really should be using lower-case names for your functions and variables.
Related
I was given code in Matlab made by someone else and asked to convert to python. However, I do not know MatLab.This is the code:
for i = 1:nWind
[input(a:b,:), t(a:b,1)] = EulerMethod(A(:,:,:,i),S(:,:,i),B(:,i),n,scale(:,i),tf,options);
fprintf("%d\n",i);
for j = 1:b
vwa = generate_wind([input(j,9);input(j,10)],A(:,:,:,i),S(:,:,i),B(:,i),n,scale(:,i));
wxa(j) = vwa(1);
wya(j) = vwa(2);
end
% Pick random indexes for filtered inputs
rand_index = randi(tf/0.01-1,1,filter_size);
inputf(c:d,:) = input(a+rand_index,:);
wxf(c:d,1) = wxa(1,a+rand_index);
wyf(c:d,1) = wya(1,a+rand_index);
wzf(c:d,1) = 0;
I am confused on what [input(a:b,:), t(a:b,1)] mean and if wxf, wzf, wyf are part of the MatLab library or if it's made. Also, EulerMethod and generate_wind are seprate classes. Can someone help me convert this code to python?
The only thing I really changed so far is changing the for loop from:
for i = 1:nWind
to
for i in range(1,nWind):
There's several things to unpack here.
First, MATLAB indexing is 1-based, while Python indexing is 0-based. So, your for i = 1:nWind from MATLAB should translate to for i in range(0,nWind) in Python (with the zero optional). For nWind = 5, MATLAB would produce 1,2,3,4,5 while Python range would produce 0,1,2,3,4.
Second, wxf, wyf, and wzf are local variables. MATLAB is unique in that you can assign into specific indices at the same time variables are declared. These lines are assigning the first rows of wxa and wya (since their first index is 1) into the first columns of wxf and wyf (since their second index is 1). MATLAB will also expand an array if you assign past its end.
Without seeing the rest of the code, I don't really know what c and d are doing. If c is initialized to 1 before the loop and there's something like c = d+1; later, then it would be that your variables wxf, wyf, and wzf are being initialized on the first iteration of the loop and expanded on later iterations. This is a common (if frowned upon) pattern in MATLAB. If this is the case, you'd replicate it in Python by initializing to an empty array before the loop and using the array's extend() method inside the loop (though I bet it's frowned upon in Python, as well). But really, we need you to edit your question to include a, b, c, and d if you want to be sure this is really the case.
Third, EulerMethod and generate_wind are functions, not classes. EulerMethod returns two outputs, which you'd probably replicate in Python by returning a tuple.
[input(a:b,:), t(a:b,1)] = EulerMethod(...); is assigning the two outputs of EulerMethod into specific ranges of input and t. Similar concepts as in points 1 and 2 apply here.
Those are the answers to what you expressed confusion about. Without sitting down and doing it myself, I don't have enough experience in Python to give more Python-specific recommendations.
I'm trying to create a function in Python that returns a dictionary with an eigenvector and it's corresponding eigenvalue:
This is my working code so far:
def eigenvectors(a):
b = np.matrix(a)
dicto = {}
for i in b:
dicto.append(b)
return dicto
eigenvectors('1,2,3')
I don't think I'm going about this the right way. Basically, my parameter I'm trying to define is a matrix where no matter what matrix I put in the function, I will be able to get back the eigenvector and eigenvalue associated with it.
If anyone could help me out, I would really appreciate it. I feel like I have the concept down but I'm just having a hard time putting the function together.
Does numpy.linalg.eig helps? https://numpy.org/doc/stable/reference/generated/numpy.linalg.eig.html
If you want it exclusively as a dict you can simply use zip:
a = np.array([
[1,2,3],
[4,5,6],
[7,8,9]
])
def eigenvectors(a):
values, vectors = np.linalg.eig(a)
return dict(zip(values, vectors))
eigenvectors(a)
N00b question, maybe.
I am new-ish to python, but I was wondering if it is possible to store a function in an array? I want to do an array multiplication, where the value of one array is multiplied by a function on a location of another array of functions. Or actually, the value of the first array is inserted in the function of the designated location. This should create a new array where the values are an outcome of the "multiplication".
>>> import numpy as np
>>> a = [[1, 0], [0, 1]]
>>> b = [[f(x), g(x)], [(h(x), f(x)]]
>>> np.dot(a, b)
array([[0, 1],
[2, 0]])
Assuming that f(x), g(x) and h(x) are defined functions. In this case python will say that x is not defined. So far I know. However, I do not want to say, for example, f(a[0][1]), because I want to reuse array b and also be able to put the functions on random locations in the array.
In short I detect three questions:
- Is there a known way to have an array where the values are functions?
- If not, should I redefine an array function or write a new class for this? (how do I attack this problem?)
- If it is possible to create an array of functions, can I fill the 'function values' dynamically in the array (populate the array dynamically with functions) or can it only be static values?
like for example
b[0]=f(x)
And yes, I really want to do this with python.
f(x) is not a function (even in mathematics). The function is f. In python there is no problem to store functions in array:
def my_func():
print("Foo")
my_other_func = lambda: print("Bar")
my_arr = [my_func, my_other_func]
Your example puts the result of calling a function into your array.
b[0] = f
actually puts the function itself into the array, so that
b[0](x)
would have the same effect as
f(x)
Is there a known way to have an array where the values are functions?
There is, as stated by others already.
def my func(x):
return x
my_other_func = lambda x: x
l = [my_func, my_other_func]
If not, should I redefine an array function or write a new class for this? (how do I attack this problem?)
Not relevant
If it is possible to create an array of functions, can I fill the 'function values' dynamically in the array (populate the array dynamically with functions) or can it only be static values?
The 'function values' are called parameters and can be assigned after having the function in the array:
a[0](5) # == my_func(5)
a[1]('Hello') # == my_other_func('Hello')
The problem is that you are trying to use matrix multiplication as parameter passing and that will not work, you could create a helper fucntion that does it.
def callByElements(parameterMatrix, functionMatrix):
rows = len(parameterMatrix)
cols = len(parameterMatrix[0])
result = np.zeros( (rows, cols) )
for i in range(rows):
for j in range(cols):
result[i,j] = functionMatrix[i,j](parameterMatrix[i,j])
return result
I have defined a class which contains some basic matrix functions. My function for transposing a matrix looks like this:
def transpose(self):
'''
Transpose a matrix.
'''
C = Z ## creating a new zero matrix
for i in range(0, self.rows):
for j in range(0, self.cols):
C.matrix[i][j] = self.matrix[j][i]
## printing the resultant matrix
C.show()
return C
So when I call this function from the interpreter, it prints the result after execution (because of the show() function).
However, when I call this function from another function in the same class, I don't want the matrix to be printed, that is, I don't want the C.show() part to execute.
Is there any way to do this? I was thinking on the lines of __name__ == "__main__" but that doesn't really apply here it seems.
Just add another, default, parameter to the function and put the print in an if:
def transpose(self, print_matrix=True):
'''
Transpose a matrix.
'''
C = Z ## creating a new zero matrix
for i in range(0, self.rows):
for j in range(0, self.cols):
C.matrix[i][j] = self.matrix[j][i]
## printing the resultant matrix
if print_matrix:
C.show()
return C
As it has a default value you don't need to change any current method calls, but you can add another parameter to your new one. Call it as transpose(False), if you don't want to print.
The problem you have is that the calculation and display are both coupled into the same function. In general, tight coupling like this is considered undesirable. Why? Well, you are seeing the problem now, you can't do one part of the function without the other.
Now I could give you crazy answers about how to only print when called from the interpreter, but I would be encouraging bad code. Instead, we should decouple this function into two different function.
Decoupling is simple, take the two different things your code is doing -- printing and calculating -- and separate them into two different functions.
def transpose(self):
'''
Transpose a matrix.
'''
C = Z ## creating a new zero matrix
for i in range(0, self.rows):
for j in range(0, self.cols):
C.matrix[i][j] = self.matrix[j][i]
return C
def transposeAndPrint(self):
C = transpose(self)
C.show()
Now you can call transposeAndPrint when you need to print, and transpose when you don't need to.
Of course I could tell you to add an extra parameter but that won't change the fact that a transpose function should not do printing (except for debug).
def transpose(self):
'''
Transpose a matrix.
'''
C = Z ## creating a new zero matrix
for i in range(0, self.rows):
for j in range(0, self.cols):
C.matrix[i][j] = self.matrix[j][i]
return C
And somewhere else, where you need it:
o.transpose()
o.show()
Another option would be to use Python's logging module. You can set multiple logging levels, which are intended for just this type of situation. In this case, you could make the show function output at the DEBUG level, which you can then easily turn on or off as need be.
See:
http://docs.python.org/2/howto/logging.html
(I am quite a newbie in Python, so lots of things puzzle me even after reading the tutorial...)
Initially, I had the code like the following:
strings = ['>abc', 'qwertyu', '>def', 'zxcvbnm']
matrix = zip(*strings)
for member in matrix:
print("".join(member)) # characters are printed as expected
-- which did what I expected. But then for some reason I wanted to determine the number of members in matrix; as len(matrix) gave an error, I decided to copy it with converting to the list: mtxlist = list(matrix). Surprisingly, after this line the content of matrix seems to be changed - or at least I cannot use it the same way as above:
strings = ['>abc', 'qwertyu', '>def', 'zxcvbnm']
matrix = zip(*strings)
mtxlist = list(matrix) # this assignment empties (?) the matrix
for member in matrix:
print("".join(member)) # nothing printed
Can anybody explain what is going on there?
You're using Python 3, correct?
zip returns a generator that can only be iterated once. If you want to use it more than once, then your options are:
Write zip(*strings) each time you need it.
matrix = tuple(zip(*strings))
(iterate matrix as many times as you like. This is the easy option. The downside is that if zip(*strings) is big then it uses a lot of memory that the generator doesn't.)
matrix1, matrix2 = itertools.tee(zip(*strings))
(iterate each of matrix1 and matrix2 once. This is worse than the tuple in your usage, but it's useful if you want to partially consume matrix1, then use some of matrix2, more of matrix1, etc)
def matrix():
return zip(*strings)
# or
matrix = lambda: zip(*strings)
(iterate but using matrix(), not matrix, as many times as you like. Doesn't use extra memory for a copy of the result like the tuple solution, but the syntax for using it is a bit annoying)
class ReusableIterable:
def __init__(self, func):
self.func = func
def __iter__(self):
return iter(self.func())
matrix = ReusableIterable(lambda: zip(*strings))
(iterate using matrix as many times as you like. Deals with the syntax annoyance, although you still have to beware that if you modify strings between iterations over matrix then you'll get different results.)