Say I have two Numpy arrays:
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
b = np.array([7, 8, 9])
How do I easily find where b exists in a? In this case I want 2. numpy.where() returns useful information but it still has to be processed. I have written a function for that, as can be seen below, but there must be an easier way.
def find_vertical_array_index(a, b):
"""Find array in another array.
Parameters
----------
a: numpy array
Array to find array in.
b: numpy array
Array to find array. Must have dimensions 1 by n.
Returns
-------
Integer value of index where b first occurs in a.
Notes
-----
Only searches through the array vertically and returns the first index.
If array does not occur, nothing is returned.
Examples
--------
>>> x = np.array([[5, 3, 1, 1], [9, 9, 9, 8], [9, 3, 7, 9]])
>>> y = np.array([9, 9, 9, 8])
>>> find_vertical_array_index(x, y)
1
>>> x = np.array([[9, 9, 9, 8], [9, 9, 9, 8], [9, 3, 7, 9]])
>>> y = np.array([9, 9, 9, 9])
0
"""
try:
index = list(Counter(np.where(a == b)[0]).values()).index(len(b))
except ValueError:
pass
return list(Counter(np.where(a == b)[0]).keys())[index]
Related
The situation is the following:
Lets say I have two arrays, x and y:
Input:
x = [1,2,3,4,5,6,7,8,9,10,11,12,13,14]
y = [2,6,9,13]
Expected output:
arr1 = [2,3,4,5]
arr2 = [6,7,8]
arr3 = [9,10,11,12]
I would like to create a python script that can let me split up array x into multiple arrays based on the values of array y as the end points.
So x will split up between 2 and 6, then between 6 and 9, then between 9 and 13 in this example.
I am not sure how to get started on this, I am a beginner. I would appreciate the help and I would love to know how you broke down the problem to solve it? Thank you!
Find the index of x based on value in y and then use indexing
arr = []
for i in range(len(y)-1):
arr.append(x[x.index(y[i]):x.index(y[i+1])])
arr
[[2, 3, 4, 5], [6, 7, 8], [9, 10, 11, 12]]
This works if there are duplicates in the array,
x = [2,3,4,5,6,7,7,8,9,9,10,11,11,12,13,14,15]
y = [2,6,9,13]
arr = []
for i in range(len(y)-1):
arr.append(x[x.index(y[i]):x.index(y[i+1])])
[[2, 3, 4, 5], [6, 7, 7, 8], [9, 9, 10, 11, 11, 12]]
For x sorted, we can use np.searchsorted with np.split to split x using the indices where y is contained in x:
import numpy as np
i = np.searchsorted(x, y)
np.split(x,i+1)[1:-1]
# [array([3, 4, 5, 6]), array([7, 8, 9]), array([10, 11, 12, 13])]
You are somewhat inconsistent in your expected output, or I don`t get the pattern behind it, but this should get you close to what you want
x = [1,2,3,4,5,6,7,8,9,10,11,12,13,14]
y = [2,6,9,13]
m = []
for i in range(len(y) - 1):
m += [x[y[i] - 1:y[i+1] - 1]]
print(m)
Output
[[2, 3, 4, 5], [6, 7, 8], [9, 10, 11, 12]]
This question already has answers here:
Selecting Random Windows from Multidimensional Numpy Array Rows
(2 answers)
Closed 3 years ago.
I have an m x n numpy array arr, and for each column of arr, I have a given range of rows that I want to access.
I have an n x 1 array vec that describes when this range starts.
The range has some constant duration d.
How can I extract this d x n array of interest efficiently?
Can this be done by clever slicing?
My initial thought was to try something like:
arr = np.tile(np.arange(10),(4,1)).T
vec = np.array([3,4,5,4])
d = 3
vec_2 = vec+d
out = arr[vec:vec2,np.arange(n)]
But this gives the following error:
TypeError: only integer scalar arrays can be converted to a scalar index
The desired output would be the following array:
array([[3, 4, 5, 4],
[4, 5, 6, 5],
[5, 6, 7, 6],
[6, 7, 8, 7])
I could loop over d, but performance is important for this piece of code so I would prefer to vectorize it.
In [489]: arr=np.arange(24).reshape(6,4)
In [490]: vec=np.array([0,2,1,3])
Taking advantage of the recent expansion of linspace to generate several arrays:
In [493]: x = np.linspace(vec,vec+2,3).astype(int)
In [494]: x
Out[494]:
array([[0, 2, 1, 3],
[1, 3, 2, 4],
[2, 4, 3, 5]])
In [495]: arr[x, np.arange(4)]
Out[495]:
array([[ 0, 9, 6, 15],
[ 4, 13, 10, 19],
[ 8, 17, 14, 23]])
the column iteration approach:
In [498]: np.stack([arr[i:j,k] for k,(i,j) in enumerate(zip(vec,vec+3))],1)
Out[498]:
array([[ 0, 9, 6, 15],
[ 4, 13, 10, 19],
[ 8, 17, 14, 23]])
Suppose you have a matrix:
a = np.arange(9).reshape(3,3)
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
and I want get or set over the values 1, 5, and 6, how would I do that.
For example I thought doing
# getting
b = a[:, np.array([1,2,0])]
# want b = [1,5,6]
# setting
a[:, np.array([1,2,0])] = np.array([9, 10, 11])
# want:
# a = array([[0, 9, 2],
# [3, 4, 10],
# [11, 7, 8]])
would do it, but that is not the case. Any thoughts on this?
Only a small tweak makes this work:
import numpy as np
a = np.arange(9).reshape(3,3)
# getting
b = a[range(a.shape[0]), np.array([1,2,0])]
# setting
a[range(a.shape[0]), np.array([1,2,0])] = np.array([9, 10, 11])
The reason why your code didn't work as expected is because you were indexing the x-axis with slices instead of indices. Slices mean take all rows, but specifying the index directly will get you the row you want for each index value.
I'm new in python, I was looking into a code which is similar to as follows,
import numpy as np
a = np.ones([1,1,5,5], dtype='int64')
b = np.ones([11], dtype='float64')
x = b[a]
print (x.shape)
# (1, 1, 5, 5)
I looked into the python numpy documentation I didn't find anything related to such case. I'm not sure what's going on here and I don't know where to look.
Edit
The actual code
def gausslabel(length=180, stride=2):
gaussian_pdf = signal.gaussian(length+1, 3)
label = np.reshape(np.arange(stride/2, length, stride), [1,1,-1,1])
y = np.reshape(np.arange(stride/2, length, stride), [1,1,1,-1])
delta = np.array(np.abs(label - y), dtype=int)
delta = np.minimum(delta, length-delta)+length/2
return gaussian_pdf[delta]
I guess that this code is trying to demonstrate that if you index an array with an array, the result is an array with the same shape as the indexing array (in this case a) and not the indexed array (i.e. b)
But it's confusing because b is full of 1s. Rather try this with a b full of different numbers:
>> a = np.ones([1,1,5,5], dtype='int64')
>> b = np.arange(11) + 3
array([ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13])
>>> b[a]
array([[[[4, 4, 4, 4, 4],
[4, 4, 4, 4, 4],
[4, 4, 4, 4, 4],
[4, 4, 4, 4, 4],
[4, 4, 4, 4, 4]]]])
because a is an array of 1s, the only element of b that is indexed is b[1] which equals 4. The shape of the result though is the shape of a, the array used as the index.
Say I have the following 5x5 numpy array called A
array([[6, 7, 7, 7, 8],
[4, 2, 5, 5, 9],
[1, 2, 4, 7, 4],
[0, 7, 3, 6, 8],
[4, 9, 6, 1, 6]])
and this 5x5 array called F
array([[1,0,0,0,0],
[1,0,0,0,0],
[1,0,0,0,0],
[1,0,0,0,0],
[0,0,0,0,0]])
I've been trying to use np.copyto, but I can't wrap my head around why it is not working/how it works.ValueError: could not broadcast input array from shape (5,5) into shape (2)
Is there a easy way to get the values of only the matching integers that have a corresponding 1 in F when laid over A? e.i it would return, 6,4,1,0
you can just do this little trick: A[F==1]
In [8]:
A[F==1]
Out[8]:
array([6, 4, 1, 0])
Check out Boolean indexing
To use np.copyto make sure that the destination array is np.empty.
This basically solved my problem.