Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I two numpy arrays, both M by N. X contains random values. Y contains true/false. Array A contains indices for rows in X that need replacement, with the value -1. I want to only replace values where Y is true.

Here is some code to do that:

M=30
N=40
X = np.zeros((M,N))  # random values, but 0s work too
Y = np.where(np.random.rand(M,N) > .5, True, False)
A=np.array([ 7,  8, 10, 13]), # in my setting, it's (1,4), not (4,)
for i in A[0]:
    X[i][Y[A][i]==True]=-1

However, what I actually want is only replace some of the entries. List B contains how many need to be replaced for each index in A. It's already ordered so A[0][0] corresponds to B[0], etc. Also, it's true that if A[i] = k, then the corresponding row in Y has at least k trues.

B = [1,2,1,1]

Then for each index i (in loop),

X[i][Y[A][i]==True][0:B[i]] = -1

This doesn't work. Any ideas on a fix?

share|improve this question

2 Answers 2

It is not clear what you want to do, here is my understanding:

import numpy as np
m,n = 30,40
x = np.zeros((m,n))
y = np.random.rand(m,n) > 0.5    #no need for where here
a = np.array([7,8,10,13])
x[a] = np.where(y[a],-1,x[a])    #need where here
share|improve this answer
    
Right, but I actually don't want them all replaced -- I need the first B replaced. If B[0] = 2, instead of all y[7] being changed to -1, I only want the first y[7][0:2] replaced. If B[1] = 3, then change y[8][0:3] = -1. –  Kevin Sep 8 '13 at 4:23
up vote 0 down vote accepted

Unfortunately, I don't have an elegant answer; however, this works:

M=30
N=40
X = np.zeros((M,N))  # random values, but 0s work too
Y = np.where(np.random.rand(M,N) > .5, True, False)
A=np.array([ 7,  8, 10, 13]), # in my setting, it's (1,4), not (4,)
B = [1,2,1,1]

# position in row where X should equal - 1, i.e. X[7,a0], X[8,a1], etc
a0=np.where(Y[7]==True)[0][0]
a1=np.where(Y[8]==True)[0][0]
a2=np.where(Y[8]==True)[0][1]
a3=np.where(Y[10]==True)[0][0]
a4=np.where(Y[13]==True)[0][0]

# For each row (i) indexed by A, take only B[i] entries where Y[i]==True.  Assume these indices in X = -1
for i in range(len(A[0])):
    X[A[0][i]][(Y[A][i]==True).nonzero()[0][0:B[i]]]=-1

np.sum(X) # should be -5
X[7,a0]+X[8,a1]+X[8,a2]+X[10,a3]+X[13,a4] # should be -5
share|improve this answer
    
This code would look a bit better if A was (k,) instead of (1,k). Any ideas for speed improvement? –  Kevin Sep 8 '13 at 13:54

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.