3

I have a large 2D array, array, with each entry being a large array of numbers :

array = [
            [1, 0, 3, ...],
            [5, 4, 1, ...],
            [1, 2, 3, ...],
            ...
        ]

All the numbers in the 2D array are from 0-5 and I have to somehow find and replace specific numbers, like, for example, all occurrences of the number 3 and replace it with 5.

Thanks

NKahle
  • 142
  • 6
ssal
  • 95
  • 1
  • 1
  • 8
  • 5
    Can you provide a **[mcve]**? – jpp Oct 17 '18 at 23:22
  • As you say 'specific numbers' is it correct that you are searching for more than 1 number? Do you know what these numbers are beforehand? – GeoMonkey Oct 17 '18 at 23:30
  • Yes, the only numbers in the arrays are from 0-5, so i have to replace 1 with -5, 2 with -3, 3 with 1, 4 with 3 and 5 with 5 – ssal Oct 17 '18 at 23:43
  • Possible duplicate of [Fast replacement of values in a numpy array](https://stackoverflow.com/questions/3403973/fast-replacement-of-values-in-a-numpy-array) – jpp Oct 18 '18 at 01:41
  • @jojo, Above is a **perfect** dup of this question. I suggest you post your answer there.. – jpp Oct 18 '18 at 01:41
  • 3
    This question doesn't seem unclear to me. – dendragon Oct 23 '18 at 15:09

3 Answers3

5

This can be done with list comprehension in a simple one-liner.

Say you have a list of lists:

a = [[1, 2, 3], [1, 2, 3], [1, 2, 3]]

and you want to replace all occurrences of 2 with 4:

[[_el if _el != 2 else 4 for _el in _ar] for _ar in a]

Another option is to use numpy's where function. From the docstring:

where(condition, [x, y])

Return elements, either from x or y, depending on condition.

So, in your case (say you'd like again to replace all 2 with 4):

import numpy as np

a = np.array([[1, 2, 3],
   [1, 2, 3],
   [1, 2, 3]])

np.where(a==2, 4, a)

If you want to replace several values in one go, you could do something like this: Say you'd like to replace 1 with 3 and 3 with 5:

ix=np.isin(array, [1,3])
vc=np.vectorize(lambda x: 3 if x == 1 else 5)
np.where(ix, vc(array), array)

If you have more than 2 values to replace, say you want to map the list [1,3,5] to [3, 5, -3], then you can define a simple function like:

old_vals = [1,3,5]
new_vals = [3, 5, -3]
def switch_val(x):
    return new_vals[old_vals.index(x)] if x in old_vals else x

and so:

vc=np.vectorize(switch_val)
vc(array)

where we vectorized the function.

Hope that helped and happy coding!

Community
  • 1
  • 1
j-i-l
  • 10,281
  • 3
  • 53
  • 70
  • Just curious, given the OP wants to replace multiple values, I guess the most pythonic approach would be to use np.where multiple times...? Rather than using a bunch of conditions and/or elifs? – GeoMonkey Oct 18 '18 at 00:01
  • @NathanThomas sorry for the hick-hack. I added it to the answer. :) – j-i-l Oct 18 '18 at 00:46
  • 1
    I was just curious, but it turned out to be pretty elegant. It's good to see the full working example for future use! – GeoMonkey Oct 18 '18 at 01:43
  • @NathanThomas you are very welcome! – j-i-l Oct 18 '18 at 01:44
0
for i in range(len(array)):
    for j in range(len(array[i])):
        if array[i][j] == value_you_are_looking_for:
            array[i][j] = new_value

This should work

Dhruvit
  • 21
  • 2
  • Thanks, i tried this form but it didn't work for some reason it just printed the exact same array for i in range(len(new_set)): for j in range(len(new_set[i])): if new_set[i][j] == 1: new_set[i][j] = -5 print(new_set) – ssal Oct 17 '18 at 23:45
0

For a single value, given you have an array called Arr, such that:

Arr = np.array([[1,2,3],
                [1,2,3],
                [1,2,3]])

Then:

mask = Arr == 2

gives:

mask = np.array([[False,True,False],
                [False,True,False],
                [False,True,False]])

finally, replacing 2 with 4:

newArr[mask] = 4

gives:

Arr = np.array([[1,4,3],
                [1,4,3],
                [1,4,3]])
GeoMonkey
  • 1,615
  • 7
  • 28
  • 56