Modify a particular row/column of a NumPy array - python

How do I modify particular a row or column of a NumPy array?
For example I have a NumPy array as follows:
P = array([[1, 2, 3],
[4, 5, 6]])
How do I change the elements of first row, [1, 2, 3], to [7, 8, 9] so that the P will become:
P = array([[7, 8, 9],
[4, 5, 6]])
Similarly, how do I change second column values, [2, 5], to [7, 8]?
P = array([[1, 7, 3],
[4, 8, 6]])

Rows and columns of NumPy arrays can be selected or modified using the square-bracket indexing notation in Python.
To select a row in a 2D array, use P[i]. For example, P[0] will return the first row of P.
To select a column, use P[:, i]. The : essentially means "select all rows". For example, P[:, 1] will select all rows from the second column of P.
If you want to change the values of a row or column of an array, you can assign it to a new list (or array) of values of the same length.
To change the values in the first row, write:
>>> P[0] = [7, 8, 9]
>>> P
array([[7, 8, 9],
[4, 5, 6]])
To change the values in the second column, write:
>>> P[:, 1] = [7, 8]
>>> P
array([[1, 7, 3],
[4, 8, 6]])

In a similar way if you want to select only two last columns for example but all rows you can use:
print P[:,1:3]

If you have lots of elements in a column:
import numpy as np
np_mat = np.array([[1, 2, 2],
[3, 4, 5],
[5, 6, 5]])
np_mat[:,2] = np_mat[:,2] * 3
print(np_mat)
It is making a multiplied by 3 change in third column:
[[ 1 2 6]
[ 3 4 15]
[ 5 6 15]]

Related

In a specific row of a numpy array, how to find column indexes of the top 3 largest values

I have an array X:
X = np.array([[4, 3, 5, 2],
[9, 6, 7, 3],
[8, 6, 7, 5],
[3, 4, 5, 3],
[5, 3, 2, 6]])
I want the indices of the top 3 greatest values in a row with index 1. The result of that would be :
[0,2,1]
I am relatively new to Python. I tried doing it with argsort, but am not able to do it for one specific row.
You can use argsort on axis=1 (by row) and then extract the last 3 indices for each row:
X.argsort(axis=1)[:,:-4:-1]
#[[2 0 1]
# [0 2 1]
# [0 2 1]
# [2 1 3]
# [3 0 1]]
X = np.array([[4, 3, 5, 2],
[9, 6, 7, 3],
[8, 6, 7, 5],
[3, 4, 5, 3],
[5, 3, 2, 6]])
# get top 3 values in the row with index 1
row_sorted = sorted(X[1], reverse=True)[0:3]
# Find the corresponding index of theses top 3 values
indexes = [list(X[1]).index(i) for i in row_sorted]
output:
[0, 2, 1]
For sufficiently large arrays, np.argpartition will be the most efficient solution. It will place the last three elements of the sort indices in the right positions:
i = np.argpartition(x[1], [-3, -2, -1])[:-4:-1]
This behaves similarly to np.argsort except that only the selected indices are in the right place. All the other elements are only guaranteed to be in the correct side relative to each partition point, but not the exact position.

Which way are rows and columns in a numpy 2-d array used as a matrix?

