How to change values in an area of an array? - python

A = np.array([[1,2,3],[4,1,3],[6,7,1]])
array([[1, 2, 3],
[4, 1, 3],
[6, 7, 1]])
I need to transform every 1 to a 23 but only on a subset of the array.
I want to start at the index 1:1 and stop at 2:2
array([[1, 2, 3],
[4, 23, 3],
[6, 7, 23]])

>>>A = np.array([[1,2,3],[4,1,3],[6,7,1]])
array([[1, 2, 3],
[4, 1, 3],
[6, 7, 1]])
>>>b = A[1:,1:]==1
>>>A[1:,1:][b]=23
>>>A
array([[ 1, 2, 3],
[ 4, 23, 3],
[ 6, 7, 23]])

Related

Numpy Split array to sub arrays by specific number of elements

for example
I have a point list
a = np.array([[0,0,0],
[1,1,1],
[2,2,2],
[3,3,3],
[4,4,4],
[5,5,5],
[6,6,6],
[7,7,7],
[8,8,8],
[9,9,9]])
and I have another array represents the number of elements
b = np.array([2,0,3,5])
how can I split array a according the number of elements of array b so that I can get the output
[[[0,0,0],[1,1,1]],
[],
[[2,2,2],[3,3,3],[4,4,4]],
[[5,5,5],[6,6,6],[7,7,7],[8,8,8],[9,9,9]]]
You can use numpy.split using cumsum on b to get the split points:
out = np.split(a, b.cumsum()[:-1])
output:
[array([[0, 0, 0],
[1, 1, 1]]),
array([], shape=(0, 3), dtype=int64),
array([[2, 2, 2],
[3, 3, 3],
[4, 4, 4]]),
array([[5, 5, 5],
[6, 6, 6],
[7, 7, 7],
[8, 8, 8],
[9, 9, 9]])]
If you want lists:
out = [x.tolist() for x in np.split(a, b.cumsum()[:-1])]
output:
[[[0, 0, 0], [1, 1, 1]],
[],
[[2, 2, 2], [3, 3, 3], [4, 4, 4]],
[[5, 5, 5], [6, 6, 6], [7, 7, 7], [8, 8, 8], [9, 9, 9]]]
intermediate:
b.cumsum()[:-1]
# array([2, 2, 5])

Stack every two elements of the third dimension in a numpy 3d array

I have a numpy array of shape (294, 62, 350). Along the third dimension (the 350), I need to combine every two columns into one longer one which would result in an array of shape (294, 124, 175). For example if I have this array:
a_3d_array = np.array([[[1, 2, 3, 6, 1, 2], [3, 4, 3, 6, 1, 4]],
[[5, 2, 2, 1, 4, 2], [2, 9, 4, 3, 2, 7]]])
The expected output would be:
expected_output = np.array([[[5, 2, 4], [2, 4, 2], [ 2, 1, 2], [9, 3, 7]],
[[1, 3, 1], [3, 3, 1], [2, 6, 2], [4, 6, 4]]])
Sorry as I'm new to python and I don't have a clue how to approach this and thus I don't have a "my own attempt" to include here.
a_3d_array = np.array([[[1, 2, 3, 6, 1, 2], [3, 4, 3, 6, 1, 4]],
[[5, 2, 2, 1, 4, 2], [2, 9, 4, 3, 2, 7]]])
output = np.hstack([a_3d_array[:, :, ::2], a_3d_array[:, :, 1::2]])
To combine every N-th column:
N = 3
output = np.hstack([an_array[:, :, idx::N] for idx in range(N)])
You can reshape and reverse the first dimension:
a_3d_array.reshape((2,4,3), order='F')[::-1]
If you don't know the shape:
x,y,z = a_3d_array.shape
a_3d_array.reshape((x,y*2,-1), order='F')[::-1]
output:
array([[[5, 2, 4],
[2, 4, 2],
[2, 1, 2],
[9, 3, 7]],
[[1, 3, 1],
[3, 3, 1],
[2, 6, 2],
[4, 6, 4]]])

Appending to numpy array column wise

I have an array
a = np.array([
[1, 2, 3],
[2, 3, 4]
])
and 3 more column wise arrays
b=np.array([[1],
[2],
[3]])
c=np.array([[5],
[6],
[7]])
d=np.array([[9],
[10],
[11]])
I want to concatenate my array such the column wise arrays are appended to the original array "a" like this
a = np.array([
[1, 2, 3],
[2, 3, 4],
[1, 5, 9],
[2, 6, 10],
[3, 7, 11],
])
def st():
a = np.array([[1, 2, 3],[2, 3, 4]])
b=np.array([[1],[2],[3]])
c=np.array([[5],[6],[7]])
d=np.array([[9],[10],[11]])
return np.vstack([a, np.hstack([b,c,d])])
Results:
>>> st()
array([[ 1, 2, 3],
[ 2, 3, 4],
[ 1, 5, 9],
[ 2, 6, 10],
[ 3, 7, 11]])

numpy select values based on list of indices. Process batch at once [duplicate]

