'numpy.ndarray' object has no attribute 'D' - python

import numpy as np
rowlist = np.array([[0, 2, 3, 4, 5], [0, 0, 0, 3, 2], [1, 2, 3, 4, 5], [0, 0, 0, 6, 7], [0, 0, 0, 9, 9]])
new_rowlist = []
rows_left = set(range(len(rowlist)))
col_label_list = sorted(rowlist[0].D, key=hash)
for c in col_label_list:
rows_with_non_zero = [ r for r in rows_left if rowlist[r][c] != 0 ]
if rows_with_non_zero != []:
pivot = rows_with_non_zero[0]
new_rowlist.append(rowlist[pivot])
rows_left.remove(pivot)
for r in new_rowlist:
print(r)
So i'm following the Coding the Matrix by Philip Klein book lessons and on one of the chapter on Gaussian Elimination, this keeps erroring 'numpy.ndarray' object has no attribute 'D'
What I wanted was to be able to sort the matrix called rowlist. Any idea how to overcome this ? im doing this on jupyter notebook if it is of any help
Thanks in advance!

There is a typo. There is no rowlist[0].D, change the line to the following
col_label_list = sorted(rowlist[0], key=hash)
Also, maybe from next time as a learning process, try and debug a code yourself by locating which line is causing the error (if you read the error message properly).

Related

lists and for loop syntax

