how to program Matrix in Python [closed] - python

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I wanna create matrix like following;
I am still beginner of this language and I need help so badly, thanks
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1

You can create list of lists and print them as you like
matrix = [[0] * 5 for _ in range(5)]
for i in range(5):
matrix[i][i] = 1
print " ".join(str(num) for num in matrix[i])
print matrix
Output
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
[[1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1]]

If you're planning to do any real work with matrices, you should strongly consider looking at NumPy.
Once you get it installed:
>>> import numpy as np
>>> matrix = np.diag([1]*5)
>>> print(matrix)
[[1 0 0 0 0]
[0 1 0 0 0]
[0 0 1 0 0]
[0 0 0 1 0]
[0 0 0 0 1]]
So far, not too exciting. But check this out:
>>> print(matrix * 2)
[[2 0 0 0 0]
[0 2 0 0 0]
[0 0 2 0 0]
[0 0 0 2 0]
[0 0 0 0 2]]
>>> print(matrix + 1)
[[2 1 1 1 1]
[1 2 1 1 1]
[1 1 2 1 1]
[1 1 1 2 1]
>>> print((1 + matrix) * (1 - matrix))
[[0 1 1 1 1]
[1 0 1 1 1]
[1 1 0 1 1]
[1 1 1 0 1]
[1 1 1 1 0]]
>>> print(np.arccos(matrix) / np.pi)
[[ 0. 0.5 0.5 0.5 0.5]
[ 0.5 0. 0.5 0.5 0.5]
[ 0.5 0.5 0. 0.5 0.5]
[ 0.5 0.5 0.5 0. 0.5]
[ 0.5 0.5 0.5 0.5 0. ]]
All that math, and a whole lot more, you don't have to implement yourself. And it's generally at least 10x as fast as if you did implement it yourself. All that, plus fancy indexing (like slicing by row, column, or both), and all kinds of other things you don't yet know you were going to ask for, but will.

My way will be ...
Code::
size = 5
for i in range(size):
for j in range(size):
print 1 if i==j else 0,
print ''
Output:
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
Hope this helps :)

I think this is the most simple. please enjoy it
def fun(N):
return [[0]*x + [1] + [0]*(N-x) for x in range(N)]
print(fun(5))
The result:
[[1, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 1, 0]]

Related

Counting neighbours in conway's game of life using python

