15

In a given numpy array X:

X = array([1,2,3,4,5,6,7,8,9,10])

I would like to replace indices (2, 3) and (7, 8) with a single element -1 respectively, like:

X = array([1,2,-1,5,6,7,-1,10])

In other words, I replaced values at indices (2, 3) and (7,8) of the original array with a singular value.

Question is: Is there a numpy-ish way (i.e. without for loops and usage of python lists) around it? Thanks.

Note: This is NOT equivalent of replacing a single element in-place with another. Its about replacing multiple values with a "singular" value. Thanks.

7
  • 1
    @awiebe I don't think you get the point, the point is two replace two indexes in to one element. Commented Oct 26, 2018 at 2:23
  • 1
    @awiebe No this is asked zero times not including this on so far... Commented Oct 26, 2018 at 2:23
  • 2
    @awiebe Not sure what this means ... the question is looking for a numpy-ish way of replacing two entities in an array with a single entity (demo-ed by the examples too in which you can clearly see the size of array reduced by 2 elements). Commented Oct 26, 2018 at 2:40
  • 1
    Ah, I see the question was resizing the array, not replacing the value. That makes more sense then how I read it. Commented Oct 26, 2018 at 2:45
  • 1
    @awiebe Yup, that's why that's no a dupliacte of this :-)... Commented Oct 26, 2018 at 2:46

3 Answers 3

7

A solution using numpy.delete, similar to @pault, but more efficient as it uses pure numpy indexing. However, because of this efficient indexing, it means that you cannot pass jagged arrays as indices

Setup

a = np.array([1,2,3,4,5,6,7,8,9,10])
idx = np.stack([[2, 3], [7, 8]])

a[idx] = -1
np.delete(a, idx[:, 1:])

array([ 1,  2, -1,  5,  6,  7, -1, 10])
Sign up to request clarification or add additional context in comments.

2 Comments

Definitely seems like a cleaner and more efficient way.
This is a very good approach. It avoids an extra lookup, because indices to be deleted are already know.
4

I'm not sure if this can be done in one step, but here's a way using np.delete:

import numpy as np
from operator import itemgetter

X = np.array(range(1,11))
to_replace = [[2,3], [7,8]]


X[list(map(itemgetter(0), to_replace))] = -1
X = np.delete(X, list(map(lambda x: x[1:], to_replace)))
print(X)
#[ 1  2 -1  5  6  7 -1 10]

First we replace the first element of each pair with -1. Then we delete the remaining elements.

Comments

2

Try np.put:

np.put(X, [2,3,7,8], [-1,0]) # `0` can be changed to anything that's not in the array
print(X[X!=0]) # whatever You put as an number in `put`

So basically use put to do the values for the indexes, then drop the zero-values.

Or as @khan says, can do something that's out of range:

np.put(X, [2,3,7,8], [-1,np.max(X)+1])
print(X[X!=X.max()])

All Output:

[ 1  2 -1  5  6  7 -1 10]

5 Comments

what if the list contains 0 initially?
This zero can actually be anything out of the range of the array..that will help it. So, X=numpy.arange(1,11); numpy.put(X, [2,3,7,8], [-1,numpy.max(X)+1]); X[X!=X.max()]..
A food for thought: What if we like to replace indices (2,3,7,8) with -1 and indices (9,10) with -2..
@khan Then add an extra put, for indexes 9,10
Thats true. Agreed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.