Change my 2D numpy array's 1st index with another 1D array [duplicate] - 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 first 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]

Related

Modify different columns in each row of a 2D NumPy array

I have the following problem:
Let's say I have an array defined like this:
A = np.array([[1,2,3],[4,5,6],[7,8,9]])
What I would like to do is to make use of Numpy multiple indexing and set several elements to 0. To do that I'm creating a vector:
indices_to_remove = [1, 2, 0]
What I want it to mean is the following:
Remove element with index '1' from the first row
Remove element with index '2' from the second row
Remove element with index '0' from the third row
The result should be the array [[1,0,3],[4,5,0],[0,8,9]]
I've managed to get values of the elements I would like to modify by following code:
values = np.diagonal(np.take(A, indices, axis=1))
However, that doesn't allow me to modify them. How could this be solved?
You could use integer array indexing to assign those zeros -
A[np.arange(len(indices_to_remove)), indices_to_remove] = 0
Sample run -
In [445]: A
Out[445]:
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
In [446]: indices_to_remove
Out[446]: [1, 2, 0]
In [447]: A[np.arange(len(indices_to_remove)), indices_to_remove] = 0
In [448]: A
Out[448]:
array([[1, 0, 3],
[4, 5, 0],
[0, 8, 9]])

How to add new column to existing csv file

For instance, x is my data and r is supposed to be new data to be added.
import numpy as np
x = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]], np.int32)
np.savetxt("test.csv", x, fmt='%d', delimiter=',')
r = [1,2,3]
how could I add it to that "test.csv"
You can insert a new column by using the insert function in numpy like so
np.insert(x, 3, [r], axis=1)
Isn't this just about adding a column to an existing 2d array. Writing it to a csv file is just a further step and isn't affected by this addition.
In [96]: x = np.array([[1, 2, 3],
...: [4, 5, 6],
...: [7, 8, 9]], np.int32)
In [97]: r = [1,2,3]
There are a number of functions that can add a column to an array, but they all end up using concatenate. And knowing how to use concatenate directly is a good thing to know. The key is matching the number of dimensions.
In [98]: x1 = np.concatenate((x, np.array(r)[:,None]), axis=1)
In [99]: x1
Out[99]:
array([[1, 2, 3, 1],
[4, 5, 6, 2],
[7, 8, 9, 3]])
vstack takes care of turning r into this column array. insert is more general, allowing you to add values within the existing (not just at the end). But like concatenate (and all the stacks) it does not operate in-place.

Select 'area' from a 2D array in python

Is there a way to select a particular 'area' of a 2d array in python?
I can use array slicing to project out only one row or column but I am unsure about how to pick a 'subarray' from the large 2d array.
Thanks in advance
Jack
If you are using the numpy library, you can use numpy's more advanced slicing to accomplish this like so:
import numpy as np
x = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]])
print x[0:2, 2:4]
# ^^^ ^^^
# rows cols
# Result:
[[3 4]
[7 8]]
(more info in the numpy docs)
If you don't want to use numpy, you can use a list comprehension like this:
x = [[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]]
print [row[2:4] for row in x[0:2]]
# ^^^ ^^^ select only rows of index 0 or 1
# ^^^ and only columns of index 2 or 3
# Result:
[[3, 4],
[7, 8]]

Numpy - How to replace elements based on condition (or matching a pattern)

I have a numpy array, say:
>>> a=np.array([[0,1,2],[4,3,6],[9,5,7],[8,9,8]])
>>> a
array([[0, 1, 2],
[4, 3, 6],
[9, 5, 7],
[8, 9, 8]])
I want to replace the second and third column elements with the minimum of them (row by row), except if one of these 2 elements is < 3.
The resulting array should be:
array([[0, 1, 2],# nothing changes since 1 and 2 are <3
[4, 3, 3], #min(3,6)=3 => 6 changed to 3
[9, 5, 5], #min(5,7)=5 => 7 changed to 5
[8, 8, 8]]) #min(9,8)=8 => 9 changed to 8
I know I can use clip, for instance a[:,1:3].clip(2,6,a[:,1:3]), but
1) clip will be applied to all elements, including those <3.
2) I don't know how to set the min and max values of clip to the minimum values of the 2 related elements of each row.
Just use the >= operator to first select what you are interested of:
b = a[:, 1:3] # select the columns
matching = numpy.all(b >= 3, axis=1) # find rows with all elements matching
b = b[matching, :] # select rows
Now you can replace the content with the minimum by e.g.:
# find row minimum and convert to a column vector
b[:, :] = b.min(1, keepdims=True)
We first defined a row_mask, depicting the <3 condition, and then apply a minimum along an axis to find the minimum (for rows in row_mask).
The newaxis part is required for the broadcasting of a 1dim array (of minimums) to the 2-dim target of the assignment.
a=np.array([[0,1,2],[4,3,6],[9,5,7],[8,9,8]])
row_mask = (a[:,0]>=3)
a[row_mask, 1:] = a[row_mask, 1:].min(axis=1)[...,np.newaxis]
a
=>
array([[0, 1, 2],
[4, 3, 3],
[9, 5, 5],
[8, 8, 8]])
Here's a one liner:
a[np.where(np.sum(a,axis=1)>3),1:3]=np.min(a[np.where(np.sum(a,axis=1)>3),1:3],axis=2).reshape(1,3,1)
Here's a breakdown:
>>> b = np.where(np.sum(a,axis=1)>3) # finds rows where, in a, row sums are > 3
(array([1, 2, 3]),)
>>> c = a[b,1:3] # the part of a that needs to change
array([[[3, 3],
[5, 5],
[8, 8]]])
>>> d = np.min(c,axis=2) # the minimum values in each row (cols 1 and 2)
array([[3, 5, 8]])
>>> e = d.reshape(1,3,1) # adjust shape for broadcast to a
array([[[3],
[5],
[8]]])
>>> a[np.where(np.sum(a,axis=1)>3),1:3] = e # set the values in a
>>> a
array([[0, 1, 2],
[4, 3, 3],
[9, 5, 5],
[8, 8, 8]])

Appending matrices

Suppose I have a matrix. I delete an entire row and after doing so, I want to append the deleted row to the reduced matrix. How can I do this?
import numpy as np
A=np.array([[1,2,3],[4,5,6],[7,8,9]])
A1=np.delete(A,1,0)
A2=A[1,:]
np.append(A1,A2,0)
But this is showing error.
Any suggestion?
When you do np.delete it returns the array without the deleted row, not the deleted row. So your A1 has actually two rows instead of one, and that's why it's failing.
To achieve what you want, this should do it:
A1 = A[1]
A = np.delete(A, 1, 0)
result = np.append(A, A1[np.newaxis, :], 0)
and this result will contain:
array([[1, 2, 3],
[7, 8, 9],
[4, 5, 6]])
Was this what you wanted?
Note the use of np.newaxis is necessary to make the single-row array A1 of the same shape as the array to append (because np.append requires arrays to have the same number of dimensions).
How about:
def move_row_to_end(A, row):
return A[range(row) + range(row + 1, A.shape[0]) + [row]]
A = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print move_row_to_end(A, 1)
You can try vstack instead: Stack arrays in sequence vertically (row wise).
http://docs.scipy.org/doc/numpy/reference/generated/numpy.vstack.html
In [33]: np.vstack([A1, A2])
Out[33]:
array([[1, 2, 3],
[7, 8, 9],
[4, 5, 6]])

Resources