Home > Software engineering >  how to apply numpy.where to a range of rows
how to apply numpy.where to a range of rows

Time:04-24

I have a 2d matrix file(inputdata) that contain 4 rows and 5 column as given below

1 2 3 4 5
0 2 2 4 6
1 2 5 6 1 
2 4 5 6 7

I want to make all values that are greater than 2 to 1 (only for second and third rows of second and third columns) using numpy.where

Expected output is

1 2 3 4 5
0 1 1 4 6
1 1 5 6 1 
2 4 5 6 7

My script is

import numpy as np
data=np.loadtxt("inputdata")
values=np.where(((data>2) & (data[1:3])))
data[values]=1

but the second condition (i.e. i want to apply the first condition of numpy.where to a range of rows only)

is not working.

I hope experts may help overcoming this problem.Thank you.

CodePudding user response:

Since the area you want to focus on is contiguous, you could make a subarray and then replace that part of the original array with the final subarray:

# Let's say your original array is called arr.
# subarray contains the 4 values that are in the 2nd and 3rd rows and columns.
subarray = arr[1:3, 1:3]

# Do your calculations on subarray and then change arr to match.
# This has the advantage of not iterating through all of arr, only the subarray.
subarray = np.where(subarray > 2, 1, subarray)
arr[1:3, 1:3] = subarray

CodePudding user response:

You can use np.ix_ to take the subarray using advanced indexing, and then assign the results of np.where back to x with the same indexing:

rows = (1, 2)
cols = (1, 2)
coords = np.ix_(rows, cols)
x[coords] = np.where(x[coords] == 2, 1, x[coords])

Demo:

In [11]: coords = np.ix_((1,2), (1,2))

In [12]: x[coords]
Out[12]:
array([[2, 2],
       [2, 5]])

In [13]: x[coords] = np.where(x[coords] == 2, 1, x[coords])

In [14]: x
Out[14]:
array([[1, 2, 3, 4, 5],
       [0, 1, 1, 4, 6],
       [1, 1, 5, 6, 1],
       [2, 4, 5, 6, 7]])

For contiguous subarrays you can just use normal slicing (see AJH's answer). You can, however, still use np.ix_, which in my opinion is nicer to work with:

rows = np.arange(1, 11)  # rows 1 through 10
cols = np.arange(4, 21)  # columns 4 through 20
target_value = 2  # The value to replace
substitution = 1  # The value used in replacement

coords = np.ix_(rows, cols)
x[coords] = np.where(x[coords] == target_value, substitution, x[coords])

CodePudding user response:

np.where(a[1:3, 2:4] > 2, 1, a[1:3, 2:4])

  • Related