lets assume that i have a numpy array and its like this:
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12]]
and I like to have a new numpy array, that the first half exactly the same as array above but second half it should be started from the bottom till it reaches the half of array. how do I do that?
EDIT: The method i need it has to work for an array with 60000 elements. not for this simple example!!
Output should be like this:
[[1, 2, 3],
[4, 5, 6],
[10, 11, 12],
[7, 8, 9]]
Use numpy indexes:
array = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
array[[0,1,3,2], :]
array([[ 1, 2, 3],
[ 4, 5, 6],
[10, 11, 12],
[ 7, 8, 9]])
Another solution would be to simply swap the rows with an assignment, like:
arr[2], arr[3] = arr[3], arr[2]
After your edit, here's a solution that inverts just the bottom half of the array:
arr = np.array([[...],...])
arr[int(len(a)/2):] = arr[int(len(a)/2):][::-1]
[::-1] returns the elements of an array in reverse order. So applying it to the bottom half of the original array and assigning this new array to the bottom half of the original array will give you an array with the first n/2 rows unchanged and last n/2 rows in reverse order.
This might be kinda crude but you simply need to replace the 3rd (index = 2) row in array e with the 4th (index = 3) row. 'a' is a placeholder for switching the 3rd and 4th row.
for i in range(len(e)):
if i == 2:
a = e[i]
e[i] = e[3]
if i == 3:
e[i] = a
Takes always half the array as requested. (Based on mathfux's answer)
array = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
sl = range(0, len(array)//2)
s2 = reversed(range(len(array)//2, len(array)))
b = array[(*sl, *s2), :]
print(b)
prints
[[ 1 2 3]
[ 4 5 6]
[10 11 12]
[ 7 8 9]]
Of course cou could just index the last half:
array = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
from_to = tuple(range(len(array)//2, len(array)))
to_from = tuple(reversed(from_to))
array[from_to, :] = array[to_from, :]
print(array)
Same result.
array = numpy.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
n = (int)(array.shape[0]//2) # change n accordingly
# n is the row number from which you want to start the reversal
temp = array[n:]
temp = temp[::-1]
array[n:] = temp
Related
I have a Matrix of indices I e.g.
I = np.array([[1, 0, 2], [2, 1, 0]])
The index at i-th row selects an element from another Matrix M in the i-th row.
So having M e.g.
M = np.array([[6, 7, 8], [9, 10, 11])
M[I] should select:
[[7, 6, 8], [11, 10, 9]]
I could have:
I1 = np.repeat(np.arange(0, I.shape[0]), I.shape[1])
I2 = np.ravel(I)
Result = M[I1, I2].reshape(I.shape)
but this looks very complicated and I am looking for a more elegant solution. Preferably without flattening and reshaping.
In the example I used numpy, but I am actually using jax. So if there is a more efficient solution in jax, feel free to share.
In [108]: I = np.array([[1, 0, 2], [2, 1, 0]])
...: M = np.array([[6, 7, 8], [9, 10, 11]])
...:
...: I,M
I had to add a ']' to M.
Out[108]:
(array([[1, 0, 2],
[2, 1, 0]]),
array([[ 6, 7, 8],
[ 9, 10, 11]]))
Advanced indexing with broadcasting:
In [110]: M[np.arange(2)[:,None],I]
Out[110]:
array([[ 7, 6, 8],
[11, 10, 9]])
THe first index has shape (2,1) which pairs with the (2,3) shape of I to select a (2,3) block of values.
How about this one line code? The idea is to enumerate both the rows and the row indices of the matrix, so you can access the corresponding rows in the indexing matrix.
import numpy as np
I = np.array([[1, 0, 2], [2, 1, 0]])
M = np.array([[6, 7, 8], [9, 10, 11]])
Result = np.array([row[I[i]] for i, row in enumerate(M)])
print(Result)
Output:
[[ 7 6 8]
[11 10 9]]
np.take_along_axis can also be used here to take values of M using indices I over axis=1:
>>> np.take_along_axis(M, I, axis=1)
array([[ 7, 6, 8],
[11, 10, 9]])
I'm working with numpy and I hit a roadblock, I think it's an easy question and can be done using indexing, but I still haven't figure it out. So I have 2D array and from each row I get the index of the minimum value, what I want is to use this index to add values to the 2D array, here is an example
a = np.array([[9, 4, 9, 9],
[1, 6, 4, 6],
[8, 7, 1, 5],
[8, 9, 2, 7]])
values = np.array([1, 2, 3, 4])
minimum = np.argmin(a, axis = 1) #To find the index of the minimum values
print(minimum) #minimum = [1, 0, 2, 2]
So in the first row of the 2D array and the first index of the minimum array I want to add the value of 1, in the second row of the 2D array using the second index, I want to add the value of 2 and so on, my desired output should be something like this.
output = [[9, 5, 9, 9],
[3, 6, 4, 6],
[8, 7, 4, 5],
[8, 9, 6, 7]]
I try this, but I failed:
newarray = a[:, minimum] + values
newarray = [[ 5, 11, 12, 13],
[ 7, 3, 7, 8],
[ 8, 10, 4, 5],
[10, 10, 5, 6]]
Thank you for all your help!
You were close. Try this:
newarray = a.copy()
newarray[np.arange(len(a)), minimum] += values
Lets say we have a numpy array:
A = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12]])
Can anyone explain why this line is used to swap two rows(in this occasion the 1st with the 4th)?
'A[[0, 3]] = A [[3, 0]]'
You are updating the positions of two subarrays simultaneously.
However, doing:
A[0] = A[3]
A[3] = A[0]
would not work because the subarray A[0] has already been updated, so you need to do it simultaneously with:
A[[0, 3]] = A [[3, 0]]
A
array([[10, 11, 12],
[ 4, 5, 6],
[ 7, 8, 9],
[ 1, 2, 3]])
I would like to know if there is any fast way to sum each row of a first array with all rows of a second array. In this case both arrays have the same number of colulmns. For instance if array1.shape = (n,c) and array2.shape = (m,c), the resulting array would be an array3.shape = ((n*m), c)
Look at the example below:
array1 = np.array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
array2 = np.array([[0, 1, 2],
[3, 4, 5]])
The result would be:
array3 = np.array([[0, 2, 4],
[3, 5, 7]
[3, 5, 7]
[6, 8, 10]
[6, 8, 10]
[9, 11, 13]])
The only way I see I can do this is to repeat each row of one of the arrays the number of rows of the other array. For instance, by doing np.repeat(array1, len(array2), axis=0) and then sum this array with array2. This is not very practical however if the number of rows is too big. The other way would be with a for loop but this is too slow.
Any other better way to do it..?
Thanks in advance.
Extend array1 to 3D so that it becomes broadcastable against 2D array2 and then perform broadcasted addition and a final reshape is needed for desired output -
In [30]: (array1[:,None,:] + array2).reshape(-1,array1.shape[1])
Out[30]:
array([[ 0, 2, 4],
[ 3, 5, 7],
[ 3, 5, 7],
[ 6, 8, 10],
[ 6, 8, 10],
[ 9, 11, 13]])
You could try the following inline code if you haven't already. This is the simplest and probably also the quickest on a single thread.
>>> import numpy as np
>>> array1 = np.array([[0, 1, 2],
... [3, 4, 5],
... [6, 7, 8]])
>>>
>>> array2 = np.array([[0, 1, 2],
... [3, 4, 5]])
>>> array3 = np.array([i+j for i in array1 for j in array2])
>>> array3
array([[ 0, 2, 4],
[ 3, 5, 7],
[ 3, 5, 7],
[ 6, 8, 10],
[ 6, 8, 10],
[ 9, 11, 13]])
>>>
If you are looking for speed up by treading, you could consider using CUDA or multithreading. This suggestion goes a bit out of scope of your question but gives you an idea of what can be done to speed up matrix operations.
I have an m X 3 matrix and an array of length m.
I want to do the following
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15]])
b = np.array([1, 2, 1, 3, 3])
me = np.mean(a[np.where(b==1)][:, 0])
a[np.where(b==1)][:, 0] = me
The problem is that
a[np.where(b==1)][:, 0]
returns [1, 7] instead of [4, 4].
You are combining index arrays with slices:
[np.where(b==1)] is a index array, [:, 0] is a slice. The way you do it a copy is returned and therefore you set the new values on the copy. You should instead do:
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15]])
b = np.array([1, 2, 1, 3, 3])
me = np.mean(a[np.where(b==1)][:, 0])
a[np.where(b==1), 0] = me
Also see https://docs.scipy.org/doc/numpy/user/basics.indexing.html for combining index arrays with slices.