Hello guys I am trying to do conway's game of life as a beginner, however I keep getting IndexError: list index out of range, I am not sure why it happens, can you guys help? thank you!
def count_neighbors(x, y, G):
count= 0
n=len(G)
if x>0:
if y>0:
if G[x-1][y-1]=='x':
count +=1
if y<n-1:
if G[x-1][y+1]=='x':
count +=1
if G[x-1][y]=='x':
count +=1
if y>0:
if G[x][y-1]=='x':
count +=1
if y<n-1:
if G[x][y+1] =='x':
count +=1
if x<n-1:
if y>0:
if G[x+1][y-1] =='x':
count +=1
if y<n-1:
if G[x+1][y+1] =='x':
count +=1
if G[x+1][y]=='x':
count +=1
return count
You're not checking if x < n-1 here, and therefore G[x+1] could be out of bounds:
if y<n-1:
if G[x+1][y+1] =='x':
count +=1
if G[x+1][y]=='x':
count +=1
Upon further inspection, it seems that you should just indent this block once, so that it falls under the if x<n-1: check you wrote above.
Your code is also assuming that G is a square matrix (height == width); if this is not the case, then you will also run into issues.
A more generic answer is to use loops:
def count(x,y,G):
counts = 0
for dy in (-1,0,1):
for dx in (-1,0,1):
if not (dx and dy) and x+dx in range(n) and y+dy in range(n) and G[y+dy][x+dx] == 'x':
counts += 1
return counts
Another trick I've used is to have a list of the possible moves:
dirs = (
(-1,-1), ( 0,-1), ( 1,-1),
(-1, 0), ( 1, 0),
(-1, 1), ( 0, 1), ( 1, 1)
)
def count(x,y,G):
counts = 0
for dx,dy in dirs:
if x+dx in range(n) and y+dy in range(n) and G[y+dy][x+dx] == 'x':
counts += 1
return counts
Update: I just realized I have the wrong rule for 4 neighbors! Fixing...
Update #2: Fixed 2 rules.
I have written numerous programs to play Conway's life game in many languages (including assebly language). None of the programs were easy nor short!
Here is a pure numpy solution to Conway's life game that not only computes all neighbor counts in a few lines of code but also goes on to calculate the next generation in a total of only 9 numpy statements.
import numpy as np
# A 5x5 numpy array represents a 3x3 "world" where the outer edge cells
# will always remain equal to 0.
G = np.array([[0, 0, 0, 0, 0],
[0, 1, 1, 1, 0],
[0, 0, 1, 0, 0],
[0, 1, 0, 1, 0],
[0, 0, 0, 0, 0]])
print('G ---------- Original generation')
print(G)
# Create array S (sum) where each element is the sum of the 3x3 cell surrounding
# the same element in the G array.
S = np.zeros_like(G)
S[1:-1, 1:-1] = sum(G[i:G.shape[0]-2+i, j:G.shape[1]-2+j]
for i in range(0, 3) for j in range(0, 3))
print('S ---------- Provisional neighbor counts')
print(S)
# Since the sums in S include the center cell we subtract the extra values by
# subtracting G from S!
X = np.subtract(S, G)
print('X ---------- Adjusted neighbor counts')
print(X)
# Apply Conway's rules of life
X[((X == 1) | (X > 3)) & (G == 1)] = -1 # Death
X[((X == 1) | (X > 3)) & (G == 0)] = 0 # No change if G is already equal to 0
X[X == 2] = 0 # Survival
X[(X == 3) & (G == 1)] = 0 # No change if G is already equal to 1
X[(X == 3) & (G == 0)] = +1 # Birth otherwise!
print('X ---------- Changes for the next generation')
print(X)
# Apply the calculated changes from X to G
G = np.add(G, X)
print('G ---------- Tada!!! The next generation')
print(G)
Output:
G ---------- Original generation
[[0 0 0 0 0]
[0 1 1 1 0]
[0 0 1 0 0]
[0 1 0 1 0]
[0 0 0 0 0]]
S ---------- Provisional neighbor counts
[[0 0 0 0 0]
[0 3 4 3 0]
[0 4 6 4 0]
[0 2 3 2 0]
[0 0 0 0 0]]
X ---------- Adjusted neighbor counts
[[0 0 0 0 0]
[0 2 3 2 0]
[0 4 5 4 0]
[0 1 3 1 0]
[0 0 0 0 0]]
X ---------- Changes for the next generation
[[ 0 0 0 0 0]
[ 0 0 0 0 0]
[ 0 0 -1 0 0]
[ 0 -1 1 -1 0]
[ 0 0 0 0 0]]
G ---------- Tada!!! The next generation
[[0 0 0 0 0]
[0 1 1 1 0]
[0 0 0 0 0]
[0 0 1 0 0]
[0 0 0 0 0]]

How do you convert a matrix into a string? [duplicate]

This question already has answers here:
Printing 2D-array in a grid
(6 answers)
Closed 1 year ago.
let's say I have this matrix: m = [[0 for i in range(5)] for i in range(5)],
which when printed, outputs this:
[[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]]
How do I make it so that it outputs something like this:
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
You can simply unpack the list
m = [[0 for i in range(5)] for i in range(5)]
for i in m:
print(*i)
Output:
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
You can use the below where m is your matrix and can control the spacing in the ' '.join()
for line in m:
print (' '.join(map(str, line)))

get non zero ROI from numpy array

