NumPy: remove element from a 3-dimensional array - python-3.x

I have a 2-dimensional array with each element being a list of valid values
(pseudosyntax):
[ [1,2] [1,2]
[1,2] [1,2] ]
so effectively it's a 3-dim array/list/matrix (whatever Python calls those.)
It is generated by
import numpy as np
grid = np.full((borderSize, borderSize, borderSize), range(1, borderSize + 1))
What is the best practice to remove a value from an array on the "deepest" level?
Pseudocode:
grid = [ [1,2] [1,2]
[1,2] [1,2] ]
grid[0,1].remove(not index but value 2)
#result: grid = [ [1,2] [1]
[1,2] [1,2] ]
I did attempt every solution I could google, including numpy.delete() and array.remove(), any whatever that syntax is: arr = arr[ (arr >= 6) & (arr <= 10) ]. All the approaches seem to "flatten" the array/list/matrix, or throw cryptic-to-me errors ("can't broadcast array into shape")
Thanks!

Arrays don't really have such a thing as a "deepest" level, they have dimensions and each and every dimension has to be defined globally. You can change your array to a list and then remove the element like that:
grid = np.array([ [1,2], [1,2],
[1,2], [1,2] ])
grid = grid.tolist()
del grid[1][1]
grid
result:
[[1, 2], [1], [1, 2], [1, 2]]
but you cannot do this on an array.

Related

How to square each element in 2D list using map function python

I have a 2D list:
list1 = [[2,3,4], [3,2]]
I tried:
print( list(map(lambda x :(x**2), arr1 )))
but it gives error
TypeError: can't multiply sequence by non-int of type 'list'
How can I loop inside a map...?
You can use two maps:
list1 = [[2,3,4], [3,2]]
print(list(map(lambda x :list(map(lambda y: (y**2), x)), list1 )))
It gives the following output
[[4, 9, 16], [9, 4]]
This is cleaner with a list comprehension:
list1 = [[2,3,4], [3,2]]
list1 = [[i ** 2 for i in sublist] for sublist in list1]
print(list1)
# [[4, 9, 16], [9, 4]]
We iterate through the sublists of list1, and for each element in each sublist, we apply the transform -- squaring the number in this case.
I believe a single map and a single list comprehension is the most readable.
list1 = [[2, 3, 4], [3, 2]]
square = lambda x: x**2
squared = [list(map(square, sublist)) for sublist in list1]
you can use this code:
list1 = [[2,3,4], [3,2]]
def power(my_list):
return [ x**2 for x in my_list[i] ]
list=[]
for i in range(len(list1)):
sublist = power(list1)
list.append(sublist)
print(list)
In fact, in this code, you can adjust your power by using the function and changing it.(x ** 3 or x ** 4 and etc).

returing a list of diagonals in square matrices (simplification)

I want to return the diagonals i.e. from left to right and from right to left in a given matrix, Im using list comprehensionsto do so but I came up, in my eyes with a to complicated comprehension that returns the left to right matrix.
I was wondering if there are simpler ways to write a comprehension that returns the right to left diagonal ? Also, given that im a noob, im only beginning to dive into learning the language, i was wondering if the right_left comprehension is even conventional ?
matrix = [[1,2,3],
[4,5,6],
[7,8,9]]
left_right = [arr[i][i]
for i in range(len(arr))]
right_left = [arr[i][[-j
for j in range(-len(arr)+1,1)][i]]
for i in range(-len(arr),0)]
left_right = [arr[i][-(i+1)] for i in range(len(arr))]
For explanation of negiative indicies read this: https://stackoverflow.com/a/11367936/8326775
[list(reversed(matrix[i]))[i] for i in range(len(matrix))]
# more transparent version:
for i in range(len(matrix)):
row = list(reversed(matrix[i]))
el = row[i]
print("reversed row {} = {} -> extract element {} -> gives {}".format(i, row, i, el))
#reversed row 0 = [3, 2, 1] -> extract element 0 -> gives 3
#reversed row 1 = [6, 5, 4] -> extract element 1 -> gives 5
#reversed row 2 = [9, 8, 7] -> extract element 2 -> gives 7
You're probably better off learning about numpy, which has a function for diagonals built-in
>>> import numpy as np
>>> matrix = np.array([[1,2,3],
[4,5,6],
[7,8,9]])
>>> np.diag(matrix)
array([1, 5, 9])
>>> np.diag(matrix, k=1)
array([2, 6])
>>> np.diag(matrix, k=-1)
array([4, 8])

