Interleave numpy arrays [duplicate] - python

This question already has answers here:
Interweaving two numpy arrays
(13 answers)
Closed 4 years ago.
I'm trying to interleave arrays as below.
import numpy as np
x = np.array([1,2,3,4,5])
y = np.array([4,6,2,6,9],[5,9,8,7,4],[3,2,5,4,9])
Desired result:
[[1,2,3,4,5],[4,6,2,6,9],[1,2,3,4,5],[5,9,8,7,4],[1,2,3,4,5],[3,2,5,4,9]]
Is there an elegant way to do this?
This is my the way I wrote, but I was looking to improve this line. data=np.array([x,y[0],x,y[1],x,y[2]]) Any other way to write this?
x=np.array([1,2,3,4,5])
y=np.array([[4,6,2,6,9],[5,9,8,7,4],[3,2,5,4,9]])
data=np.array([x,y[0],x,y[1],x,y[2]])
print(data)

You can try to use np.insert
import numpy as np
x = np.array([1,2,3,4,5])
y = np.array([[4,6,2,6,9],[5,9,8,7,4],[3,2,5,4,9]])
np.insert(y, obj=(0, 1, 2), values=x, axis=0)
array([[1, 2, 3, 4, 5],
[4, 6, 2, 6, 9],
[1, 2, 3, 4, 5],
[5, 9, 8, 7, 4],
[1, 2, 3, 4, 5],
[3, 2, 5, 4, 9]])
(0, 1, 2) refers to the indexes in y that you would like to insert into before insertion.
EDIT : One can use obj=range(y.shape[0]) for arbitrary length of y. Thanks for Chiel's suggestion.
Please see the tutorial for more information.

Adapted from the answer https://stackoverflow.com/a/5347492/7505395 to Interweaving two numpy arrays:
import numpy as np
x=np.array([1,2,3,4,5])
y=np.array([[4,6,2,6,9],[5,9,8,7,4],[3,2,5,4,9]]) # fixed missing []
x_enh = np.array([x]*len(y)) # blow up x to y size
c = np.empty((y.size * 2,), dtype=y.dtype).reshape(y.size,5) # create correctly sized empty
c[0::2] = x_enh # interleave using 2 steps starting on 0
c[1::2] = y # interleave using 2 steps starting on 1
print(c)
Output:
[[1 2 3 4 5]
[4 6 2 6 9]
[1 2 3 4 5]
[5 9 8 7 4]
[1 2 3 4 5]
[3 2 5 4 9]]

Related

Use numpy to stack combinations of a 1D and 2D array

I have 2 numpy arrays, one 2D and the other 1D, for example like this:
import numpy as np
a = np.array(
[
[1, 2],
[3, 4],
[5, 6]
]
)
b = np.array(
[7, 8, 9, 10]
)
I want to get all possible combinations of the elements in a and b, treating a like a 1D array, so that it leaves the rows in a intact, but also joins the rows in a with the items in b. It would look something like this:
>>> combine1d(a, b)
[ [1 2 7] [1 2 8] [1 2 9] [1 2 10]
[3 4 7] [3 4 8] [3 4 9] [3 4 10]
[5 6 7] [5 6 8] [5 6 9] [5 6 10] ]
I know that there are slow solutions for this (like a for loop), but I need a fast solution to this as I am working with datasets with millions of integers.
Any ideas?
This is one of those cases where it's easier to build a higher dimensional object, and then fix the axes when you're done. The first two dimensions are the length of b and the length of a. The third dimension is the number of elements in each row of a plus 1. We can then use broadcasting to fill in this array.
x, y = a.shape
z, = b.shape
result = np.empty((z, x, y + 1))
result[...,:y] = a
result[...,y] = b[:,None]
At this point, to get the exact answer you asked for, you'll need to swap the first two axes, and then merge those two axes into a single axis.
result.swapaxes(0, 1).reshape(-1, y + 1)
An hour later. . . .
I realized by being a little bit more clever, I didn't need to swap axes. This also has the nice benefit that the result is a contiguous array.
def convert1d(a, b):
x, y = a.shape
z, = b.shape
result = np.empty((x, z, y + 1))
result[...,:y] = a[:,None,:]
result[...,y] = b
return result.reshape(-1, y + 1)
this is very "scotch tape" solution:
import numpy as np
a = np.array(
[
[1, 2],
[3, 4],
[5, 6]
]
)
b = np.array(
[7, 8, 9, 10]
)
z = []
for x in b:
for y in a:
z.append(np.append(y, x))
np.array(z).reshape(3, 4, 3)
You need to use np.c_ to attach to join two dataframe. I also used np.full to generate a column of second array (b). The result are like what follows:
result = [np.c_[a, np.full((a.shape[0],1), x)] for x in b]
result
Output
[array([[1, 2, 7],
[3, 4, 7],
[5, 6, 7]]),
array([[1, 2, 8],
[3, 4, 8],
[5, 6, 8]]),
array([[1, 2, 9],
[3, 4, 9],
[5, 6, 9]]),
array([[ 1, 2, 10],
[ 3, 4, 10],
[ 5, 6, 10]])]
The output might be kind of messy. But it's exactly like what you mentioned as your desired output. To make sure, you cun run below to see what comes from the first element in the result array:
print(result[0])
Output
array([[1, 2, 7],
[3, 4, 7],
[5, 6, 7]])

How to replace values in numpy array at the same time [duplicate]