so I'm a beginner programmer and I'm trying to build a python program to print the Fibonacci sequence.
my code is as follows:
fib_sequence = [0,1,1]
def fib_add(x):
fib_seq.insert(x, int(fibseq[x-1]+fibseq[x-2])
for n in range(2,10):
fib_add(n)
print(fib_seq)
the program says there is a syntax error at the colon on
for n in range(2,10):
I don't know how to correct it
Interestingly, that is not where the syntax error is. It is the preceding line that is the problem:
fib_seq.insert(x, int(fibseq[x-1]+fibseq[x-2]))
This line was missing closing parentheses. What happens in such cases is that, since the parentheses were not closed, the Python interpreter continues looking for more stuff to put in the expression. It hits the for in the next line and continues all the way to right before the colon. At this point, there is a way to continue the code which is still valid.
Then, it hits the colon. There is no valid Python syntax which allows a colon there, so it stops and raises an error at the first token which is objectively in the wrong place. In terms of your intention, however, we can see that the mistake was actually made earlier.
Also, as noted in a comment, your original list was named fib_sequence, while in the rest of your code you reference fib_list. This will raise a NameError.
You have to place your for loop code inside main. Also as the other answer suggests, you must add another parenthesis after
fib_seq.insert(x, int(fibseq[x-1]+fibseq[x-2]))
if __name__ == '__main__':
for n in range(2,10):
fib_add(n)
print(fib_seq)
While you have some useful answers, you might look into generators, they make Python a powerful language:
def fibonacci():
x, y = 0, 1
while True:
yield x
x, y = y, x + y
for x in fibonacci():
if x >= 10:
break
print(x)
This prints
0
1
1
2
3
5
8
Here is the corrected code:
fib_seq = [0,1,1]
def fib_add(x):
fib_seq.insert(x, int(fib_seq[x-1]+fib_seq[x-2]))
for n in range(3,10):
fib_add(n)
print(fib_seq)
Resulting Output:
[0, 1, 1, 2]
[0, 1, 1, 2, 3]
[0, 1, 1, 2, 3, 5]
[0, 1, 1, 2, 3, 5, 8]
[0, 1, 1, 2, 3, 5, 8, 13]
[0, 1, 1, 2, 3, 5, 8, 13, 21]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

Reading a text document containing python list into a python program

I have a text file(dummy.txt) which reads as below:
['abc',1,1,3,3,0,0]
['sdf',3,2,5,1,3,1]
['xyz',0,3,4,1,1,1]
I expect this to be in lists in python as below:
article1 = ['abc',1,1,3,3,0,0]
article2 = ['sdf',3,2,5,1,3,1]
article3 = ['xyz',0,3,4,1,1,1]
That many articles have to be created as many lines present in dummy.txt
I was trying the following things:
Opened the file, split it by '\n' and appended it to an empty list in python, it had extra quotes and square brackets hence tried to use 'ast.literal_eval' which did not work as well.
my_list = []
fvt = open("dummy.txt","r")
for line in fvt.read():
my_list.append(line.split('\n'))
my_list = ast.literal_eval(my_list)
I also tried to manually remove additional quotes and extra square brackets using replace, that did not help me either. Any leads much appreciated.
This should help.
import ast
myLists = []
with open(filename) as infile:
for line in infile: #Iterate Each line
myLists.append(ast.literal_eval(line)) #Convert to python object and append.
print(myLists)
Output:
[['abc', 1, 1, 3, 3, 0, 0], ['sdf', 3, 2, 5, 1, 3, 1], ['xyz', 0, 3, 4, 1, 1, 1]]
fvt.read() will produce the entire file string, so that means line will contain a single character string. So this will not work very well, you also use literal_eval(..) with the entire list of strings, and not a single string.
You can obtain the results by iterating over the file handler, and each time call literal_eval(..) on a single line:
from ast import literal_eval
with open("dummy.txt","r") as f:
my_list = [literal_eval(line) for line in f]
or by using map:
from ast import literal_eval
with open("dummy.txt","r") as f:
my_list = list(map(literal_eval, f))
We then obtain:
>>> my_list
[['abc', 1, 1, 3, 3, 0, 0], ['sdf', 3, 2, 5, 1, 3, 1], ['xyz', 0, 3, 4, 1, 1, 1]]
ast.literal_eval is the right approach. Note that creating a variable number of variables like article1, article2, ... is not a good idea. Use a dictionary instead if your names are meaningful, a list otherwise.
As Willem mentioned in his answer fvt.read() will give you the whole file as one string. It is much easier to exploit the fact that files are iterable line-by-line. Keep the for loop, but get rid of the call to read.
Additionally,
my_list = ast.literal_eval(my_list)
is problematic because a) you evaluate the wrong data structure - you want to evaluate the line, not the list my_list to which you append and b) because you reassign the name my_list, at this point the old my_list is gone.
Consider the following demo. (Replace fake_file with the actual file you are opening.)
>>> from io import StringIO
>>> from ast import literal_eval
>>>
>>> fake_file = StringIO('''['abc',1,1,3,3,0,0]
... ['sdf',3,2,5,1,3,1]
... ['xyz',0,3,4,1,1,1]''')
>>> result = [literal_eval(line) for line in fake_file]
>>> result
[['abc', 1, 1, 3, 3, 0, 0], ['sdf', 3, 2, 5, 1, 3, 1], ['xyz', 0, 3, 4, 1, 1, 1]]
Of course, you could also use a dictionary to hold the evaluated lines:
>>> result = {'article{}'.format(i):literal_eval(line) for i, line in enumerate(fake_file, 1)}
>>> result
{'article2': ['sdf', 3, 2, 5, 1, 3, 1], 'article1': ['abc', 1, 1, 3, 3, 0, 0], 'article3': ['xyz', 0, 3, 4, 1, 1, 1]}
where now you can issue
>>> result['article2']
['sdf', 3, 2, 5, 1, 3, 1]
... but as these names are not very meaningful, I'd just go for the list instead which you can index with 0, 1, 2, ...
When I do this:
import ast
x = '[ "A", 1]'
x = ast.literal_eval(x)
print(x)
I get:
["A", 1]
So, your code should be:
for line in fvt.read():
my_list.append(ast.literal_eval(line))
Try this split (no imports needed) (i recommend):
with open('dummy.txt','r') as f:
l=[i[1:-1].strip().replace("'",'').split(',') for i in f]
Now:
print(l)
Is:
[['abc', 1, 1, 3, 3, 0, 0], ['sdf', 3, 2, 5, 1, 3, 1], ['xyz', 0, 3, 4, 1, 1, 1]]
As expected!!!

Python: Dictionary to Spare Vector

I am new to Python and programming in general. I was working on Pyschool exercises Topic 8, Q 11 on converting Dictionary to Spare Vectore.
I was asked to Write a function that converts a dictionary back to its sparese vector representation.
Examples
>>> convertDictionary({0: 1, 3: 2, 7: 3, 12: 4})
[1, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 4]
>>> convertDictionary({0: 1, 2: 1, 4: 2, 6: 1, 9: 1})
[1, 0, 1, 0, 2, 0, 1, 0, 0, 1]
>>> convertDictionary({})
[]
I have attempted many times. Below is the latest code I have:
def convertDictionary(dictionary):
k=dictionary.keys()
v=dictionary.values()
result=[]
for i in range(0,max(k)):
result.append(0)
for j in k:
result[j]=v[k.index(j)]
return result
The returned error is:
Traceback (most recent call last):
File "Code", line 8, in convertDictionary
IndexError: list assignment index out of range
Could anyone help me? Thank you so much!
Something like this should suffice:
M = max(dictionary, default=0)
vector = [dictionary.get(i, 0) for i in range(M)]
Translated into a plain old for-loop
M = max(dictionary, default=0)
vector = []
for i in range(M):
vector.append(dictionary.get(i, 0))
The get method lets you provide a default as a second argument in case the key is missing. Once you get more advance you could use a defaultdict
Edit: the default parameter for max requires Python >3.4 . You can either use exception handling (generally prefered) or explicit checks for empty dictionary to deal with that case if you have earlier versions.
Your code works logically fine, but you have a problem of indentation. Your function should be:
def convertDictionary(dictionary):
k=dictionary.keys()
v=dictionary.values()
result=[]
for i in range(0,max(k)):
result.append(0)
for j in k:
result[j]=v[k.index(j)]
return result
The problem is that your second for was inside of the first. What you want is to build a list with max(k) elements and then put the right values into it. Then, the two for loops should be one after the other, rather than one inside of the other.

