Adding two matrices in python - python-3.3

def addM(a, b):
res = []
for i in range(len(a)):
row = []
for j in range(len(a[0])):
row.append(a[i][j]+b[i][j])
res.append(row)
return res
I found this code here which was made by #Petar Ivanov, this code adds two matrices, i really don't understand the 3rd line, why does he use len(a) and the 5th line, why does he use len(a[0]). In the 6th line, also why is it a[i][j] +b[i][j]?

The matrix here is a list of lists, for example a 2x2 matrix will look like: a=[[0,0],[0,0]]. Then it is easy to see:
len(a) - number of rows.
len(a[0]) - number of columns (since this is a matrix, the length of a[0] is the same as length of any a[i]).
This way, i is the number of row, j is the number of column and a[i][j]+b[i][j] is simply adding up the elements of two matrices which are placed in the same locations in the matrices.
For all this to work, a and b should be of the same shapes (so, numbers of rows and columns would match).

Related

Efficient sparse matrix column change

I'm implementing an efficient PageRank algorithm so I'm using sparse matrices. I'm close, but there's one problem. I have a matrix where I want the sum of each column to be one. This is easy to implement, but the problem occurs when I get a matrix with a zero column.
In this case, I want to set each element in the column to be 1/(n-1) where n is the dimension of the matrix. I divide by n-1 and not n because I wish to keep the diagonals zero, always.
How can I implement this efficiently? My naive solution is to just determine the sum of each column and then find the column indices that are zero and replace the entire column with an 1/(n-1) value like so:
# naive approach (too slow!)
# M is my nxn sparse matrix where each column sums to one
col_sums = M.sum(axis=0)
for i in range(n):
if col_sums[0,i] == 0:
# set entire column to 1/(n-1)
M[:, i] = 1/(n-1)
# make sure diagonal is zeroed
M[i,i] = 0
My M matrix is very very very large and this method simply doesn't scale. How can I do this efficiently?
You can't add new nonzero values without reallocating and copying the underlying data structure. If you expect these zero columns to be very common (> 25% of the data) you should handle them in some other way, or you're better off with a dense array.
Otherwise try this:
import scipy.sparse
M = scipy.sparse.rand(1000, 1000, density=0.001, format='csr')
nz_col_weights = scipy.sparse.csr_matrix(M.shape, dtype=M.dtype)
nz_col_weights[:, M.getnnz(axis=0) == 0] = 1 / (M.shape[0] - 1)
nz_col_weights.setdiag(0)
M += nz_col_weights
This has only two allocation operations

builtins.TypeError: list indices must be integers or slices, not list

The question is:
Write a function get_column(game, col_num) that takes a legal 3 x 3 game of noughts and crosses as explained above and returns a 3-element list containing the values from column number col_num, top to bottom. You may assume col_num is in the range 0 to 2 inclusive.
Hint: Since noughts and crosses is always played on a 3 x 3 grid, you don't need to handle general n x m grids. It is sufficient to just explicitly select the row and column elements you need, so you don't actually require a loop for this question. However, you're welcome to try using a loop to give yourself more practice.
Hence I want to retrieve any column which I mention in the function from a list of list.
Below code is what I tried
def get_column(game, col_num):
"""returns a 3-element list containing the values from column number
col_num, top to bottom"""
j = col_num
result = []
for i in game:
result.append(game[i][j])
return result
I won't try to solve your exercise for you, but I can tell you why you are getting the error.
Your loop
for i in game:
Loops through the 3x3 list of lists. So it will loop 3 times, namely
i = ['O', 'X', 'O'] # pass 1
i = ['X', '',''] # pass 2
i = ['X', '',''] # pass 3
So i is a list. You are then trying to use i to index a list in this statement
result.append(game[i][j])
but lists must be indexed with a single integer (o, 1 or 2), or a slice(like 0:1, 1:2, etc).

Apply this function to a 2D numpy Matrix vector operations only

