Per line numpy roll [duplicate] - python

This question already has answers here:
Roll rows of a matrix independently
(6 answers)
Closed 4 months ago.
Is there an elegant way to perform a per-line roll of a numpy array?
Example:
>>> arr
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
>>> desired_func(arr, shift=np.array([1, 2]))
array([[4, 1, 2, 3],
[7, 8, 5, 6]])
The function np.roll doesn't seem to allow that.

You can use fancy indexing:
# define the roll per row
roll = np.array([1, 2])
# compute the rolled indices
idx = (np.arange(arr.shape[1]) - roll[:,None]) % arr.shape[1]
# index as 2D
out = arr[np.arange(arr.shape[0])[:,None], idx]
output:
array([[4, 1, 2, 3],
[7, 8, 5, 6]])

Related

How to stack numpy array with different shape [duplicate]

This question already has answers here:
How to make a multidimension numpy array with a varying row size?
(7 answers)
Closed 1 year ago.
I want to stack arrays with this code.
a = np.array([[1, 2, 3], [4, 5, 6]])
b = np.array([7, 8])
np.stack((a, b), axis=-1)
But it returns
ValueError: all input arrays must have the same shape error.
I expect the output to be:
array([[[1, 2, 3], 7],
[[4, 5, 6], 8]])
I don't think that's a valid numpy array. You could probably do this by letting the array's dtype be an object (which could be anything, including a ragged sequence, such as yours).
data = [[[1, 2, 3], 7], [[4, 5, 6], 8]]
ar = np.array(data, dtype=object)
To build data, you can do:
a = np.array([[1, 2, 3], [4, 5, 6]])
b = np.array([7, 8])
data = [[_a, _b] for _a, _b in zip(a, b)]

Connecting an array of numpys [duplicate]

This question already has answers here:
concatenate numpy arrays which are elements of a list
(2 answers)
Closed 2 years ago.
I have a list of numpys of the same length each. for example:
my_list = [np.array([2, 3, 5, 5]),
np.array([5, 4, 1, 4]),
np.array([8, 4, 5, 1]),
np.array([7, 4, 5, 1])]
I want to turn the list into 2d numpy:
[[2, 3, 5, 5],
[5, 4, 1, 4],
[8, 4, 5, 1],
[7, 4, 5, 1]]
The following code does perform the operation but in a sloppy manner.
The result is also not arranged in the desired order:
combined = []
for i in my_list :
if len(combined) == 0:
combined = i
else:
combined = np.vstack((i,combined))
print(combined)
What needs to be changed to get the desired result?
The most straightforward way
np.vstack(my_list)
or
np.concatenate(my_list).reshape(len(my_list),-1)
Simply doing np.array(my_list) can get the job done.

How to slice a multi-dimensional array with another multi-dimensional array? [duplicate]

This question already has answers here:
Indexing one array by another in numpy
(4 answers)
Closed 3 years ago.
I have, say, a 2D-array:
x = np.array([[4, 5, 6],
[7, 8, 9]])
and another one with indexes:
a = np.array([[0, 1],
[1, 2]])
How do I slice each row of x using the indexes in each respective row in a without using a loop in order to obtain:
[[4, 5]
[8, 9]]
Try this :
import numpy as np
x = np.array([[4, 5, 6],
[7, 8, 9]])
a = np.array([[0, 1],
[1, 2]])
print(np.take_along_axis(x,a,1))
You can use numpy.take_along_axis
np.take_along_axis(x,a,1)
# array([[4, 5],
# [8, 9]])
or manually add the first coordinate (broadcasting applies)
x[np.c_[:2],a]
# array([[4, 5],
# [8, 9]])
I know it is technically a loop, but you can do it in one line with a list comprehension.
print(np.array([x[i][a[i]] for i in range(0, x.shape[0])]))

Concatenate two numpy arrays [duplicate]

This question already has answers here:
Concatenating two one-dimensional NumPy arrays
(6 answers)
Closed 5 years ago.
I have written this code to append two numpy arrays:
td_XN = searchNegative(X,y,10)
td_XP = searchPosotive(X,y,10)
print(np.array(td_XN).shape, np.array(td_XP).shape)
print(type(td_XN), type(td_XP))
td_X = np.concatenate(td_XP, td_XN)
td_y = [1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0]
print(td_X.shape, len(td_y))
However, it produces this error:
TypeError: only length-1 arrays can be converted to Python scalars
On this line:
td_X = np.concatenate(td_XP, td_XN)
If you want to concatenate side by side (that is, create an array of 10 -by- 2544*2): you can do
td_X = np.concatenate([td_XP, td_XN],axis=1)
For example
td_X = np.concatenate([[[1,2,3,7],[4,5,6,8]],[[1,2,3],[4,5,6]]],axis=1)
gives
array([[1, 2, 3, 7, 1, 2, 3],
[4, 5, 6, 8, 4, 5, 6]])
On the other hand, if you want to add td_XN below td_XP you can do
td_X = np.concatenate([td_XP, td_XN],axis=0)
For example,
td_X = np.concatenate([[[1,2,3],[4,5,6]],[[1,2,7],[4,5,8]]],axis=0)
gives
array([[1, 2, 3],
[4, 5, 6],
[1, 2, 7],
[4, 5, 8]])

How can I create a vector from a matrix using specified colums from each row without looping in Python? [duplicate]

This question already has answers here:
using an numpy array as indices of the 2nd dim of another array? [duplicate]
(2 answers)
Closed 6 years ago.
Say I have a matrix of shape (N,d) and a vector of size N which says which column in the matrix is of relevance to a given row. How can I return the vector of size N which is given by the values in the matrix and the relevant column?
For example:
M = [[ 2, 4, 1, 8],
[3, 5, 7, 1],
[2, 5, 3, 9],
[1, 2, 3, 4]]
V = [2, 1, 0, 1]
I tried something like:
M[:,V]
but this returns a matrix which is NXN
Is there a simple way to format this which does not involve writing a for-loop so that I could get the following vector:
V' = [1,5,2,2]
Use np.arange(len(V)) for indexing the row numbers and V for columns:
In [110]: M = [[ 2, 4, 1, 8],
.....: [3, 5, 7, 1],
.....: [2, 5, 3, 9],
.....: [1, 2, 3, 4]]
In [111]: V = [2, 1, 0, 1]
In [112]:
In [112]: M = np.array(M)
In [113]: M[np.arange(len(V)),V]
Out[113]: array([1, 5, 2, 2])

Categories