multidimensional numpy array __eq__ - python

I have a bi-dimensional np.array like
x = np.array([[1,2], [4,5], [4,6], [5,4], [4,5]])
now I want the indices where x is equal to [4,5] (-> [1, 4]). The operator == works in a different way:
x == [4,5]
array([[False, False],
[ True, True],
[ True, False],
[False, False],
[ True, True]], dtype=bool)
but I want something like [False, True, False, False, True]. Is it ok to do an and?
Usually the array is very big and I have to do it a lot of times, so I need a very fast way.

this should be the numpy-way:
x = np.array([[1,2], [4,5], [4,6], [5,4], [4,5]])
(x == [4,5]).all(1)
#out: array([False, True, False, False, True], dtype=bool)

No prior experience with numpy, but this works for a standard array:
x = [[1, 2], [4, 5], [4, 6], [5, 4], [4, 5]]
indices = [i for i, v in enumerate(x) if v == [4, 5]]
# gives [1, 4]
matches = [v == [4, 5] for v in x]
# gives [False, True, False, False, True]

Related

Boolean indicies of extended slice

I have the following numpy array:
a = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
I can use extended slicing to select e.g. columns:
>>> a[:,0::2]
array([[1, 3],
[4, 6],
[7, 9]])
>>> a[:,1::2]
array([[2],
[5],
[8]])
But I want to produce the following:
array([[True, False, True],
[True, False, True],
[True, False, True]])
array([[False, True, False],
[False, True, False],
[False, True, False]])
import numpy as np
bools = np.array([[False, False, False],
[False, False, False],
[False, False, False]])
bools[:, 0::2] = True
print(bools)
Output:
[[ True False True]
[ True False True]
[ True False True]]
np.array([[True if y%2==0 else False for y,z in enumerate(x)] for x in bools])
np.array([[False if y%2==0 else True for y,z in enumerate(x)] for x in bools])
Explanation:
By using list comprehension, variable 'x' iterates through each row of a. The inner list comprehension iterates through each of this('x' from outer comprehension) list elements. It can be observed that in your output, True & False values depend on index of the elements rather than the element values. Hence by using enumerate(), we get the index of each element in 'y' & value in 'z'. And using conditions on 'y', we decide on replacing with True or False

Check if a value from a nested list is in anothere nested list

I want to check if list1[0] value is contained in list2[0] and then list1[1] -> list2[1] ... so I get the same result as below:
list1 = [[1, 2, 3], [2, 3, 4], [3, 4, 5]]
list2 = [[2, 5], [4, 6, 8], [4]]
result = [[False, True, False], [False, False, True], [False, True, False]]
You can use nested list comprehensions:
result = [[x in b for x in a] for a, b in zip(list1, list2)]
print(result)
Output:
[[False, True, False], [False, False, True], [False, True, False]]

How to compare 2-number elements in an array with a 2-number list to generate a boolean-type array?

for example
a = np.array(([0, 0], [0, 1], [1, 0], [1, 1]))
c = np.array(a == [0, 1])
in this way I just get
`array([[ True, False],
[ True, True],
[False, False],
[False, True]])`
but I want to get
array([False, True, False, False])
of course I can ravel c and use a if(c[i]==1)&(c[i+1]==1) to give "True",
c = c.ravel()
cshape = list(c.shape)
del cshape[-1]
d = []
for i in range(0, len(c), 2):
if (c[i]==1)&(c[i + 1]==1):
d.append(True)
else:
d.append(False)
d = np.array(d).reshape(cshape)
but for a large system, it could be a cost of resources.
is there any simple method to do it?
In [1]: a = np.array(([0, 0], [0, 1], [1, 0], [1, 1]))
In [2]: a==np.array([0,1])
Out[2]:
array([[ True, False],
[ True, True],
[False, False],
[False, True]])
Just check whether all elements of a row are True:
In [3]: _.all(axis=1)
Out[3]: array([False, True, False, False])

Mask from max values in numpy array, specific axis