This question already has answers here:
Replace all elements of Python NumPy Array that are greater than some value
(8 answers)
Closed 9 months ago.
I have numpy array with random numbers. For example like this
[7 1 2 0 2 3 4 0 5]
and I want to replace every number at the same time if number from this array = 7, I want to replace it with 2 , also if number = 2, replace it with 3. So it will be like [2 1 3 0 3 3 4 0 5] . I have tried it with np.where but can't change any of them.
It's better to use np.select if you've multiple conditions:
a = np.array([7, 1, 2, 0, 2, 3, 4, 0, 5])
a = np.select([a == 7, a == 2], [2, 3], a)
OUTPUT:
[2 1 3 0 3 3 4 0 5]
Numpy provide the comparison to a scalar with the standard == operator, such that arr == v return a boolean array. Taking arr[arr == v] takes the subset (or slice) of arr where the condition is met so this snippet should work.
import numpy as np
arr = np.array([7, 1, 2, 0, 2, 3, 4, 0, 5])
arr[arr == 7] = 2
arr
array([2, 1, 2, 0, 2, 3, 4, 0, 5])

How to delete all minimum values from array in python

I have a array of [2 2 3 4 4 5 6 6 6], and want to delete all minimum values from it.
The output should be [3 4 4 5 6 6 6].
I tried like following code, but it deleted a single 2, and left [2 3 4 4 5 6 6 6].
import numpy as np
a = np.array([2,2,3,4,4,5,6,6,6])
b= np.delete(a, a.argmin())
Python has a built-in function for finding min
val = min(values)
b =[v for v in values if v != val]
Use Boolean or “mask” index arrays
Numpy: Indexing
min() or not to a.min() depends on the array size.
For small arrays, use python built-in min
For large arrays, use numpy min
Test the timing for your particular usage.
b = a[a > min(a)]
[b]:
array([3, 4, 4, 5, 6, 6, 6])
The size of numpy arrays is immutable but you can create a copy of this array using this simple oneliner:
arr = np.array([2, 2, 3, 4, 4, 5, 6, 6, 6])
arr[arr!=np.min(arr)]
Output:
array([3, 4, 4, 5, 6, 6, 6])
You can get the indices that are greater than minimum value and slice the array as in this answer.
out = a[a>a.min()]
Notice this is faster than using np.delete as explained in the linked answer.

Using numpy.ones as indices of an array

I would like to translate a matlab code into a python one. The matlab code is equivalent to the following toy example:
a = [1 2 3; 4 5 6; 7 8 9]
b = a(:, ones(1,3))
It returns
a =
1 2 3
4 5 6
7 8 9
b =
1 1 1
4 4 4
7 7 7
I tried to translate it like this:
from numpy import array
from numpy import ones
a = array([ [1,2,3], [4,5,6], [7,8,9] ])
b = a[:][ones((1,3))]
but it returns the following error message:
Traceback (most recent call last):
File "example_slice.py", line 6, in
b =a[:, ones((1,3))]
IndexError: arrays used as indices must be of integer (or boolean) type
EDIT: maybe ones should be replaced by zeros in this particular case but it is not the problem here. The question deals with the problem of giving a list containing the same index many times to the array a in order to get the same array b as the one computed with Matlab.
The MATLAB code can also be written (more idiomatically and more clearly) as:
b = repmat(a(:,1),1,3);
In NumPy you'd write:
b = np.tile(a[:,None,0],(1,3))
(Note the None needed to preserve the orientation of the vector extracted).
You could use list comprehension with np.full() to create arrays of certain values.
import numpy as np
a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
b = np.array([np.full(len(i), i[0]) for i in a])
print(b)
Output:
[[1 1 1]
[4 4 4]
[7 7 7]]
In [568]: a = np.array([ [1,2,3], [4,5,6], [7,8,9] ])
In [569]: a[:,0]
Out[569]: array([1, 4, 7])
In [570]: a[:,[0,0,0]]
Out[570]:
array([[1, 1, 1],
[4, 4, 4],
[7, 7, 7]])
In [571]: a[:, np.zeros(3, dtype=int)] # int dtype to avoid your error
Out[571]:
array([[1, 1, 1],
[4, 4, 4],
[7, 7, 7]])
====
In [572]: np.zeros(3)
Out[572]: array([0., 0., 0.])
In [573]: np.zeros(3, int)
Out[573]: array([0, 0, 0])
Earlier numpy versions allowed float indices, but newer ones have tightened the requirement.

Slice 2-D array row by row with corresponding rows from identically shaped array [duplicate]

This question already has answers here:
Indexing one array by another in numpy
(4 answers)
Closed 6 years ago.
consider the array a
np.random.seed([3,1415])
a = np.random.choice(np.arange(8), (2, 4), False)
print(a)
[[7 1 4 5]
[6 2 3 0]]
I'll create another array b that holds the results of np.argsort along each row.
b = a.argsort(1)
print(b)
[[1 2 3 0]
[3 1 2 0]]
I want to produce the sorted version of a by doing an appropriate slice of a with b. It should look like this
idx0 = np.arange(a.shape[0]).repeat(a.shape[1])
print(a[idx0, b.ravel()].reshape(a.shape))
[[1 4 5 7]
[0 2 3 6]]
question
what is the appropriate way to slice an 2 x 4 array with another 2 x 4 array in the fashion described above?
Advanced-indexing for the help -
a[np.arange(b.shape[0])[:,None],b]
Sample run -
In [10]: a
Out[10]:
array([[7, 1, 4, 5],
[6, 2, 3, 0]])
In [11]: b
Out[11]:
array([[1, 2, 3, 0],
[3, 1, 2, 0]])
In [12]: a[np.arange(b.shape[0])[:,None],b]
Out[12]:
array([[1, 4, 5, 7],
[0, 2, 3, 6]])

Categories

Resources