List elements less than tolerance in Python - python

I have a list Test containing numpy arrays. I want to see if each array element is less than the tol value. If it is less, it should return empty list. But I am getting an error. I present the expected output.
import numpy as np
tol=1e-12
Test=[[np.array([9.75016872e-15])], [np.array([9.75016872e-15]), np.array([0.00019793]), np.array([0.0001007])]]
for i in range(0,len(Test)):
for j in range(0,len(Test[i])):
if (Test[j][i]<tol):
Test[j][i]=[]
else:
Test=Test[j][i]
print(Test)
The error is
in <module>
if (CB[j][i]<tol):
IndexError: list index out of range
The expected output is
[[[]], [[], array([0.00019793]), array([0.0001007])]]

What about a list comprehension?
out = [[[] if (a<tol).all() else a for a in l] for l in Test]
# [[[]], [[], array([0.00019793]), array([0.0001007])]]
Fix of your code:
for i in range(len(Test)):
for j in range(len(Test[i])):
if Test[i][j] < tol:
Test[i][j] = []

Related

Method for indexing into a list by a number of dimensions

I am writing code that uses nested lists. My list structure is essentially 2 elements, but the second element comprises two individual elements and so on and so forth. The size of the list therefore grows as 2^n + 1. Anyway, for each recursion of a function I need to be able to access any given element at some 'depth'. Usually, this would be trivial as given,
list1 = [[0,1], [[1,2], [1,0]]]
the following code:
list1[1][1]
would return:
[1,0]
However, for an n dimensional nested list (I use the word 'dimension' fairly haphazardly given that this is a nested list and not an array) I would surely need to 'exponentiate' my [1] index in order to index into each progressively 'deeper' nested list. Is there a trivial way to do this?
Thanks in advance, your help is greatly appreciated.
Use recursion:
def get(li, k):
return get(li[1], k-1) if k > 0 else li
Or iteration:
def get(li, k):
for _ in range(k):
li = li[1]
return li
I created this, I tried to make it as self explanatory as possible:
my_list = [[8,9], [[0,1], [[1,2], [1,0]]]]
# dim=1 -> [8,9]
# dim=2 -> [0,1]
# dim=3 -> [1,2]
# dim=4 -> [1,0]
def get_value_by_dimension(dim :int, lst: list):
x = dim-1
if x==0:
return (lst[0])
else:
try:
return get_value_by_dimension(x, lst[1])
except:
return "Dim is to high!"
print(get_value_by_dimension(2, my_list))
# [0, 1]
print(get_value_by_dimension(1, my_list))
# [8, 9]
print(get_value_by_dimension(5, my_list))
# Dim is to high!

replacing special characters in a numpy array with blanks

I have a list of lists (see below) which has ? where a value is missing:
([[1,2,3,4],
[5,6,7,8],
[9,?,11,12]])
I want to convert this to a numpy array using np.array(test), however, the ? value is causing an issue. What I want to do is replace the ? with blank space '' and then convert to a numpy array so that I have the following
so that I end up with the following array:
([[1,2,3,4],
[5,6,7,8],
[9,,11,12]])
Use list comprehension:
matrix = ...
new_matrix = [["" if not isinstance(x,int) else x for x in sublist] for sublist in matrix]
Python does not have type for ?
check this
a =?
print(type(a))
Above code will cause syntax error
It must be "?".
If this is the case then you can use
list1 = ([[1,2,3,4],
[5,6,7,8],
[9,?,11,12]])
for i1, ele in enumerate(list1):
for i2, x in enumerate(ele):
if x == "?":
list1[i1][i2] = ""
print(list1)
This is an approach using loops to find elements that can't be turned into integers and replaces them with blank spaces.
import numpy as np
preArray = ([[1,2,3,4],
[5,6,7,8],
[9,'?',11,12]])
newPreArray = []
for row in preArray:
newRow = []
for val in row:
try:
int(val)
newRow.append(val)
except:
newRow.append('')
newPreArray.append(newRow)
array = np.array(newPreArray)
For a single list you can do something like:
>>> myList = [4, 5, '?', 6]
>>> myNewList = [i if str(i).isdigit() else '' for i in myList]
>>> myNewList
[4,5,'',6]
so take that information and make it work with a list of lists.

Generating a list using another list and an index list

Suppose I have the following two list and a smaller list of indices:
list1=[2,3,4,6,7]
list2=[0,0,0,0,0]
idx=[1,2]
I want to replace the values in list 2 using the values in list 1 at the specified indices.
I could do so using the following loop:
for i in idx:
list2[i]=list1[i]
If I just have list1 and idx , how could I write a list comprehension to generate list2 (same length as list1)such that list2 has values of list1 at indices idx or 0 otherwise.
This will call __contains__ on every call for idx but should be reasonable for small(ish) lists.
list2 = [list1[i] if i in idx else 0 for i in range(len(list1))]
or
list2 = [e if i in idx else 0 for i, e in enumerate(list1)]
Also, do not write code like this. It is much less readable than your example. Furthermore, numpy may give you the kind of syntax you desire without sacrificing readability or speed.
import numpy as np
...
arr1 = np.array(list1)
arr2 = np.zeros_like(list1)
arr2[idx] = arr1[idx]
I assume that you want to generate list2 by using appending values of list1 at specific indexes. All you need to do this is to check whether the idx list contains any values and then use a for each loop to append the specific list1 values to list2. If idx is empty then you would only append list1[0] to list2.
if(len(idx) > 0):
for i in idx:
list2.append(list1[i])
else:
list2.append(list1[0])

