Replicate multidimensional NumPy array on an axis up-to specific value - python

I have a two-dimensional NumPy array with shape
(2, 2)
Example array
array([[1, 2],
[3, 4]])
I am trying to have it copy on just the first axis until it reaches the shape:
(5, 2)
Example result array
array([[1, 2],
[1, 2],
[1, 2],
[3, 4],
[3, 4]])
np.repeat does the job but it has to be a multiple as it repeats everything
np.repeat(arr, 3, axis=0)
array([[1, 2],
[1, 2],
[1, 2],
[3, 4],
[3, 4],
[3, 4]])
giving a 6 by 2 array and not a 5 by 2 array

np.repeat(arr, [3, 2], axis=0)

Related

adding elements to a numpy array and reshape it

I have the following numpy array
a= np.array([1,1])
I have the two elements
b= [2, 2]
c= [3, 3]
I would like to add those elements b and c, so that my output seems like this
a= [[1, 1],
[2, 2].
[3, 3]], #shape=(3,2)
which numpy function should i use?
thanks
Create a new numpy array with the three elements
>>> np.array([a,b,c])
array([[1, 1],
[2, 2],
[3, 3]])
# shape : (3, 2)
If a had more than 1 dimension, np.append can be used :
>>> a= np.array([[1,1], [4,4]])
>>> a
array([[1, 1],
[4, 4]])
>>> np.append(a,[b],axis=0)
array([[1, 1],
[4, 4],
[2, 2]])

how to append a 1d numpy array to a 2d numpy array python

I would like to append an array [3, 3, 3] to an array [[1, 1, 1], [2, 2, 2]], so that it becomes [[1, 1, 1], [2, 2, 2], [3, 3, 3]]
Here is my code:
import numpy as np
arr1 = np.array([[1, 1, 1],
[2, 2, 2]])
arr2 = np.append(arr1, [3, 3, 3])
print (arr2)
instead of printing [[1, 1, 1], [2, 2, 2], [3, 3, 3]],
it prints [1, 1, 1, 2, 2, 2, 3, 3, 3].
I am quite new to numpy and I do not understand why the 2d array suddenly becomes 1d.
You can use the useful numpy's standard method of vstack.
Here is my code.
Initialize 2-dimensional numpy array
initial_array = np.array([
[1, 1, 1],
[2, 2, 2]
])
define the array to append to initiali array
new_array = np.array([3, 3, 3])
append the new array to initial array as row
result = np.vstack((initial_array, new_array))
this is the result
print(result)
array([[1, 1, 1],
[2, 2, 2],
[3, 3, 3]])
You can read more details at here.
Hope this answer to be helpful for you. Thanks.
import numpy as np
arr1 = np.array([[1, 1, 1],
[2, 2, 2]])
arr2 = np.append(arr1, [[3, 3, 3]], axis=0)
print (arr2)
Output:
[[1 1 1]
[2 2 2]
[3 3 3]]
Use numpy.vstack:
arr2 = np.vstack((arr1, [3,3,3]))
>>> arr2
[[1 1 1]
[2 2 2]
[3 3 3]]

How do I reshape the following array into the other one?

How do I reshape the following numpy array with reshape:
array([[1, 2],
[3, 4],
[5, 6]])
into this one:
array([[1, 3, 5],
[2, 4, 6]])
Transpose it using - x.T
Output -
array([[1, 3, 5],
[2, 4, 6]])
The transformation that you are trying to achieve is a transpose.
a = np.array([[1, 2],
[3, 4],
[5, 6]])
a.T # array([[1, 3, 5], [2, 4, 6]])

Row-wise replacement of numpy array with values of another numpy array