I want to extract a rectangular ROI from an image.
The image contains a single connected non zero part.
I need it to be efficient in run time.
I was thinking maybe:
Summing along each direction.
Finding first non zero and last non zero.
Slicing the image accordingly.
Is there a better way?
My code:
First is a function to find the first and last non zero:
import numpy as np
from PIL import Image
def first_last_nonzero(boolean_vector):
first = last = -1
for idx,val in enumerate(boolean_vector):
if val == True and first == -1:
first = idx
if val == False and first != -1:
last = idx
return first , last
Then creating an image:
np_im = np.array([[ 0 0 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 255 154 251 60 0 0 0]
[ 0 0 0 0 4 66 0 0 255 0 0 0]
[ 0 0 0 0 0 0 0 134 48 0 0 0]
[ 0 0 0 0 0 0 236 70 0 0 0 0]
[ 0 0 0 0 1 255 0 0 0 0 0 0]
[ 0 0 0 0 255 24 24 24 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0]])
Then running our function on the sum along each axis:
y_start, y_end = first_last_nonzero(np.sum(np_im, 1)>0)
x_start, x_end = first_last_nonzero(np.sum(np_im, 0)>0)
cropped_np_im = np_im[y_start:y_end, x_start:x_end]
# show the cropped image
Image.fromarray(cropped_np_im).show()
This works but there are probably a plenty of unnecessary calculations.
Is there a better way to do this? Or maybe more pythonic way?
You can make use of the functions from this post:
Numpy: How to find first non-zero value in every column of a numpy array?
def first_nonzero(arr, axis, invalid_val=-1):
mask = arr!=0
return np.where(mask.any(axis=axis), mask.argmax(axis=axis), invalid_val)
def last_nonzero(arr, axis, invalid_val=-1):
mask = arr!=0
val = arr.shape[axis] - np.flip(mask, axis=axis).argmax(axis=axis) - 1
return np.where(mask.any(axis=axis), val, invalid_val)
arr = np.array([
[0, 0, 0, 0, 1, 1],
[0, 0, 1, 1, 0, 0],
[0, 1, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0],
[0, 0, 1, 0, 1, 0],
[0, 0, 0, 0, 0, 0] ])
y_Min, y_Max, x_Min, x_Max = (0, 0, 0, 0)
y_Min = first_nonzero(arr, axis = 0, invalid_val = -1)
y_Min = (y_Min[y_Min >= 0]).min()
x_Min = first_nonzero(arr, axis = 1, invalid_val = -1)
x_Min = (x_Min[x_Min >= 0]).min()
y_Max = last_nonzero(arr, axis = 0, invalid_val = -1)
y_Max = (y_Max[y_Max >= 0]).max()
x_Max = last_nonzero(arr, axis = 1, invalid_val = -1)
x_Max = (x_Max[x_Max >= 0]).max()
print(x_Min)
print(y_Min)
print(x_Max)
print(y_Max)
For this example of mine, the code will return 1, 0, 5, 4.
As a general rule of thumb in python: Try to avoid loops at all costs. From my own experience that statement is true in 99 out of 100 cases

How to find longest consecutive ocurrence of non-zero elements in 2D numpy array

