Related
Suppose I have an array a representing 3 center points of 3 rectangles. I want to create four other copied points based on each of points in array a by add 1 or minus 1 in x, y coordinates like shown in the picture.
a = np.arange(9).reshape(3,3)
>>>a
>>>out:[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]]
I'm very new to numpy. What I can think of is that I can make 4 coupies of a, for the first do a[:,0]+=1, then a[:,1]+=1. for the second do a[:,0]+=1,then a[:,1]-=1.for the third do a[:,0]-=1 then a[:,1]+=1, for the fourth do a[:,0]-=1then a[:,1]-=1. But I know it's stupid. So I 'm wondering if there is a clearer way to do it in numpy?
My expected outputs:
array_1 = [[ 1 2 2]
[ 4 5 5]
[ 7 8 8]]
array_2 = [[ 1 0 2]
[ 4 3 5]
[ 7 6 8]]
array_3 = [[ -1 2 2]
[ 2 5 5]
[ 5 8 8]]
array_4 = [[ -1 0 2]
[ 2 3 5]
[ 5 6 8]]
You can generate a 3D array:
a = np.arange(9).reshape(3,3)
b = np.array([[ 1, 1,0],
[ 1,-1,0],
[-1, 1,0],
[-1,-1,0]])
# or programmatically
from itertools import product
b = np.array(list(product([1,-1], [1,-1], [0])))
out = np.tile(a, (4,1,1))+b[:,None,:]
array([[[ 1, 2, 2],
[ 4, 5, 5],
[ 7, 8, 8]],
[[ 1, 0, 2],
[ 4, 3, 5],
[ 7, 6, 8]],
[[-1, 2, 2],
[ 2, 5, 5],
[ 5, 8, 8]],
[[-1, 0, 2],
[ 2, 3, 5],
[ 5, 6, 8]]])
Subsetting:
out[0]
array([[1, 2, 2],
[4, 5, 5],
[7, 8, 8]])
it seems that what you need is to loop over a Cartesian product, there are many ways of doing so, one is to use itertools, here goes:
import numpy as np
import itertools
a = np.arange(9).reshape(3,3)
list_of_arrays = []
for seq in itertools.product([1, -1], repeat=2):
b = a.copy()
b[:,0]+=seq[0]
b[:,1]+=seq[1]
list_of_arrays.append(b)
list_of_arrays:
[array([[1, 2, 2],
[4, 5, 5],
[7, 8, 8]]),
array([[1, 0, 2],
[4, 3, 5],
[7, 6, 8]]),
array([[-1, 2, 2],
[ 2, 5, 5],
[ 5, 8, 8]]),
array([[-1, 0, 2],
[ 2, 3, 5],
[ 5, 6, 8]])]
Using numpy broadcasting and itertools to generate the shifts:
import itertools
import numpy as np
a = np.arange(9).reshape(3, 3)
shifts = np.array([(dx, dy, 0) for dx, dy in itertools.product([1, -1], repeat=2)])
shifted_a = a + shifts[:, None]
This question already has answers here:
Transpose list of lists
(14 answers)
Closed 2 years ago.
We have an array
a = [[1, 2, 3],[4, 5, 6],[7, 8, 9]]
and looking for array:
b = [[1, 4, 7],[2, 5, 8],[3, 6, 9]]
Thank you!
Try with numpy.transpose(). See below:
import numpy as np
a = [[1, 2, 3],[4, 5, 6],[7, 8, 9]]
[list(i) for i in np.array(a).transpose()]
Output:
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
This question already has answers here:
numpy array concatenate: "ValueError: all the input arrays must have same number of dimensions"
(4 answers)
Closed 2 years ago.
My use case is causing me to struggle with numpy append and concatenate. I wanted to reach out to determine if there is a clean way of handling the following challenge.
I have two numpy arrays:
a = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
b = [10, 11, 12]
I would like to combine so that they look like this:
c = [[1, 2, 3, 10],
[4, 5, 6, 11],
[7, 8, 9, 12]]
Any help would be appreciated.
The most convenient way is np.c_ which handles 1D arrays intelligently:
a = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
b = [10, 11, 12]
np.c_[a,b]
# array([[ 1, 2, 3, 10],
# [ 4, 5, 6, 11],
# [ 7, 8, 9, 12]])
In vanilla python you can do a list comprehension with zip:
out = [u+[v] for u,v in zip(a,b)]
# [[1, 2, 3, 10], [4, 5, 6, 11], [7, 8, 9, 12]]
But since you tagged numpy, you can use hstack like this:
np.hstack((a,np.array([b]).T))
array([[ 1, 2, 3, 10],
[ 4, 5, 6, 11],
[ 7, 8, 9, 12]])
You should try this :
a = [[1,2,3],[4,5,6],[7,8,9]]
b = [10,11,12]
for k in range(len(a)):
a[k].append(b[k])
I'm not entirely sure this would work in any case but it works for that example at least. This doesn't use Numpy though, it works on Python list as well.
In addition to other answers, since you mentioned numpy and concatenate,
here is the way to do it using them:
import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
b = np.array([10, 11, 12])
print(np.concatenate((a, b.reshape((-1, 1))), axis=1))
[[ 1 2 3 10]
[ 4 5 6 11]
[ 7 8 9 12]]
Given a 2D np.array:
arr = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
How do I ravel it in an s-path such that I get
>>> sravel(arr)
array([1, 2, 3, 6, 5, 4, 7, 8, 9])
Additonally, I would like the option of going down the 0-axis first as well, i.e.
>>> sravel(arr, [0,1])
array([1, 4, 7, 8, 5, 2, 3, 6, 9])
here the second argument of the parenthesis indicates the order of axis.
I don't think there is any direct way to do that, but it's not hard to get that result:
import numpy as np
arr = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
arr2 = arr.copy()
arr2[1::2] = np.flip(arr[1::2], 1)
print(arr2.ravel())
# [1 2 3 6 5 4 7 8 9]
arr3 = arr.T.copy()
arr3[1::2] = np.flip(arr.T[1::2], 1)
print(arr3.ravel())
# [1 4 7 8 5 2 3 6 9]
EDIT: As pointed out by scleronomic, the second case can also be done by means of an F-contiguous array:
import numpy as np
arr = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
# The array is copied with F order so ravel does not require another copy later
arr3 = arr.copy(order='F')
arr3[:, 1::2] = np.flip(arr3[:, 1::2], 0)
print(arr3.ravel(order='F'))
# [1 4 7 8 5 2 3 6 9]
I have a source array:
a = array([[1, 1, 2, 2],
[3, 4, 5, 6],
[7, 7, 7, 8]])
And a vector that indicates how many times I want to tile each row of the array:
count = array([3, 1, 2])
I want to get:
results =array([[1, 1, 2, 2],
[1, 1, 2, 2],
[1, 1, 2, 2],
[3, 4, 5, 6],
[7, 7, 7, 8],
[7, 7, 7, 8]]
Is there a vectorized/numpy way to achieve this?
Currently I'm using an iterative loop approach and it's horribly slow when len(a) and/or count contains high values.
numpy.repeat() is what you are after:
Code:
np.repeat(a, count, axis=0)
Test Code:
import numpy as np
a = np.array([[1, 1, 2, 2],
[3, 4, 5, 6],
[7, 7, 7, 8]])
count = np.array([3, 1, 2])
print(np.repeat(a, count, axis=0))
Results:
[[1 1 2 2]
[1 1 2 2]
[1 1 2 2]
[3 4 5 6]
[7 7 7 8]
[7 7 7 8]]