Bi-dimensional arrays in Python - python

I have a vector with int values like:
v=[10,8,6]
and what I want is to create an m*m matrix that stores the distance between these elements, i.e. take each element of the vector and substract it from all the other ones, so at the end I will end up with:
m[3][3]=10-10 10-8 10-6
8-10 8-8 8-6
6-10 6-8 6-6
I want to implement it into Python, but without using NumPy. I have done this so far:
def main():
v=[10,8,6]
l=len(v)
m=[]
#filling the matrix
for i in range(0,l-1):
for j in range(0,l-1):
m[i][j]=abs(v[i]-v[j])
#visualize the matrix
for i in range(0,l-1):
for j in range(0,l-1):
print m[i][j]
But I am getting some error that does not recognize with the bounds of m. Why is that?

v= [10,8,6]
m = [[abs(y-x) for y in v] for x in v]
EDIT:
For pretty printing you can use something like:
for i in m:
print '%s '*len(i) % tuple(i)

You need to make a list for each row inside of the enveloping list. I used a double list comprehension to make m and then made the formatting a little prettier for printing out the matrix. Also, watch your indices: remember that range goes from the first index to one minus the second index passed to it. You could also do print ' '.join(row) for each row in m to print it out nicely.
def main():
v=[10,8,6]
l=len(v)
#filling the matrix
m=[[abs(x - y) for y in v] for x in v]
#visualize the matrix
for i in range(0,l):
for j in range(0,l):
print m[i][j],
print
main()
result:
0 2 4
2 0 2
4 2 0

Your list starts out empty. You can't index the element in the list. One way to solve this would be to create the lists and then append them.
m=[]
#filling the matrix
for i in range(0,l-1):
x = []
for j in range(0,l-1):
x.append( abs(v[i]-v[j]) )
m.append(x)
Or you could create the matrix and then fill it up
m=[[0] *l for x in range(l)]
#filling the matrix
for i in range(0,l-1):
for j in range(0,l-1):
m[i][j]=abs(v[i]-v[j])
better yet is the list comprehension other have shown
m = [[abs(y-x) for y in v] for x in v]
but then, I'd use numpy/scipy
m = scipy.spatial.distance.pdist(v)

You need to initialize each object in the first dimension as an array, otherwise it's like you're basically trying to index on None.
#filling the matrix
for i in range(0,l-1):
m[i] = []
for j in range(0,l-1):
m[i][j]=abs(v[i]-v[j])

Related

Iterating through multiple variables while performing a calculation and saving result? List comprehension, enumerate() - Python

I have a range of temperatures ('T') (0 - 100 inclusive) and a range of humidities ('RH') (0-1.00 inclusive) so 101 values in each list.
For each step through temp I would like to run a calculation for the range of humidities, so at T=0 I calculate for every RH in the list and save the results of each calculation (returns an np.array), then at T=1 repeat calc for entire range of RH again and save each result and so on...
I am using list comprehension to iterate over the two lists:
ray2 = np.zeros(np.size(T)*np.size(RH))
ray18 = np.zeros(np.size(T)*np.size(RH))
for x,y in [(x,y) for x in T for y in RH]:
ray2, ray18 = rayleigh(T[x], RH[y], f, del2, del18)
I cannot figure out how to incorporate a counter into the list comprehension to save all 10201 results as an array.
I think you need to create n by m zeros matrix, then save all the data to it
ray2 = np.zeros((np.size(T), np.size(RH)))
ray18 = np.zeros((np.size(T), np.size(RH)))
for idx, t_ele in enumerate(T):
for idx_rh, rh_ele in enumerate(RH):
ray2[idx][idx_rh], ray18[idx][idx_rh] = rayleigh(t_ele , rh_ele , f, del2, del18)
If you want ray2 and ray18 to remain as one-dimensional arrays, then you can address them using the method seen here: Treating a 1D data structure as 2D grid.
The code for this follows:
EDIT: After clarification I have adjusted the code.
ray2 = np.zeros(np.size(T)*np.size(RH))
ray18 = np.zeros(np.size(T)*np.size(RH))
for i, t in enumerate(T):
for j, rh in enumerate(RH):
index = i*np.size(RH) + j
ray2[index], ray18[index] = rayleigh(t, rh, f, del2, del18)
However, if you are okay with using matrices, then you should probably use the solution posted by #galaxyan.

which would be the most time efficient way to perform these nested loops?

for i in range(x):
for j in range(y):
for k in range(z):
if arr[i][j][k] != 0:
arr[i][j][k] = 1
I'm traversing through a 3D array and if any value is not equal to 1, I would like to change it to 1.
If you use numpy, just write:
arr[arr!=0] = 1
or if you only need a boolean array:
result = arr!=0
If you, on the other side, have a list of list of lists:
for plane in arr:
for row in plane:
row[:] = [int(item!=0) for item in row]

Strange bevahiour of Python when adding up all elements in a matrix

I have an empty matrix in Python 2.7:
self.board = {}
N = 2
for i in range(N):
for j in range(N):
self.board[i, j] = 0
Now I want to add up all elements of the matrix. So I googled how to do it:
print sum(map(sum, self.board))
How would I sum a multi-dimensional array in the most succinct python?
Suprisingly, it prints out 4 - the sum of all indexes. Why is that? How can I sum the elements correctly?