I am simulating protein folding on a 2D grid where every angle is either ±90° or 0°, and have the following problem:
I have an n-by-n numpy array filled with zeros, except for certain places where the value is any integer from 1 to n. Every integer appears just once. Integer k is always a nearest neighbour to k-1 and k + 1, except for the endpoints. The array is saved as an object in the class Grid which I have created for doing energy calculations and folding the protein. Example array, with n=5:
>>> from Grid import Grid
>>> a = Grid(5)
>>> a.show()
[[0 0 0 0 0]
[0 0 0 0 0]
[1 2 3 4 5]
[0 0 0 0 0]
[0 0 0 0 0]]
My goal is to find the longest consecutive line of non-zero elements withouth any bends. In the above case, the result should be 5.
My idea so far are something like this:
def getDiameter(self):
indexes = np.zeros((self.n, 2))
for i in range(1, self.n + 1):
indexes[i - 1] = np.argwhere(self.array == i)[0]
for i in range(self.n):
j = 1
currentDiameter = 1
while indexes[0][i] == indexes[0][i + j] and i + j <= self.n:
currentDiameter += 1
j += 1
while indexes[i][0] == indexes[i + j][0] and i + j <= self.n:
currentDiameter += 1
j += 1
if currentDiameter > diameter:
diameter = currentDiameter
return diameter
This has two problems: (1) it doesn't work, and (2) it is horribly inefficient if I get it to work. I am wondering if anybody has a better way of doing this. If anything is unclear, please let me know.
Edit:
Less trivial example
[[ 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 10 0 0 0]
[ 0 0 0 0 0 0 9 0 0 0]
[ 0 0 0 0 0 0 8 0 0 0]
[ 0 0 0 4 5 6 7 0 0 0]
[ 0 0 0 3 0 0 0 0 0 0]
[ 0 0 0 2 1 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0]]
The correct answer here is 4 (both the longest column and the longest row have four non-zero elements).
What I understood from your question is you need to find the length of longest occurance of consecutive elements in numpy array (row by row).
So for this below one, the output should be 5:
[[1 2 3 4 0]
[0 0 0 0 0]
[10 11 12 13 14]
[0 1 2 3 0]
[1 0 0 0 0]]
Because [10 11 12 13 14] are consecutive elements and they have the longest length comparing to any consecutive elements in any other row.
If this is what you are expecting, consider this:
import numpy as np
from itertools import groupby
a = np.array([[1, 2, 3, 4, 0],
[0, 0, 0, 0, 0],
[10, 11, 12, 13, 14],
[0, 1, 2, 3, 0],
[1, 0, 0, 0, 0]])
a = a.astype(float)
a[a == 0] = np.nan
b = np.diff(a) # Calculate the n-th discrete difference. Consecutive numbers will have a difference of 1.
counter = []
for line in b: # for each row.
if 1 in line: # consecutive elements differ by 1.
counter.append(max(sum(1 for _ in g) for k, g in groupby(line) if k == 1) + 1) # find the longest length of consecutive 1's for each row.
print(max(counter)) # find the max of list holding the longest length of consecutive 1's for each row.
# 5
For your particular example:
[[0 0 0 0 0]
[0 0 0 0 0]
[1 2 3 4 5]
[0 0 0 0 0]
[0 0 0 0 0]]
# 5
Start by finding the longest consecutive occurrence in a list:
def find_longest(l):
counter = 0
counters =[]
for i in l:
if i == 0:
counters.append(counter)
counter = 0
else:
counter += 1
counters.append(counter)
return max(counters)
now you can apply this function to each row and each column of the array, and find the maximum:
longest_occurrences = [find_longest(row) for row in a] + [find_longest(col) for col in a.T]
longest_occurrence = max(longest_occurrences)

outputting large matrix in python from a dictionary

I have a python dictionary formatted in the following way:
data[author1][author2] = 1
This dictionary contains an entry for every possible author pair (all pairs of 8500 authors), and I need to output a matrix that looks like this for all author pairs:
"auth1" "auth2" "auth3" "auth4" ...
"auth1" 0 1 0 3
"auth2" 1 0 2 0
"auth3" 0 2 0 1
"auth4" 3 0 1 0
...
I have tried the following method:
x = numpy.array([[data[author1][author2] for author2 in sorted(data[author1])] for author1 in sorted(data)])
print x
outf.write(x)
However, printing this leaves me with this:
[[0 0 0 ..., 0 0 0]
[0 0 0 ..., 0 0 0]
[0 0 0 ..., 0 0 0]
...,
[0 0 0 ..., 0 0 0]
[0 0 0 ..., 0 0 0]
[0 0 0 ..., 0 0 0]]
and the output file is just a blank text file. I am trying to format the output in a way to read into Gephi (https://gephi.org/users/supported-graph-formats/csv-format/)
You almost got it right, your list comprehension is inverted. This will give you the expected result:
d = dict(auth1=dict(auth1=0, auth2=1, auth3=0, auth4=3),
auth2=dict(auth1=1, auth2=0, auth3=2, auth4=0),
auth3=dict(auth1=0, auth2=2, auth3=0, auth4=1),
auth4=dict(auth1=3, auth2=0, auth3=1, auth4=0))
np.array([[d[i][j] for i in sorted(d.keys())] for j in sorted(d[k].keys())])
#array([[0, 1, 0, 3],
# [1, 0, 2, 0],
# [0, 2, 0, 1],
# [3, 0, 1, 0]])
You could use pandas. Using #Saullo Castro input:
import pandas as pd
df = pd.DataFrame.from_dict(d)
Result:
>>> df
auth1 auth2 auth3 auth4
auth1 0 1 0 3
auth2 1 0 2 0
auth3 0 2 0 1
auth4 3 0 1 0
And if you want to save you can just do df.to_csv(file_name)

Categories

Resources