def matrixDimensions(m):
""" function that returns the dimensions of a matrix. """
mRowNum= len(m) # this is the number of rows
mColNum=len(m[0])# this is the size of columns in row 1
i=1
j=1
if mRowNum ==1: # if there is only one row , don't need to check for identical columns
return "This is a %ix%i matrix." %(mRowNum,mColNum)
ColNum=len(m[i])# # this is the size of columns in row 2
if mRowNum>1:# this is where you need to check all the columns are identical
while i< mRowNum:
i+=1
if len(m[j])== len(m[0]):
print (i,j,mRowNum,ColNum,m[j],len(m[j]))
j+=1
continue
elif len(m[j])!= len(m[0]):
return 'This is not a valid matrix.'
return "This is a %ix%i matrix." %(mRowNum,mColNum)
there got to be simpler logic, and how do you check for lists nested with, for example I think this is not a valid matrix, but would pass this test.
([ [1,4, 3], [4,0,21],[3,4,[5,7]],[1,2,3],[1,2,3]])
You could try something like this instead:
def are_int(iterable):
return all(isinstance(i, int) for i in iterable)
def matrix_dimensions(matrix):
col = len(matrix[0])
if not all(len(l) == col and are_int(l) for l in matrix):
return 'This is not a valid matrix'
else:
return len(matrix), col
m = [[1,4,3], [4,0,21], [3,4,[5,7]], [1,2,3], [1,2,3]]
l = [[1,4,3], [4,0,21], [3,4,7], [1,2,3], [1,2,3]]
print(matrix_dimensions(m))
print(matrix_dimensions(l))
Output:
This is not a valid matrix
(5, 3)
Related
I have a function to build adjacency matrix. I want to improve matrix readability for humans, so I decided to print row index like this:
Now I want to print column index in the same way, but I can't do it properly. best result I get is this:
Any Ideas and suggestions how i can print column indexes neatly?
Source code here.
def generate_adjacency_matrix(vertices):
# Create empty Matrix
matrix = [['.' for _ in range(len(vertices))] for _ in range(len(vertices))]
# Fill Matrix
for row in range(len(matrix)):
for num in range(len(matrix)):
if num in vertices[row]:
matrix[row][num] = '1'
# Print column numbers
numbers = list(range(len(matrix)))
for i in range(len(numbers)):
numbers[i] = str(numbers[i])
print(' ', numbers)
#Print matrix and row numbers
for i in range(len(matrix)):
if len(str(i)) == 1:
print(str(i) + ' ', matrix[i])
else:
print(i, matrix[i])
If it matters Parameter in my function is a dictionary that looks like:
{0:[1],
1:[0,12,8],
2:[3,8,15]
....
20:[18]
}
If you know you're only going to 20, then just pad everything to 2 chars:
For the header row:
numbers[i] = str(numbers[i].zfill(2))
For the other rows, set to ". " or ".1" or something else that looks neat.
That would seem to be the easiest way.
Alternative way is to have 2 column headers, one above the other, first one is the tens value, second is the unit value. That allows you to keep the width of 1 in the table as well, which maybe you need.
I need to check if the numbers in gradescale is in my NxM matrix as a numpy array, if example the number 8 is in my matrix, I would like to append the number to a empty list and the row number to another list
So how do i check if the number in my matrix isn't in gradescale, i have tried different types of loops, but they dont work.
wrongNumber = []
Rows = []
gradeScale = np.array([-3,0,2,4,7,10,12])
if there is a number i matrix which is not i gradeScale
wrongNumber.append[number]
Rows.append[rownumber]
print("the grade {} in line {} is out of range",format(wrongNumber),
format(Rows))
You can use numpy.ndarray.shape to go through your rows.
for row in range(matrix.shape[0]):
for x in matrix[row]:
if x not in gradeScale:
wrongNumber.append(x)
Rows.append(row)
In addition, you do not use format correctly. Your print statement should be
print("The grade {} in line {} is out of range".format(wrongNumber, Rows))
The following post has some more information on formatting String formatting in Python .
Example
import numpy as np
wrongNumber = []
Rows = []
matrix = np.array([[1,2],[3,4],[5,6],[7,8]])
gradeScale = [1,3,4,5,8]
for row in range(matrix.shape[0]):
for x in matrix[row]:
if x not in gradeScale:
wrongNumber.append(x)
Rows.append(row)
print("The grades {} in lines {} (respectively) are out of range.".format(wrongNumber, Rows))
Output
The grades [2, 6, 7] in lines [0, 2, 3] (respectively) are out of range
Probably a for loop with enumerate() is what you are looking for.
Example:
for rowNumber, number in enumerate(matrix)
if number not in gradeScale:
wrongNumber.append[number]
Rows.append[rowNumber]
I am trying to compare a variable to the values that are stored in an array. The values in the array are extracted out from a csv file. If the values of the array are equal to the variable it will print out true.
import csv
array=[]
values = csv.reader(open('SampleEEG data Insight-1-30.11.15.17.36.16.csv', 'r'),
delimiter=',',
quotechar='|')
for row in values:
array.append(row[5])
number= 4200
for a in array:
if number == a:
print ('True')
print ('False')
The code only compares one value in the array and returns a false. How do I compare all the values in the array to the variable?
Use the all function with list comprehensions
number = 10
array = [1, 2, 3, 4]
print( all(number == a for a in array) )
# False
array = [10, 10, 10, 10]
print( all(number == a for a in array) )
# True
You can use all() - builtin function
all (number == a for a in array)
From what I could figure out from your comment, this is probably what you are looking for:
array=[]
with open('SampleEEG data Insight-1-30.11.15.17.36.16.csv', 'r') as file:
lines = [line.split() for line in file.readlines()]
for line in lines:
try:
array.append(float(line[5]))
except ValueError:
pass
number= 4200
for a in array:
if number == a:
print ('True')
print ('Done, all checked')
Because it is exiting from the loop after it hits the first true value. Use the following code:
for i in array:
if number == i:
print ('True')
else:
print ('False')
t = 8
string = "1 2 3 4 3 3 2 1"
string.replace(" ","")
string2 = [x for x in string]
print string2
for n in range(t-1):
string2.remove(' ')
print string2
def remover(ca):
newca = []
print len(ca)
if len(ca) == 1:
return ca
else:
for i in ca:
newca.append(int(i) - int(min(ca)))
for x in newca:
if x == 0:
newca.remove(0)
print newca
return remover(newca)
print (remover(string2))
It's supposed to be a program that takes in a list of numbers, and for every number in the list it subtracts from it, the min(list). It works fine for the first few iterations but not towards the end. I've added print statements here and there to help out.
EDIT:
t = 8
string = "1 2 3 4 3 3 2 1"
string = string.replace(" ","")
string2 = [x for x in string]
print len(string2)
def remover(ca):
newca = []
if len(ca) == 1: return()
else:
for i in ca:
newca.append(int(i) - int(min(ca)))
while 0 in newca:
newca.remove(0)
print len(newca)
return remover(newca)
print (remover(string2))
for x in newca:
if x == 0:
newca.remove(0)
Iterating over a list and removing things from it at the same time can lead to strange and unexpected behvaior. Try using a while loop instead.
while 0 in newca:
newca.remove(0)
Or a list comprehension:
newca = [item for item in newca if item != 0]
Or create yet another temporary list:
newnewca = []
for x in newca:
if x != 0:
newnewca.append(x)
print newnewca
return remover(newnewca)
(Not a real answer, JFYI:)
Your program can be waaay shorter if you decompose it into proper parts.
def aboveMin(items):
min_value = min(items) # only calculate it once
return differenceWith(min_value, items)
def differenceWith(min_value, items):
result = []
for value in items:
result.append(value - min_value)
return result
The above pattern can, as usual, be replaced with a comprehension:
def differenceWith(min_value, items):
return [value - min_value for value in items]
Try it:
>>> print aboveMin([1, 2, 3, 4, 5])
[0, 1, 2, 3, 4]
Note how no item is ever removed, and that data are generally not mutated at all. This approach helps reason about programs a lot; try it.
So IF I've understood the description of what you expect,
I believe the script below would result in something closer to your goal.
Logic:
split will return an array composed of each "number" provided to raw_input, while even if you used the output of replace, you'd end up with a very long number (you took out the spaces that separated each number from one another), and your actual split of string splits it in single digits number, which does not match your described intent
you should test that each input provided is an integer
as you already do a print in your function, no need for it to return anything
avoid adding zeros to your new array, just test first
string = raw_input()
array = string.split()
intarray = []
for x in array:
try:
intarray.append(int(x))
except:
pass
def remover(arrayofint):
newarray = []
minimum = min(arrayofint)
for i in array:
if i > minimum:
newarray.append(i - minimum)
if len(newarray) > 0:
print newarray
remover(newarray)
remover(intarray)
I have an 2 dimensional array. Each of the row vectors, in this case, is considered a quantity of interest. What I want to do is return all the rows that appear exactly once as one array, and all the rows that appear more than once as a second array.
For example, if the array was:
a=[[1,1,1,0], [1,1,1,0], [5,1,6,0], [3,2,1,0], [4,4,1,0], [5,1,6,0]]
I would like to return two arrays:
nonsingles=[[1,1,1,0], [1,1,1,0], [5,1,6,0], [5,1,6,0]]
singles= [[3,2,1,0], [4,4,1,0]]
It is important that the order stay preserved. The code I have written to do this is as follows:
def singles_nonsingles(array):
#returns the elements that occur only once, and the elements
#that occur more than once in the array
singles=[]
nonsingles=[]
arrayhash=map(tuple, array)
for x in arrayhash:
if (arrayhash.count(x)==1):
singles.append(x)
if (arrayhash.count(x)>1):
nonsingles.append(x)
nonsingles=array(nonsingles)
singles=array(singles)
return {'singles':singles, 'nonsingles':nonsingles}
Now, I am happy to say that this works, but unhappy to say that it is extremely slow, as a typical array i have is 30000(rows)x10 elements/row=300000 elements. Can anyone give me some tips about how to speed this up?? I apologize if this question is very simple, I am new to Python. Also, I am using Numpy/Scipy with Python 2.7, if that is any help.
In Python 2.7 or above, you can use collections.Counter to count the number of occurrences:
def unique_items(iterable):
tuples = map(tuple, iterable)
counts = collections.Counter(tuples)
unique = []
non_unique = []
for t in tuples:
if counts[t] == 1:
unique.append(t)
else:
non_unique.append(t)
return unique, non_unique
I think your problem is that you are doing an in test on a list. This has O(n) performance.
It should be faster to build a dict and then use that to figure out what to do with each row.
EDIT: The code had an unnecessary enumerate() in it; I stripped it out.
from collections import defaultdict
def singles_nonsingles(array):
#returns the elements that occur only once, and the elements
#that occur more than once in the array
singles=[]
nonsingles=[]
d = defaultdict(int)
t = [tuple(row) for row in array]
for row in t:
d[row] += 1
for row in t:
if d[row] == 1:
singles.append(row)
else:
nonsingles.append(row)
return {'singles':singles, 'nonsingles':nonsingles}
Here's a version that only returns unique rows:
from collections import defaultdict
def singles_nonsingles(array):
#returns the elements that occur only once, and the elements
#that occur more than once in the array
singles=[]
nonsingles=[]
d = defaultdict(int)
already_seen = set()
t = [tuple(row) for row in array]
for row in t:
d[row] += 1
for row in t:
if row in already_seen:
continue
if d[row] == 1:
singles.append(row)
else:
nonsingles.append(row)
already_seen.add(row)
return {'singles':singles, 'nonsingles':nonsingles}
a=[[1,1,1,0], [1,1,1,0], [5,1,6,0], [3,2,1,0], [4,4,1,0], [5,1,6,0]]
x = singles_nonsingles(a)
print("Array: " + str(a))
print(x)
The first return only the list of the single/no single arrays without repetitions, the second with repetitions
def comp (multi):
from collections import defaultdict
res = defaultdict(int)
for vect in multi:
res[tuple(vect)] += 1
singles = []
no_singles = []
for k in res:
if res[k] > 1:
no_singles.append(list(k))
elif res[k] == 1:
singles.append(list(k))
return singles, no_singles
def count_w_repetitions(multi):
from collections import defaultdict
res = defaultdict(int)
for vect in multi:
res[tuple(vect)] += 1
singles = []
no_singles = []
for k in res:
if res[k] == 1:
singles.append(list(k))
else:
for i in xrange(res[k]):
no_singles.append(list(k))
return singles, no_singles
from itertools import compress,imap
def has_all_unique(a):
return len(a) == len(frozenset(a))
uniq = map( has_all_unique,a)
singles = list(compress(a,uniq))
notuniq = imap(lambda x: not x,uniq)
nonsingles = list(compress(a,notuniq))