I have a simple numpy array. I want to select all rows but 1st and 6th
I tried:
temp = np.array([1,2,3,4,5,6,7,8,9])
t = temp[~[0,5]]
I get the following error:
TypeError: bad operand type for unary ~: 'list'
What is the correct way to do this?
You can use numpy.delete to delete elements at a specific index position:
t = np.delete(temp, [0, 5])
Or you can create an boolean array, than it is possible to negate the indices:
bool_idx = np.zeros(len(temp), dtype=bool)
bool_idx[[0, 5]] = True
t = temp[~bool_idx]
You cant create the indices that way. Instead you could create a range of numbers from 0 to temp.size and delete the unwanted indices:
In [19]: ind = np.delete(np.arange(temp.size), [0, 5])
In [21]: temp[ind]
Out[21]: array([2, 3, 4, 5, 7, 8, 9])
Or just create it like following:
In [16]: ind = np.concatenate((np.arange(1, 5), np.arange(6, temp.size)))
In [17]: temp[ind]
Out[17]: array([2, 3, 4, 5, 7, 8, 9])
You can use the np.r_ numpy object which concatenates the array into by breaking them using the indices giving the resultant output.
np.r_[temp[1:5], temp[6:]]
The code above concatenates the two arrays which are sliced from the original array and hence the resultant array without the indices specified.
Related
I need to extract one element from each column of a matrix according to an index vector. Say:
index = [0,1,1]
matrix = [[1,4,7],[2,5,8],[3,6,9]]
Index vector tells me I need the first element from column 1, second element from column 2, and third element from column 3.
The output should be [1,5,8]. How can I write it out without explicit loop?
Thanks
You can use advanced indexing:
index = np.array([0,1,2])
matrix = np.array([[1,4,7],[2,5,8],[3,6,9]])
res = matrix[np.arange(matrix.shape[0]), index]
# array([1, 5, 9])
For your second example, reverse your indices:
index = np.array([0,1,1])
matrix = np.array([[1,4,7],[2,5,8],[3,6,9]])
res = matrix[index, np.arange(matrix.shape[1])]
# array([1, 5, 8])
Since you're working with 2-dimensional matrices, I'd suggest using numpy. Then, in your case, you can just use np.diag:
>>> import numpy as np
>>> matrix = np.array([[1,4,7],[2,5,8],[3,6,9]])
>>> matrix
array([[1, 4, 7],
[2, 5, 8],
[3, 6, 9]])
>>> np.diag(matrix)
array([1, 5, 9])
However, #jpp's solution is more generalizable. My solution is useful in your case because you really just want the diagonal of your matrix.
val = [matrix[i][index[i]] for i in range(0, len(index))]
In Python, i need to split two rows in half, take the first half from row 1 and second half from row 2 and concatenate them into an array which is then saved as a row in another 2d array. for example
values=np.array([[1,2,3,4],[5,6,7,8]])
will become
Y[2,:]= ([1,2,7,8])) // 2 is arbitrarily chosen
I tried doing this with concatenate but got an error
only integer scalar arrays can be converted to a scalar index
x=values.shape[1]
pop[y,:]=np.concatenate(values[temp0,0:int((x-1)/2)],values[temp1,int((x-1)/2):x+1])
temp0 and temp1 are integers, and values is a 2d integer array of dimensions (100,x)
np.concatenate takes a list of arrays, plus a scalar axis parameter (optional)
In [411]: values=np.array([[1,2,3,4],[5,6,7,8]])
...:
Nothing wrong with how you split values:
In [412]: x=values.shape[1]
In [413]: x
Out[413]: 4
In [415]: values[0,0:int((x-1)/2)],values[1,int((x-1)/2):x+1]
Out[415]: (array([1]), array([6, 7, 8]))
wrong:
In [416]: np.concatenate(values[0,0:int((x-1)/2)],values[1,int((x-1)/2):x+1])
----
TypeError: only integer scalar arrays can be converted to a scalar index
It's trying to interpret the 2nd argument as an axis parameter, hence the scalar error message.
right:
In [417]: np.concatenate([values[0,0:int((x-1)/2)],values[1,int((x-1)/2):x+1]])
Out[417]: array([1, 6, 7, 8])
There are other concatenate front ends. Here hstack would work the same. np.append takes 2 arrays, so would work - but too often people use it wrongly. np.r_ is another front end with different syntax.
The indexing might be clearer with:
In [423]: idx = (x-1)//2
In [424]: np.concatenate([values[0,:idx],values[1,idx:]])
Out[424]: array([1, 6, 7, 8])
Try numpy.append
numpy.append Documentation
np.append(values[temp0,0:int((x-1)/2)],values[temp1,int((x-1)/2):x+1])
You don't need splitting and/or concatenation. Just use indexing:
In [47]: values=np.array([[1,2,3,4],[5,6,7,8]])
In [48]: values[[[0], [1]],[[0, 1], [-2, -1]]]
Out[48]:
array([[1, 2],
[7, 8]])
Or ravel to get the flattened version:
In [49]: values[[[0], [1]],[[0, 1], [-2, -1]]].ravel()
Out[49]: array([1, 2, 7, 8])
As a more general approach you can also utilize np.r_ as following:
In [61]: x, y = values.shape
In [62]: values[np.arange(x)[:,None],[np.r_[0:y//2], np.r_[-y//2:0]]].ravel()
Out[62]: array([1, 2, 7, 8])
Reshape to split the second dimension in two; stack the part you want.
a = np.array([[1,2,3,4],[5,6,7,8]])
b = a.reshape(a.shape[0], a.shape[1]//2, 2)
new_row = np.hstack([b[0,0,:], b[1,1,:]])
#new_row = np.hstack([b[0,0], b[1,1]])
I have 1D array in numpy, and I want to add a certain value to part of the array.
For example, if the array is:
a = [1, 2, 3, 4, 5]
I want to add the value 7 to 2nd and 3rd columns to get:
a = [1, 2, 10, 11, 5]
Is there any simple way to do this?
Thanks!
You can index the array with another array containing the indices:
a[[2,3]] += 7
If your columns have some pattern, like in this specific case, they are contiguous, then you can use fancy indexing:
a = np.array([1, 2, 3, 4, 5])
a[2:4] += 7
Note here 2:4 means "from column 2(included) to column 4(excluded)", thus it's column 2 and 3.
Assuming that I have a numpy array such as:
import numpy as np
arr = np.array([10,1,2,5,6,2,3,8])
How could I extract an array containing the indices of the elements smaller than 6 so I get the following result:
np.array([1,2,3,5,6])
I would like something that behave like np.nonzero() but instead of testing for nonzero value, it test for value smaller than x
You can use numpy.flatnonzero on the boolean mask and Return indices that are non-zero in the flattened version of a:
np.flatnonzero(arr < 6)
# array([1, 2, 3, 5, 6])
Another option on 1d array is numpy.where:
np.where(arr < 6)[0]
# array([1, 2, 3, 5, 6])
The simplest way one can do this is by
arr[arr<6]
I'd suggest a cleaner and self-explainable way to do so:
First, find the indices where the condition is valid:
>> indices = arr < 6
>> indices
>> [False, True, True, True, False, True, False]
Then, use the indices for indexing:
>> arr[indices]
>> [1, 2, 5, 2, 3]
or for finding the right position in the original array:
>> np.where(indices)[0]
>> [1, 2, 3, 5, 6]
Suppose I have an N-dimensional np.array (or just a list) and a list of N indices. What is the preferred/efficient way to index the array without using loops?
# 4D array with shape of (2, 3, 4, 5)
arr = np.random.random((2, 3, 4, 5))
index = [0, 2, 1, 3]
result = ??? # Equivalent to arr[0, 2, 1, 3]
Additionally, supplying only a 3D index the result should be an array of the last dimension.
index = [0, 2, 1]
result2 = ??? # Equivalent to arr[0, 2, 1]
Please note that I am not able to just index with the usual syntax because the implementation has to handle arrays of different shapes.
I am aware that NumPy supports indexing by an array but that behaves differently as it cherry-picks values from the array rather by indexing by dimension (https://docs.scipy.org/doc/numpy/user/basics.indexing.html).
Per the docs:
If one supplies to the index a tuple, the tuple will be interpreted as a list of indices.
Therefore, change index to a tuple:
In [46]: np.allclose(arr[tuple([0,2,1])], arr[0,2,1])
Out[46]: True
In [47]: np.allclose(arr[tuple([0,2,1,3])], arr[0,2,1,3])
Out[47]: True