Suppose I have a matrix A with some arbitrary values:
array([[ 2, 4, 5, 3],
[ 1, 6, 8, 9],
[ 8, 7, 0, 2]])
And a matrix B which contains indices of elements in A:
array([[0, 0, 1, 2],
[0, 3, 2, 1],
[3, 2, 1, 0]])
How do I select values from A pointed by B, i.e.:
A[B] = [[2, 2, 4, 5],
[1, 9, 8, 6],
[2, 0, 7, 8]]
EDIT: np.take_along_axis is a builtin function for this use case implemented since numpy 1.15. See #hpaulj 's answer below for how to use it.
You can use NumPy's advanced indexing -
A[np.arange(A.shape[0])[:,None],B]
One can also use linear indexing -
m,n = A.shape
out = np.take(A,B + n*np.arange(m)[:,None])
Sample run -
In [40]: A
Out[40]:
array([[2, 4, 5, 3],
[1, 6, 8, 9],
[8, 7, 0, 2]])
In [41]: B
Out[41]:
array([[0, 0, 1, 2],
[0, 3, 2, 1],
[3, 2, 1, 0]])
In [42]: A[np.arange(A.shape[0])[:,None],B]
Out[42]:
array([[2, 2, 4, 5],
[1, 9, 8, 6],
[2, 0, 7, 8]])
In [43]: m,n = A.shape
In [44]: np.take(A,B + n*np.arange(m)[:,None])
Out[44]:
array([[2, 2, 4, 5],
[1, 9, 8, 6],
[2, 0, 7, 8]])
More recent versions have added a take_along_axis function that does the job:
A = np.array([[ 2, 4, 5, 3],
[ 1, 6, 8, 9],
[ 8, 7, 0, 2]])
B = np.array([[0, 0, 1, 2],
[0, 3, 2, 1],
[3, 2, 1, 0]])
np.take_along_axis(A, B, 1)
Out[]:
array([[2, 2, 4, 5],
[1, 9, 8, 6],
[2, 0, 7, 8]])
There's also a put_along_axis.
I know this is an old question, but another way of doing it using indices is:
A[np.indices(B.shape)[0], B]
output:
[[2 2 4 5]
[1 9 8 6]
[2 0 7 8]]
Following is the solution using for loop:
outlist = []
for i in range(len(B)):
lst = []
for j in range(len(B[i])):
lst.append(A[i][B[i][j]])
outlist.append(lst)
outarray = np.asarray(outlist)
print(outarray)
Above can also be written in more succinct list comprehension form:
outlist = [ [A[i][B[i][j]] for j in range(len(B[i]))]
for i in range(len(B)) ]
outarray = np.asarray(outlist)
print(outarray)
Output:
[[2 2 4 5]
[1 9 8 6]
[2 0 7 8]]

How to replace each array element by 4 copies in Python?

How do I use numpy / python array routines to do this ?
E.g. If I have array [ [1,2,3,4,]] , the output should be
[[1,1,2,2,],
[1,1,2,2,],
[3,3,4,4,],
[3,3,4,4]]
Thus, the output is array of double the row and column dimensions. And each element from original array is repeated three times.
What I have so far is this
def operation(mat,step=2):
result = np.array(mat,copy=True)
result[::2,::2] = mat
return result
This gives me array
[[ 98.+0.j 0.+0.j 40.+0.j 0.+0.j]
[ 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
[ 29.+0.j 0.+0.j 54.+0.j 0.+0.j]
[ 0.+0.j 0.+0.j 0.+0.j 0.+0.j]]
for the input
[[98 40]
[29 54]]
The array will always be of even dimensions.
Use np.repeat():
In [9]: A = np.array([[1, 2, 3, 4]])
In [10]: np.repeat(np.repeat(A, 2).reshape(2, 4), 2, 0)
Out[10]:
array([[1, 1, 2, 2],
[1, 1, 2, 2],
[3, 3, 4, 4],
[3, 3, 4, 4]])
Explanation:
First off you can repeat the arrya items:
In [30]: np.repeat(A, 3)
Out[30]: array([1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4])
then all you need is reshaping the result (based on your expected result this can be different):
In [32]: np.repeat(A, 3).reshape(2, 3*2)
array([[1, 1, 1, 2, 2, 2],
[3, 3, 3, 4, 4, 4]])
And now you should repeat the result along the the first axis:
In [34]: np.repeat(np.repeat(A, 3).reshape(2, 3*2), 3, 0)
Out[34]:
array([[1, 1, 1, 2, 2, 2],
[1, 1, 1, 2, 2, 2],
[1, 1, 1, 2, 2, 2],
[3, 3, 3, 4, 4, 4],
[3, 3, 3, 4, 4, 4],
[3, 3, 3, 4, 4, 4]])
Another approach could be with np.kron -
np.kron(a.reshape(-1,2),np.ones((2,2),dtype=int))
Basically, we reshape input array into a 2D array keeping the second axis of length=2. Then np.kron essentially replicates the elements along both rows and columns for a length of 2 each with that array : np.ones((2,2),dtype=int).
Sample run -
In [45]: a
Out[45]: array([7, 5, 4, 2, 8, 6])
In [46]: np.kron(a.reshape(-1,2),np.ones((2,2),dtype=int))
Out[46]:
array([[7, 7, 5, 5],
[7, 7, 5, 5],
[4, 4, 2, 2],
[4, 4, 2, 2],
[8, 8, 6, 6],
[8, 8, 6, 6]])
If you would like to have 4 rows, use a.reshape(2,-1) instead.
The better solution is to use numpy but you could use iteration also:
a = [[1, 2, 3, 4]]
v = iter(a[0])
b = []
for i in v:
n = next(v)
[b.append([i for k in range(2)] + [n for k in range(2)]) for j in range(2)]
print b
>>> [[1, 1, 2, 2], [1, 1, 2, 2], [3, 3, 4, 4], [3, 3, 4, 4]]

Categories

Resources