Function squaring 2-d array python

I have a function that takes in any 2-d array and return a 2-d array (the same format as the array being implemented) but the values are squared.
i.e [[1,2],[3,4]] -----> [[1,4],[9,16]]
my code so far:
m0 = [[1,2],[3,4]]
empty_list = []
for x in m0:
for i in x:
empyt_list.append(x**2)
This gives me a 1-d array but how would i return a 2-d array as the imputed value?
You can make a recursive function to handle any depth of nested lists:
def SquareList(L):
if type(L) is list:
return [SquareList(x) for x in L]
else:
return L**2
Example:
> print(SquareList([1,[3],[2,[3]],4]))
[1, [9], [4, [9]], 16]
Working with an outer list
The point is that you will need an extra list outside to store the columns. So we can introduce temporary lists we build up and add as rows:
m0 = [[1,2],[3,4]]
result = []
for sublist in m0:
row = []
for item in sublist:
row.append(item**2)
result.append(row)
Notice that we here iterate over the items of the sublist.
Using list comprehension
We can however write this more elegantly with list comprehension
result = [[x*x for x in sublist] for sublist in m0]
Note: if you have to square a number x, it is usually more efficient to use x * x, then to write x ** 2.
Using numpy (for rectangular lists)
In case the list is rectangular (all sublists have the same length), we can use numpy instead:
from numpy import array
a0 = array(m0)
result = a0 ** 2
You can just do this by a list comprehension:
empty_list = [[m0[i][j]**2 for j in range(len(m0[i]))] for i in range(len(m0))]
Or like your Codestyle:
empty_list = m0
for i in range(len(m0)):
for j in range(len(m0[i])):
empty_list[i][j] = m0[i][j] ** 2
Your problem is that you never created a 2D-list and you just append the values on the created 1D-list.

how to extract numbers from each position of a python list of lists

I have a list :
N=[[0,3,4], [0,1,2,9,3], [0,3]]
How do i get it so use ths list to get another list with each list item being a number for each positon of the list items in N so that the new list looks like:
newList=[[0,0,0], [3,1,3], [4,2] ,[9], [3]]
so he first item in newList is a sublist that contains the first number in N[0], the first number in N[1], and the first number in N[2]. The next sublist in N will do the same just for the second positions.
Could make use of izip_longest, then filter out the default values, eg:
from itertools import izip_longest
N=[[0,3,4], [0,1,2,9,3], [0,3]]
new_list = [[el for el in items if el is not None] for items in izip_longest(*N)]
# [[0, 0, 0], [3, 1, 3], [4, 2], [9], [3]]
Try the list comprehension
newList= [reduce(lambda x,y: x + [y[i]] if i<len(y) else x, N, [])
for i in range(max(map(len,N)))]
The for just iterates i upto the length of the longest sublist in N, using map with len to construct a temporary list of the lengths of the lists in N to calculate the max length.
The reduce builds up each sublist in the result by picking out the ith element of the corresponding input sublist -- but only if that sublist is long enough.
A weird and inneficient way (but maybe easy to understand would be):
Get maximum length of the lists in N
Iterate all those lists from 0 to that maximum.
If you got an error, that's because your original list (the one that came from N) doesn't have that item
N=[[0,3,4], [0,1,2,9,3], [0,3]]
newList = []
max_items = max([len(lst) for lst in N])
for n_lst in N:
for i in range(max_items):
if len(newList) <= i:
newList.append([])
try:
newList[i].append(n_lst[i])
except IndexError:
pass
print "new List: %s" % newList
Another approach, that maybe makes the code cleaner is initializing newList to a list with 5 items, since the longest list on your matrix N ([0,1,2,9,3]) has 5 elements. That way you know that your result (the newList variable) is going to have 5 lists:
N=[[0,3,4], [0,1,2,9,3], [0,3]]
newList = []
max_items = max([len(lst) for lst in N])
newList=list([] for _ in range(max_items))
for i in range(max_items):
for n_lst in N:
if len(n_lst) > i:
newList[i].append(n_lst[i])
print "new List: %s" % newList
Note that instead of catching an IndexException, you can also check if the len() of the list you're evaluating is > i
EDIT:
Just saw John Clements response (https://stackoverflow.com/a/22901233/289011) which is by far the cleaner.
How about the following:
# original list
N = [[0,3,4], [0,1,2,9,3], [0,3]]
# create a new list of `n` lists (n being the length of the longest sublist in N)
newList = [[] for i in xrange(max([len(l) for l in N]))]
# iterate over each list
# enumerate - use the index to append into correct target list
for l in N:
for i, val in enumerate(l):
newList[i].append(val)
print newList
Yields:
[[0, 0, 0], [3, 1, 3], [4, 2], [9], [3]]
Hope this helps! :)
Here is a solution that does not use list comprehensions, but also does not require a pre-processing step to determine maximum list length.
N = [[0,3,4], [0,1,2,9,3], [0,3]]
newList = []
progress = True
i = 0;
while (progress):
progress = False
sublist = []
for list in N:
if len(list) <= i:
continue
else:
sublist.append(list[i])
progress = True
if not progress:
break
newList.append(sublist)
i = i+1
print(N)
print(newList)

Categories