How to print numpy objects without line breaks

I am logging input arguments to a function using
logging.debug('Input to this function = %s',
inspect.getargvalues(inspect.currentframe())[3])
But I do not want the line breaks inserted within numpy objects. numpy.set_printoptions(linewidth=np.nan) removes some, but line breaks are still inserted in 2D objects such as
array([[ 0.84148239, 0.71467895, 0.00946744, 0.3471317 ],
[ 0.68041249, 0.20310698, 0.89486761, 0.97799646],
[ 0.22328803, 0.32401271, 0.96479887, 0.43404245]])
I want it to be like this:
array([[ 0.84148239, 0.71467895, 0.00946744, 0.3471317 ], [ 0.68041249, 0.20310698, 0.89486761, 0.97799646], [ 0.22328803, 0.32401271, 0.96479887, 0.43404245]])
How can I do this? Thanks.
Given an array x, you can print it without line breaks with,
import numpy as np
x_str = np.array_repr(x).replace('\n', '')
print(x_str)
or alternatively using the function np.array2string instead of np.array_repr.
I'm not sure if there is an easy way to remove newlines from the string representation or numpy arrays. However, it is always possible to remove them after the conversion took place,
input_args = inspect.getargvalues(inspect.currentframe())[3]
logging.debug('Input to this function = %s', repr(input_args).replace('\n', ''))
import numpy as np
np.set_printoptions(threshold=np.inf)
np.set_printoptions(linewidth=np.inf)
# Testing:
big_arr = np.ones([30,70])
print(big_arr)
Simple solution
import numpy as np
value = np.array([[1, 2, 3, 4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7, 8], [1, 2, 3, 7, 8]])
value_str = str(value).replace('\n', '')
print("prints: " + value_str)
# prints: [[1, 2, 3, 4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7, 8], [1, 2, 3, 7, 8]]
This solution also works:
myArray = np.array([[ 0.84148239, 0.71467895, 0.00946744, 0.3471317 ],
[ 0.68041249, 0.20310698, 0.89486761, 0.97799646],
[ 0.22328803, 0.32401271, 0.96479887, 0.43404245]])
print(np.array2string(myArray).replace('\n','').replace(' ',', '))
Output:
[[0.84148239, 0.71467895, 0.00946744, 0.3471317, ], [0.68041249, 0.20310698, 0.89486761, 0.97799646], [0.22328803, 0.32401271, 0.96479887, 0.43404245]]

Reading a list of lists into Python

I have made a list of lists to store score data for a given student. The list is called "class1" and each student has a name followed by 3 scores. I can sort this list fine and can write to a file which show the data in the correct format:
class1=[["Tom",7,2,1],["Jo",8,0,0],["Adelphe",9,0,0]]
When written look like this which I am happy with:
['Tom', 7, 2, 1]
['Jo', 8, 0, 0]
['Adelphe', 9, 0, 0]
The problem comes when I try to read the same list in. Each sublist is read as a string. I can't seem to change this.
Here is the code:
class1 = [line.strip() for line in open("data2.txt", 'r')]
This is what the list looks like when read, as you can see there are apostrophes around each sub list, meaning they are strings within the class1 list:
["['Tom', 7, 2, 1]", "['Jo', 8, 0, 0]", "['Adelphe', 9, 0, 0]"]
Can anyone help me, I've done a lot of searching, but can't find anyone with the same problem.
Thanks, Tom
>>> import ast
>>> with open('/path/to/data2.txt', 'r') as classes:
lines = [ast.literal_eval(line.strip()) for line in classes]
>>> print lines
[['Tom', 7, 2, 1], ['Jo', 8, 0, 0], ['Adelphe', 9, 0, 0]]

Categories