I have 0s and 1s store in a 3-dimensional numpy array:
g = np.array([[[0, 1], [0, 1], [1, 0]], [[0, 0], [1, 0], [1, 1]]])
# array([
# [[0, 1], [0, 1], [1, 0]],
# [[0, 0], [1, 0], [1, 1]]])
and I'd like to replace these values by those in another array using a row-wise replacement strategy. For example, replacing the vales of g by x:
x = np.array([[2, 3], [4, 5]])
array([[2, 3],
[4, 5]])
to obtain:
array([
[[2, 3], [2, 3], [3, 2]],
[[4, 4], [5, 4], [5, 5]]])
The idea here would be to have the first row of g replaced by the first elements of x (0 becomes 2 and 1 becomes 3) and the same for the other row (the first dimension - number of "rows" - will always be the same for g and x)
I can't seem to be able to use np.where because there's a ValueError: operands could not be broadcast together with shapes (2,3,2) (2,2) (2,2).
IIUC,
np.stack([x[i, g[i]] for i in range(x.shape[0])])
Output:
array([[[2, 3],
[2, 3],
[3, 2]],
[[4, 4],
[5, 4],
[5, 5]]])
Vectorized approach with np.take_along_axis to index into the last axis of x with g using axis=-1 -
In [20]: np.take_along_axis(x[:,None],g,axis=-1)
Out[20]:
array([[[2, 3],
[2, 3],
[3, 2]],
[[4, 4],
[5, 4],
[5, 5]]])
Or with manual integer-based indexing -
In [27]: x[np.arange(len(g))[:,None,None],g]
Out[27]:
array([[[2, 3],
[2, 3],
[3, 2]],
[[4, 4],
[5, 4],
[5, 5]]])
One solution, is to simply use comprehension directly here:
>>> np.array([[x[i][c] for c in r] for i, r in enumerate(g)])
array([[[2, 3],
[2, 3],
[3, 2]],
[[4, 4],
[5, 4],
[5, 5]]])
From what I understand, g is an array of indexes (indexes being 0 or 1) and x is the array to who's values you use.
Something like this should work (tested quickly)
import numpy as np
def swap_indexes(index_array, array):
out_array = []
for i, row in enumerate(index_array):
out_array.append([array[i,indexes] for indexes in row])
return np.array(out_array)
index_array = np.array([[[0, 1], [0, 1], [1, 0]], [[0, 0], [1, 0], [1, 1]]])
x = np.array([[2, 3], [4, 5]])
print(swap_indexes(index_array, x))
[EDIT: fixed typo that created duplicates]

How to remove duplicates from a 3D array in Python?

I have a 3D array as follow, 'b', which I want to represent an array of 2-D array. I want to remove the duplicates of my 2-D arrays and get the unique ones.
>>> a = [[[1, 2], [1, 2]], [[1, 2], [4, 5]], [[1, 2], [1, 2]]]
>>> b = numpy.array(a)
>>> b
array([[[1, 2],
[1, 2]],
[[1, 2],
[4, 5]],
[[1, 2],
[1, 2]]])
In this above example, I really want to return the following because there exist one duplicate which I want to remove.
unique = array([[[1, 2],
[1, 2]],
[[1, 2],
[4, 5]])
How should do this with numpy package? Thanks
See previous answer: Remove duplicate rows of a numpy array
convert to array of tuples and then apply np.unique()
Converting to tuple and back again is probably going to be quire expensive, instead you can do a generalized view:
def unique_by_first(a):
tmp = a.reshape(a.shape[0], -1)
b = np.ascontiguousarray(tmp).view(np.dtype((np.void, tmp.dtype.itemsize * tmp.shape[1])))
_, idx = np.unique(b, return_index=True)
return a[idx].reshape(-1, *a.shape[1:])
Usage:
print unique_by_first(a)
[[[1 2]
[1 2]]
[[1 2]
[4 5]]]
Effectively, a generalization of previous answers.
You can convert each such 2D slice off the last two axes into a scalar each by considering them as indices on a multi-dimensional grid. The intention is to map each such slice to a scalar based on their uniqueness. Then, using those scalars, we could use np.unique to keep one instance only.
Thus, an implementation would be -
idx = np.ravel_multi_index(a.reshape(a.shape[0],-1).T,a.max(0).ravel()+1)
out = a[np.sort(np.unique(idx, return_index=1)[1])]
Sample run -
In [43]: a
Out[43]:
array([[[8, 1],
[2, 8]],
[[3, 8],
[3, 4]],
[[2, 4],
[1, 0]],
[[3, 0],
[4, 8]],
[[2, 4],
[1, 0]],
[[8, 1],
[2, 8]]])
In [44]: idx = np.ravel_multi_index(a.reshape(a.shape[0],-1).T,a.max(0).ravel()+1)
In [45]: a[np.sort(np.unique(idx, return_index=1)[1])]
Out[45]:
array([[[8, 1],
[2, 8]],
[[3, 8],
[3, 4]],
[[2, 4],
[1, 0]],
[[3, 0],
[4, 8]]])
If you don't mind the order of such slices being maintained, skip the np.sort() at the last step.
Reshape, find the unique rows, then reshape again.
Finding unique tuples by converting to a set.
import numpy as np
a = [[[1, 2], [1, 2]], [[1, 2], [4, 5]], [[1, 2], [1, 2]]]
b = np.array(a)
new_array = [tuple(row) for row in b.reshape(3,4)]
uniques = list(set(new_array))
output = np.array(uniques).reshape(len(uniques), 2, 2)
output
Out[131]:
array([[[1, 2],
[1, 2]],
[[1, 2],
[4, 5]]])

Categories