When using a numpy array as a matrix, in which order are rows and columns?
For example:
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
Is [1, 2, 3] the first row or the first column?
I cannot find this information in the documentation, perhaps because the answer is too obvious.
[1, 2, 3] is the first row.
The examples in numpy ndarray documentation actually gives you some hints:
>>> x = np.array([[1, 2, 3], [4, 5, 6]], np.int32)
>>> # The element of x in the *second* row, *third* column, namely, 6.
>>> x[1, 2] ```

How to sort an nx3 numpy array by column(s) but it remembers the data in that row?

First off, I'm very new to python and so any tips/help is really appreciated.
Essentially I want an nx3 numpy array to be sorted initially by the second column then by the third but I want all of the data in the row to remain with each other.
Like so:
import numpy as np
a = np.array([[20, 2, 4],
[7, 5, 6],
[25, 1, 5],
[2, 2, 3],
[3, 5, 8],
[4, 1, 3]])
......... (n times)
In this array the first column represents the value, the second it's x coordinate and the third its y coordinate. What is the best way to do a descending sort the array by first the x coordinate, then do a descending sort on the y coordinate whilst value still stays assigned to the x and y coordinate?
So after the sort, it looks like this:
a = ([[4, 1, 3],
[25, 1, 5],
[2, 2, 3],
[20, 2, 4],
[7, 5, 6],
[3, 5, 8]])
......... (n times)
As you can see how can it first sort the x coordinate then with sort all the y coordinates which have the same x coordinates. As it first finds all x coordinates of 1 then within that sort the y coordinates. Whilst the value, x and y coordinates all remain on the same row with each other.
Easiest way is to convert it into a pandas dataframe then it's easier to manipulate it.
import pandas as pd
df = pd.DataFrame({'a': [6, 2, 1], 'b': [4, 5, 6]})
print(df)
Out
a b
0 6 4
1 2 5
2 1 6
sorteddf = df.sort_values(by='a')
print(sorteddf)
Out
a b
2 1 6
1 2 5
0 6 4
Take a look at the 'order' parameter: https://docs.scipy.org/doc/numpy/reference/generated/numpy.sort.html
import numpy as np
dtype = [('x',int),('y',int)]
values = [(1,7),(3,4),(1,4),(1,3)]
a = np.array(values,dtype=dtype)
print(np.sort(a, order=['x','y']))
The easiest way is to first sort by y and then sort the result by x, so for equals values of x the final result will be sorted by y.
Full code:
import numpy as np
a = np.array([[20, 2, 4],
[7, 5, 6],
[25, 1, 5],
[2, 2, 3],
[3, 5, 8],
[4, 1, 3]])
a = a[a[:,2].argsort()] # sort according to column 2
a = a[a[:,1].argsort()] # sort according to column 1
result
a
array([[ 4, 1, 3],
[25, 1, 5],
[ 2, 2, 3],
[20, 2, 4],
[ 7, 5, 6],
[ 3, 5, 8]])

Add a matrix outside a loop

I have a function that gives me a matrix of 17*3 (float (17,3)). I call that function again and again in a loop, i want to add the matrices so that rows remain 17 but column keeps on adding to make one big matrix.
Without NUMPY:
Transpose the matrix first because you are not gonna touch the 17 rows.
# a matrix is 17 * 3
a_transpose = [[a[j][i] for j in range(len(a))] for i in range(len(a[0]))]
Then, add the column of 17 rows as one row of 17 columns
a_transpose.append([1,2,3, ... 17])
Once, you are done adding several rows, transpose the matrix back as said above. That way, you don't iterate through your array 17 times everytime you add a column to your matrix.
With NUMPY:
Transpose
# a matrix is 17 * 3
a = numpy.array(a)
a_transpose = a.transpose()
Add a row (17 column values you wanted to add)
a_transpose.append([1,2,3, .... 17], axis=0)
Your function:
In [187]: def foo(i):
...: return np.arange(i,i+6).reshape(3,2)
...:
Iteratively build a list of arrays:
In [188]: alist = []
In [189]: for i in range(4):
...: alist.append(foo(i))
...:
In [190]: alist
Out[190]:
[array([[0, 1],
[2, 3],
[4, 5]]), array([[1, 2],
[3, 4],
[5, 6]]), array([[2, 3],
[4, 5],
[6, 7]]), array([[3, 4],
[5, 6],
[7, 8]])]
Make an array from that list:
In [191]: np.concatenate(alist, axis=1)
Out[191]:
array([[0, 1, 1, 2, 2, 3, 3, 4],
[2, 3, 3, 4, 4, 5, 5, 6],
[4, 5, 5, 6, 6, 7, 7, 8]])

How to remove a column from a numpy array if the column has a specified element? (Python)

For example, I have a 2D Array with dimensions 3 x 3.
[1 2 7
4 5 6
7 8 9]
And I want to remove all columns which contain 7 - so first and third, outputting a 3 x 1 matrix of:
[2
5
8]
How do I go about doing this in python? I want to apply it to a large matrix of n x n dimensions.
Thank You!
#Creating array
x = np.array([[1, 2, 7],[4,5, 6],[7,8,9]])
x
Out[]:
array([[1, 2, 7],
[4, 5, 6],
[7, 8, 9]])
#Deletion
a = np.delete(x,np.where(x ==7),axis=1)
a
Out[]:
array([[2],
[5],
[8]])
numpy can help you do this!
import numpy as np
a = np.array([1, 2, 7, 4, 5, 6, 7, 8, 9]).reshape((3, 3))
b = np.array([col for col in a.T if 7 not in col]).T
print(b)
If you don't actually want to delete parts of the original matrix, you can just use boolean indexing:
a
Out[]:
array([[1, 2, 7],
[4, 5, 6],
[7, 8, 9]])
a[:, ~np.any(a == 7, axis = 1)]
Out[]:
array([[2],
[5],
[8]])
you can use argwhere for column index and then delete.
import numpy
a = numpy.array([[5, 2, 4],[1, 7, 3],[1, 2, 7]])
index = numpy.argwhere(a==7)
y = numpy.delete(a, index, axis=1)
print(y)
A = np.array([[1,2,7],[4,5,6],[7,8,9]])
for i in range(0,3):
... B=A[:,i]
... if(7 in B):
... A=np.delete(A,i,1)

Categories