Input example:
I have a numpy array, e.g.
a=np.array([[0,1], [2, 1], [4, 8]])
Desired output:
I would like to produce a mask array with the max value along a given axis, in my case axis 1, being True and all others being False. e.g. in this case
mask = np.array([[False, True], [True, False], [False, True]])
Attempt:
I have tried approaches using np.amax but this returns the max values in a flattened list:
>>> np.amax(a, axis=1)
array([1, 2, 8])
and np.argmax similarly returns the indices of the max values along that axis.
>>> np.argmax(a, axis=1)
array([1, 0, 1])
I could iterate over this in some way but once these arrays become bigger I want the solution to remain something native in numpy.
Method #1
Using broadcasting, we can use comparison against the max values, while keeping dims to facilitate broadcasting -
a.max(axis=1,keepdims=1) == a
Sample run -
In [83]: a
Out[83]:
array([[0, 1],
[2, 1],
[4, 8]])
In [84]: a.max(axis=1,keepdims=1) == a
Out[84]:
array([[False, True],
[ True, False],
[False, True]], dtype=bool)
Method #2
Alternatively with argmax indices for one more case of broadcasted-comparison against the range of indices along the columns -
In [92]: a.argmax(axis=1)[:,None] == range(a.shape[1])
Out[92]:
array([[False, True],
[ True, False],
[False, True]], dtype=bool)
Method #3
To finish off the set, and if we are looking for performance, use intialization and then advanced-indexing -
out = np.zeros(a.shape, dtype=bool)
out[np.arange(len(a)), a.argmax(axis=1)] = 1
Create an identity matrix and select from its rows using argmax on your array:
np.identity(a.shape[1], bool)[a.argmax(axis=1)]
# array([[False, True],
# [ True, False],
# [False, True]], dtype=bool)
Please note that this ignores ties, it just goes with the value returned by argmax.
You're already halfway in the answer. Once you compute the max along an axis, you can compare it with the input array and you'll have the required binary mask!
In [7]: maxx = np.amax(a, axis=1)
In [8]: maxx
Out[8]: array([1, 2, 8])
In [12]: a >= maxx[:, None]
Out[12]:
array([[False, True],
[ True, False],
[False, True]], dtype=bool)
Note: This uses NumPy broadcasting when doing the comparison between a and maxx
in on line : np.equal(a.max(1)[:,None],a) or np.equal(a.max(1),a.T).T .
But this can lead to several ones in a row.
In a multi-dimensional case you can also use np.indices. Let's suppose you have an array:
a = np.array([[
[0, 1, 2],
[3, 8, 5],
[6, 7, -1],
[9, 5, 8]],[
[5, 2, 8],
[7, 6, -3],
[-1, 2, 1],
[3, 5, 6]]
])
you can access argmax values calculated for axis 0 like so:
k = np.zeros((2, 4, 3), np.bool)
k[a.argmax(0), ind[0], ind[1]] = 1
The output would be:
array([[[False, False, False],
[False, True, True],
[ True, True, False],
[ True, True, True]],
[[ True, True, True],
[ True, False, False],
[False, False, True],
[False, False, False]]])

Convert list with a for

pin_configuration = [[1, 1], [2, 2], [3, 3], [4, 4], [...]]
bool_list = [[False] * 68] * 68
for m in range(0, 68):
for b in range(0, len(pin_configuration[m][1:])):
position = pin_configuration[m][b]
bool_list[m][position] = True
Now I have a output like this:
bool_list = [[True, False, False,False,...], [True, False, False,
False,...], [True, False, False, False,...], [...]
But i want this:
bool_list = [[True, False, False,False,...], [False, True, False,
False,...], [False, False, True, False,...], [...]
I just want to set True in bool_list there where the value pin_configuration[x][1] is
How I can do this ?
You initialize bool_list in wrong way - instead of making 68 separate lists (rows), you make 68 references to the same list.
bool_list = [[False] * 68 for i in range(68)]
will do what you want.
Here's a way to get the desired list. Just set n back to 68 once you're sure it works fine.
You need to create n distinct lists first, and you can then iterate over the pin_configuration coordinates to set the desired elements to True.
Note that the first element in Python lists has index 0, not 1:
pin_configuration = [[1, 1], [2, 2], [3, 3], [4, 4]]
n = 5
bool_list = [[False] * n for i in range(n)]
for i,j in pin_configuration:
bool_list[i-1][j-1] = True
print(bool_list)
#[[True, False, False, False, False], [False, True, False, False, False], [False, False, True, False, False], [False, False, False, True, False], [False, False, False, False, False]]

Categories