Python 3: Multiply a vector by a matrix without NumPy

I'm fairly new to Python and trying to create a function to multiply a vector by a matrix (of any column size).
e.g.:
multiply([1,0,0,1,0,0], [[0,1],[1,1],[1,0],[1,0],[1,1],[0,1]])
[1, 1]
Here is my code:
def multiply(v, G):
result = []
total = 0
for i in range(len(G)):
r = G[i]
for j in range(len(v)):
total += r[j] * v[j]
result.append(total)
return result
The problem is that when I try to select the first row of each column in the matrix (r[j]) the error 'list index out of range' is shown. Is there any other way of completing the multiplication without using NumPy?
The Numpythonic approach: (using numpy.dot in order to get the dot product of two matrices)
In [1]: import numpy as np
In [3]: np.dot([1,0,0,1,0,0], [[0,1],[1,1],[1,0],[1,0],[1,1],[0,1]])
Out[3]: array([1, 1])
The Pythonic approach:
The length of your second for loop is len(v) and you attempt to indexing v based on that so you got index Error . As a more pythonic way you can use zip function to get the columns of a list then use starmap and mul within a list comprehension:
In [13]: first,second=[1,0,0,1,0,0], [[0,1],[1,1],[1,0],[1,0],[1,1],[0,1]]
In [14]: from itertools import starmap
In [15]: from operator import mul
In [16]: [sum(starmap(mul, zip(first, col))) for col in zip(*second)]
Out[16]: [1, 1]
I think the problem with your code was that you loop through the rows of the matrix rather than by the columns. Also you don't reset your 'total' variable after each vector*matrix column calculation. This is what you want:
def multiply(v, G):
result = []
for i in range(len(G[0])): #this loops through columns of the matrix
total = 0
for j in range(len(v)): #this loops through vector coordinates & rows of matrix
total += v[j] * G[j][i]
result.append(total)
return result
i have attached a code for matrix multiplication do follow the example format for one dimensional multiplication (lists of list)
def MM(a,b):
c = []
for i in range(0,len(a)):
temp=[]
for j in range(0,len(b[0])):
s = 0
for k in range(0,len(a[0])):
s += a[i][k]*b[k][j]
temp.append(s)
c.append(temp)
return c
a=[[1,2]]
b=[[1],[2]]
print(MM(a,b))
result is [[5]]
r is an element from G so it's a row which only has two elements. That means you can't use index j to get a value from r because j goes from 0 till the length of v, which is 6 in your example.
I needed solution where the first matrix could be 2-dimensional. Extending the solution from #Kasramvd to accept a two dimensional first matrix. Posted here for reference:
>>> first,second=[[1,0,0,1,0,0],[0,1,1,1,0,0]], [[0,1],[1,1],[1,0],[1,0],[1,1],[0,1]]
>>> from itertools import starmap
>>> from operator import mul
>>> [[sum(starmap(mul, zip(row, col))) for col in zip(*second)] for row in first]
[[1, 1], [3, 1]]
# check matrices
A = [[1,2],[3,4]]
B = [[1,4],[5,6],[7,8],[9,6]]
def custom_mm(A,B):
if len(A[0]) == len(B): -- condition to check if matrix multiplication is valid or not. Making sure matrix is nXm and mXy
result = [] -- final matrix
for i in range(0,len(A)): -- loop through each row of first matrix
temp = [] -- temporary list to hold output of each row of the output matrix where number of elements will be column of second matrix
for j in range(0,len(B[0])): -- loop through each column of second matrix
total = 0
l = 0 -- dummy index to switch row of second matrix
for k in range(0,len(A[0])):
total += A[i][k]*B[l][j]
l = l+1
temp.append(total)
result.append(temp)
return result
else:
return (print("not possible"))
print(custom_mm(A,B))
There is a code that help u to multiply two matrix:
A=[[1,2,3],[4,5,6],[7,8,9]]
B=[[1,2,3],[4,5,6],[7,8,9]]
matrix=[]
def multiplicationLineColumn(line,column):
try:
sizeLine=len(line)
sizeColumn=len(column)
if(sizeLine!=sizeColumn):
raise ValueError("Exception")
res = sum([line[i] * column[i] for i in range(sizeLine)])
return res
except ValueError:
print("sould have the same len line & column")
def getColumn(matrix,numColumn):
size=len(matrix)
column= [matrix[i][numColumn] for i in range(size)]
return column
def getLine(matrix,numLine):
line = matrix[numLine]
return line
for i in range(len(A)):
matrix.append([])
for j in range(len(B)):
matrix[i].append(multiplicationLineColumn(getLine(A,i),getColumn(B,j)))
print(matrix)

Fill a matrix with an array

I have some code of which I obtain an array of different values within a double for loop. I assign it to a list test
and I want to set them one by one on this matrix of 8 x 8
I have tried:
for i in range(8):
for j in range(8):
matrixc[i][j] = testi[i]
I want to have a different value on each tuple. How can I advance through the list on each iteration?
Is this what you are looking for?
for i in range(8):
for j in range(8):
matrixc[i][j] = testi[i*8 + j]
Alternatively:
for index, element in enumerate(testi):
matrixc[index / 8][index % 8] = element
If you're pulling from a linear array then you could access it using array[i*8 + j] instead of array[i]

Categories

Resources