Getting certain values from two-dimensional list using lists of indexes / indices

I have a two dimensional list:
myList = [[0,1,2,3],
[4,5,6,7],
[8,9,10,11]]
I then have a separate two dimensional list of indexes I want from myList
myIdxs = [[0,2],
[1,3],
[0,1]]
Is there a 'pythonic' way to get those values, so I end up with a list like this:
newList = [[0,2],
[5,7],
[8,9]
Many thanks
Using zip and list comprehension
Ex:
myList = [[0,1,2,3],
[4,5,6,7],
[8,9,10,11]]
myIdxs = [[0,2],
[1,3],
[0,1]]
result = [[i[j] for j in v] for i, v in zip(myList, myIdxs)]
print(result)
Output:
[[0, 2], [5, 7], [8, 9]]

Finding overlap of given list

Find overlap which given list, a list of intervals like [2, 4], returns whether any two intervals overlap. Boundary overlaps don't count.
Example:
`>>> check_overlap(li=[[1,5], [8,9], [3,6]])
True
>>> check_overlap(li=[[1,5], [5,6]])
False`
data= [[1, 5], [8, 9], [3, 6]]
values = [[value for value in range(elem[0], elem[1])]for elem in data]
print(values)
[[1, 2, 3, 4], [8], [3, 4, 5]]
After that i want to know how to check with each element in a list whether any two intervals overlapping.
For checking the overlap, I would sort the bigger list with first element of the sublists, and check the 2nd element of a sublist is bigger than the 1st element of the next sublist.
def overlap(li):
li.sort(key=lambda x: x[0])
for i in range(len(li)-1):
if li[i][1] > li[i+1][0]:
return True
return False
print(overlap([[1,5], [8,9], [3,6]]))
print(overlap([[1,5], [5,6]]))
True
False
I would use the itertools.combinations function as such:
from itertools import combinations
def check_overlap(li):
lists = [list(range(a, b)) for a, b in li] # Shorter way of your values = ... line
for l1, l2 in combinations(lists, 2):
if any(l in l2 for l in l1):
return True
return False
The combinations(lists, 2) call gives you all possible unique combinations of different elements.
Next, the any() function takes any iterable and returns True if any of the elements in the iterable are True (or rather 'truthy'). In this case, the l in l2 for l in l1 is a generator expression, but would work the same with square brackets around it to explicitly make it into a list first.
You can create sets and check for intersection -
data= [[1, 5], [8, 9], [3, 6]]
sets_from_data = [set(range(*l)) for l in data]
intersection_exists = bool(max([len(a.intersection(b)) for a in sets_from_data for b in sets_from_data if a != b]) > 0)
intersection_exists
# True
If you only have integers you can indeed use range to do this test:
def check_overlap(li):
ranges = [range(r[0]+1, r[1]-1) for r in li]
return any(any(e-1 in r for r in ranges) for l in li for e in l)
On the other hand, if you have floating point values you'll have to tests both bounds of the interval individually (using < and >):
def is_in_range(value, boundaries):
m, M = boundaries
return value > m+1 and value < M-1
def check_overlap(li):
return any(any(is_in_range(e, r) for r in li) for l in li for e in l)

How to permute arrays based on a predefined list of indexes

Here are my few lines of code
import numpy as np
X = ([1,2,3], [2,4,5], [5,6,7])
y = ([2], [4], [5])
dist= np.random.RandomState(1)
r = dist.permutation(len(y))
Let's say
r= array([0, 2, 1])
Is there a way to permute the elements of X and y so that X and y elements are re-ordered according to indexes in r array i.e. y becomes ([2], [5], [1]) and X becomes ([1,2,3], [5,6,7], [2,4,5]) ? I didn't find out the answer in python doc. Thanks
You can use comprehension with zip:
[i for _, i in sorted(zip(r, X])]
EDIT
When you zip this happens:
zip(r, X)
#((0, [1,2,3]), (2, [2,4,5]), (1, [5,6,7]))
Then you use sorted() this happens:
sorted(zip(r, X])
((0, [1,2,3]), (1, [5,6,7]), (2, [2,4,5]))
When you take only second element from ziped and sorted you get this:
([1,2,3], [5,6,7], [2,4,5])

Resources