Merge two numpy array's of different shape into a single array - python

I have two numpy array's a and b of length 53 and 82 respectively. I would like to merge them into a single array because I want to use the 53+82=135 length array say call it c for plotting.
I tried
c = a+b
but I am getting ValueError: shape mismatch: objects cannot be broadcast to a single shape
Is this possible?

You need to use numpy.concatenate instead of array addition
c = numpy.concatenate((a, b))
Implementation
import numpy as np
a = np.arange(53)
b = np.arange(82)
c = np.concatenate((a, b))
Output
c.shape
(135, )

Use numpy.concatenate:
In [5]: import numpy as np
In [6]: a = np.arange(5)
In [7]: b = np.arange(11)
In [8]: np.concatenate((a, b))
Out[8]: array([ 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
For 1-D arrays you can also use numpy.hstack:
In [9]: np.hstack((a, b))
Out[9]: array([ 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Related

Python: Replace 2D numpy array filled with indices by values from a 1D array

I have a n x m numpy python array. Values of this array range between 0 and 10 what coincides with the indices of a 1D numpy array (length of 1D array = 11, so 0-10) . This 1D array stores abritrary values. I want now to replace the indices values of my 2D array with the corresponding values from the 1D array.
How can I do this ?
Cheers
Norksen
It's straightforward with numpy: result = values_1d[arr_idxs_2d]
See:
>>> import numpy as np
>>> imin, imax = 0, 9
>>> values_1d = np.random.randn(imax+1)
>>> values_1d
array([-0.80355548, 1.00645905, -1.17436992, -1.52008027, 0.73544379,
-0.72175806, -0.69933584, -0.50195895, -0.04588092, 0.86542796])
>>> arr_idxs_2d = np.random.randint(imin, imax, (4, 5))
>>> arr_idxs_2d
array([[6, 7, 4, 3, 1],
[8, 8, 3, 7, 7],
[1, 1, 5, 3, 2],
[6, 2, 3, 6, 8]])
>>> values_1d[arr_idxs_2d]
array([[-0.69933584, -0.50195895, 0.73544379, -1.52008027, 1.00645905],
[-0.04588092, -0.04588092, -1.52008027, -0.50195895, -0.50195895],
[ 1.00645905, 1.00645905, -0.72175806, -1.52008027, -1.17436992],
[-0.69933584, -1.17436992, -1.52008027, -0.69933584, -0.04588092]])

Creating this numpy array in Python

I have the following numpy array
import numpy as np
a = np.array([1,2,6,8])
I want to create another numpy array from a such that it contains all the different possible sums of TWO elements of a. It's easy to show then that there are int(a.size*(a.size-1)/2) different possible sums, composed from:
a[0] + a[1]
a[0] + a[2]
a[0] + a[3]
a[1] + a[2]
a[1] + a[3]
a[2] + a[3]
How can I construct a numpy array with the above sums as elements without using a double for loop (the only way I can think of it). For the above example, the output should be [3,7,9,8,10,14]
MWE
eff = int(a.size*(a.size-1)/2)
c = np.empty((0, eff))
You can use triu_indices:
i0,i1 = np.triu_indices(4,1)
a[i0]
# array([1, 1, 1, 2, 2, 6])
a[i1]
# array([2, 6, 8, 6, 8, 8])
a[i0]+a[i1]
# array([ 3, 7, 9, 8, 10, 14])
For more terms we need to build our own "nd_triu_idx". Here is how to do it for 3 terms out of a list of 5:
n = 5
full = np.mgrid[:n,:n,:n]
nd_triu_idx = full[:,(np.diff(full,axis=0)>0).all(axis=0)]
nd_triu_idx
# array([[0, 0, 0, 0, 0, 0, 1, 1, 1, 2],
# [1, 1, 1, 2, 2, 3, 2, 2, 3, 3],
# [2, 3, 4, 3, 4, 4, 3, 4, 4, 4]])
To fully generalize the number of terms use something like
k = 4
full = np.mgrid[k*(slice(n),)]
etc.
You can do combinations on your array of size 2 and sum each one:
import numpy as np
from itertools import combinations
a = np.array([1,2,6,8])
print(list(map(sum, combinations(a, 2))))
# [3, 7, 9, 8, 10, 14]
Or using numpy:
import numpy as np
a = np.array([1,2,6,8,1])
b = a + a[:,None]
print(b[np.triu_indices(4, 1)])
# [ 3 7 9 8 10 14]
What about computing the cartesian product of exponentiated version of a?
>>> a = np.array([1, 2, 6, 8])[:, None]
>>> b = np.exp(a)
>>> np.unique(np.tril(np.log(np.dot(b, b.T)), k=-1))[1:]
array([ 3., 7., 8., 9., 10., 14.])

Replace values in array of indexes corresponding to another array

I have an array A of size [1, x] of values and an array B of size [1, y] (y > x) of indexes corresponding to array A. I want as result an array C of size [1,y] filled with values of A.
Here is an example of inputs and outputs:
>>> A = [6, 7, 8]
>>> B = [0, 2, 0, 0, 1]
>>> C = #Some operations
>>> C
[6, 8, 6, 6, 7]
Of course I could solve it like that:
>>> C = []
>>> for val in B:
>>> C.append(A[val])
But I was actually expected a nicer way to do it. Especially because I want to use it as an argument of another function. An expression looking like A[B] (but a working one) would be ideal. I don't mind solution using NumPy or pandas.
Simple with a list comprehension:
A = [6, 7, 8]
B = [0, 2, 0, 0, 1]
C = [A[i] for i in B]
print(C)
This yields
[6, 8, 6, 6, 7]
For fetching multiple items operator.itemgetter comes in handy:
from operator import itemgetter
A = [6, 7, 8]
B = [0, 2, 0, 0, 1]
itemgetter(*B)(A)
# (6, 8, 6, 6, 7)
Also as you've mentioned numpy, this could be done directly by indexing the array as you've specified, i.e. A[B]:
import numpy as np
A = np.array([6, 7, 8])
B = np.array([0, 2, 0, 0, 1])
A[B]
# array([6, 8, 6, 6, 7])
Another option is to use np.take:
np.take(A,B)
# array([6, 8, 6, 6, 7])
This is one way, using numpy ndarrays:
import numpy as np
A = [6, 7, 8]
B = [0, 2, 0, 0, 1]
C = list(np.array(A)[B]) # No need to convert B into an ndarray
# list() is for converting ndarray back into a list,
# (if that's what you finally want)
print (C)
Explanation
Given a numpy ndarray (np.array(A)), we can index into it using an
array of integers (which happens to be exactly what your preferred
form of solution is): The array of integers that you use for
indexing into the ndarray, need not be another ndarray. It can even
be a list, and that suits us too, since B happens to a list. So,
what we have is:
np.array(A)[B]
The result of such an indexing would be another ndarray, having the
same shape (dimensions) as the array of indexes. So, in our case, as
we are indexing into an ndarray using a list of integer indexes, the
result of that indexing would be a one-dimensional ndarray of the
same length as the list of indexes.
Finally, if we want to convert the above result, from a
one-dimensional ndarray back into a list, we can pass it as an
argument to list():
list(np.array(A)[B])
You could do it with list comprehension:
>>> A = [6, 7, 8]
>>> B = [0, 2, 0, 0, 1]
>>> C = [A[x] for x in B]
>>> print(C)
[6, 8, 6, 6, 7]
I think you need a generator (list comprehension):
A = [1, 2, 3]
B = [0, 2, 0, 0, 1]
C = [A[i] for i in B]
Once you're using numpy.array you're able to do exactly what you want with syntax you expect:
>>> a = array([6, 7, 8])
>>> b = array([0, 2, 0, 0, 1])
>>> a[b]
array([6, 8, 6, 6, 7])

How to get N maximum values in a multi dimensional numpy array along a given axis(say 2)?

Since argmax only gives one maximum values,how can we find atleast 2 or 3 elements instead of just one.
Currently my input is in the format np.argmax(array,axis=2) which is giving only one maximum and i have to extract 2 or 3 atleast from the array which is N-dimensional
I would try to use the function called argpartition(). To get the indices of the two largest elements, do:
import numpy as np
a = np.array([9, 4, 4, 3, 3, 9, 0, 4, 6, 0])
ind = np.argpartition(a, -2)[-2:]
ind
Out[13]: array([5, 0], dtype=int64)
a[ind]
Out[14]: array([9, 9])
Using numpy.argsort. Data from #CarlesSansFuentes.
import numpy as np
a = np.array([9, 4, 4, 3, 3, 9, 0, 4, 6, 0])
args = np.argsort(-a)[:2]
array([0, 5], dtype=int64)

Python numpy indexing confusion

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.

Categories

Resources