guys, I have this function
def averageRating(a,b):
avg = (float(a)+float(b))/2
return round(avg/25)*25
Currently, I am looping over my np array which is just a 2D array that has numerical values. What I want to be able to do is have "a" be the 1st array and "b" be the 2nd array and get the average per row and what I want for my return is just an array with the values. I have used mean but could not find a way to edit it and have the round() part or multiple (avg*25)/25.
My goal is to get rid of looping and replace it with a vectorized operations because of how slow looping is.
Sorry for the question new to python and numpy.
def averageRating(a,b):
avg = (np.average(a,axis=1) + np.average(b,axis=1))/2
return np.round(avg,0)
This should do what you are looking for if I understand the question correctly. Specifying axis = 1 in np.average will give the average of the rows (axis = 0 would be the average of the columns). And the 0 in np.round will round to 0 decimal places, changing it will change the number of decimal places you round to. Hope that helps!
def averageRating(a, b):
averages = []
for i in range( len(a) ):
averages.append( (a[i] + b[i]) / 2 )
return averages
Giving your arrays are of equal length this should be a simple resolution.
This doesn't eliminate the use of for loops, however, it will be computationally cheaper than the current approach.

masking a double over a string

This is a question in MatLab...
I have two matrices, one being a (5 x 1 double) :
1
2
3
1
3
And the second matrix being a (5 x 3 string), with spaces where no character appears :
a
bc
def
g
hij
I am trying to get an output such that a (5 x 1 string) is created and outputs the nth value from each line of matrix two, where n is the value in matrix one. I am unsure how to do this using a mask which would be able to handle much larger matrces. My target matrix would have the following :
a
c
f
g
j
Thank you very much for the help!!!
There are so many ways you can accomplish this task. I'll give you two.
Method #1 - Generate linear indices and access elements
Use sub2ind to generate a set of linear indices that correspond to the row and column locations you want to access in your matrix. You'll note that the column locations are the ones changing, but the row locations are always increasing by 1 as you want to access each row. As such, given your string matrix A, and your columns you want to access stored in ind, just do this:
A = ['a '; 'bc '; 'def'; 'g ';'hij'];
ind = [1 2 3 1 3];
out = A(sub2ind(size(A), (1:numel(ind)).', ind(:)))
out =
a
c
f
g
j
Method #2 - Create a sparse matrix, convert to logical and access
Alternatively, you can create a sparse matrix through sparse where the non-zero entries are rows vary from 1 up to as many elements as you have in ind and the columns vary like what you have given us.
S = sparse((1:numel(ind)).',ind(:),true,size(A,1),size(A,2));
A = A.'; out = A(S.');
Be mindful that you are trying to access each element in a row-major fashion, yet MATLAB will do this in a column-major format. As such, we would need to transpose our data matrix, and also take our sparse matrix and transpose that too. The end result should give you the same order as Method #1.

List comprehensions and matrices (raws)

Please, have a look at this constriction:
M = [[1,2,3],
[4,5,6],
[7,8,9]]
T = [row[1] for row in M]
print(T)
The result is [2, 5, 8]
I managed to find something here:
http://docs.python.org/py3k/tutorial/datastructures.html#nested-list-comprehensions
But I'm not satisfied with my understanding of this scheme with 'raw'.
Could you tell me where else in the documentation can I read about it?
By the way, why raw? It seems to be a column?
T = [row[1] for row in M]
This is a list comprehension. List comprehensions basically allow you to create lists on the fly while iterating through other iterables (in this case M).
The code above is more or less identical to this:
T = [] # create empty list that holds the result
for row in M: # iterate through all 'rows' in M
cell = row[1] # get the second cell of the current row
T.append(cell) # append the cell to the list
This is all just put together into a single line and a bit more efficient, but the basic idea is the same.
M is a matrix, but the internal representation you chose is a list of lists; or a list of rows. And in T you want to select a single column of the matrix although you have no direct access to columns in the matrix T. So you basically go through each row, take the cell of the column you are interested in and create a new list with the cells of your columns (as lists are usually horizontally aligned, you are strictly getting the transposed vector of your column).
You iterate through the rows and take second element of the row. Then you collect the extracted elements from the rows. It means that you have extracted the column.
Read the list comprehension from the right to the left. It says:
Loop through the matrix M to get the row each time (for row in M).
Apply the expression to the row to get what you need (here row[1]).
Iterate through the constructed results and build the list of them ([...]).
The last point makes it the list comprehension. The thing between the [ and ] is called a generator expression. You can also try:
column = list(row[1] for row in M)
And you get exactly the same. That is because the list() construct a list from any iterable. And the generator expression is such iterable thing. You can also try:
my_set = set(row[1] for row in M)
to get the set of the elements that form the column. The syntactically brief form is:
my_set = {row[1] for row in M}
and it is called set comprehension. And there can be also a dictionary comprehension like this:
d = { row[1]: True for row in M }
Here rather artificially, the row[1] is used as the key, the True is used as the value.

Resources