By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
 440,714 Members | 750 Online
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,714 IT Pros & Developers. It's quick & easy.

# A matrix problem. Please help!

 P: n/a I have the following matrix that I want to transform: import random import Numeric as N ru = [] for i in range(25): ru.append(int(random.uniform(0, 2))) ru = N.reshape(ru, (5, 5)) ru array([[1, 0, 1, 1, 1], [0, 1, 1, 1, 0], [1, 1, 0, 0, 1], [0, 1, 0, 0, 1], [1, 1, 0, 1, 1]]) Trailing numbers (ie, from left to right) after the first encounter of a "1" for all rows should equal "0". Thus, I want this: ru array([[1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [1, 0, 0, 0, 0]]) Does anyone have a suggestion of a fast and easy way to accomplish the above? Carl Jul 18 '05 #1
Share this Question
4 Replies

 P: n/a Carl wrote: I have the following matrix that I want to transform: import random import Numeric as N ru = [] for i in range(25): ru.append(int(random.uniform(0, 2))) ru = N.reshape(ru, (5, 5)) ru array([[1, 0, 1, 1, 1], [0, 1, 1, 1, 0], [1, 1, 0, 0, 1], [0, 1, 0, 0, 1], [1, 1, 0, 1, 1]]) Trailing numbers (ie, from left to right) after the first encounter of a "1" for all rows should equal "0". Thus, I want this: ru array([[1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [1, 0, 0, 0, 0]]) Does anyone have a suggestion of a fast and easy way to accomplish the above? Carl (Disclaimer: Numeric newbie code) import random import Numeric import itertools def oneone(): .... while 1: .... r = int(random.uniform(0, 2)) .... yield r .... if r: break .... for r in itertools.repeat(0): .... yield r .... ru = Numeric.array([[x for x,y in itertools.izip(oneone(), range(5))] for z in range(5)]) ru array([[0, 0, 1, 0, 0], [0, 0, 0, 1, 0], [1, 0, 0, 0, 0], [0, 0, 0, 1, 0], [0, 0, 1, 0, 0]]) Or, more seriously, i. e. assuming that you have no influence on the initial matrix: r array([[1, 1, 1], [0, 1, 1], [0, 0, 1]]) for i in r: .... for k in Numeric.nonzero(i)[1:]: .... i[k] = 0 .... r array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) Peter Jul 18 '05 #2

 P: n/a Peter Otten wrote: Carl wrote: I have the following matrix that I want to transform: import random import Numeric as N ru = [] for i in range(25): ru.append(int(random.uniform(0, 2))) ru = N.reshape(ru, (5, 5))> ru array([[1, 0, 1, 1, 1], [0, 1, 1, 1, 0], [1, 1, 0, 0, 1], [0, 1, 0, 0, 1], [1, 1, 0, 1, 1]]) Trailing numbers (ie, from left to right) after the first encounter of a "1" for all rows should equal "0". Thus, I want this:> ru array([[1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [1, 0, 0, 0, 0]]) Does anyone have a suggestion of a fast and easy way to accomplish the above? Carl (Disclaimer: Numeric newbie code) import random import Numeric import itertools def oneone(): ... while 1: ... r = int(random.uniform(0, 2)) ... yield r ... if r: break ... for r in itertools.repeat(0): ... yield r ... ru = Numeric.array([[x for x,y in itertools.izip(oneone(), range(5))] for z in range(5)]) ru array([[0, 0, 1, 0, 0], [0, 0, 0, 1, 0], [1, 0, 0, 0, 0], [0, 0, 0, 1, 0], [0, 0, 1, 0, 0]]) Or, more seriously, i. e. assuming that you have no influence on the initial matrix: r array([[1, 1, 1], [0, 1, 1], [0, 0, 1]]) for i in r: ... for k in Numeric.nonzero(i)[1:]: ... i[k] = 0 ... r array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) Peter Thanks Peter, This: for i in ru: for k in N.nonzero(i)[1:]: i[k] = 0 works very nice, but I'm a little worried about performance problem, since the matrix ru is typically of size 10,000 to 100,000 rows by 10 to 60 columns. I have tried to figure out how to do it without loops, but have not managed to do that yet. Carl Jul 18 '05 #3

 P: n/a Well, my strategy is to get a new array with 1 in the spots where you want a 1 in the output, and other values elsewhere. Then I can use comparison to get a (boolean) array with 1s in the right place I didn't find a satisfactory way to do that, but here's one that seemed to work: ru array([[0, 0, 1, 0, 1], [1, 0, 0, 1, 1], [0, 0, 0, 1, 1], [1, 1, 1, 0, 0], [1, 1, 0, 1, 0]]) N.add.accumulate(N.add.accumulate(ru, 1), 1) array([[ 0, 0, 1, 2, 4], [ 1, 2, 3, 5, 8], [ 0, 0, 0, 1, 3], [ 1, 3, 6, 9, 12], [ 1, 3, 5, 8, 11]]) _ == 1 array([[0, 0, 1, 0, 0], [1, 0, 0, 0, 0], [0, 0, 0, 1, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0]], type=Bool) The first accumulate makes everything to the left of a 1 >0, and the second accumulate makes it >1. Jeff Jul 18 '05 #4

 P: n/a Jeff Epler wrote: Well, my strategy is to get a new array with 1 in the spots where you want a 1 in the output, and other values elsewhere. Then I can use comparison to get a (boolean) array with 1s in the right place I didn't find a satisfactory way to do that, but here's one that seemed to work: ru array([[0, 0, 1, 0, 1], [1, 0, 0, 1, 1], [0, 0, 0, 1, 1], [1, 1, 1, 0, 0], [1, 1, 0, 1, 0]]) N.add.accumulate(N.add.accumulate(ru, 1), 1) array([[ 0, 0, 1, 2, 4], [ 1, 2, 3, 5, 8], [ 0, 0, 0, 1, 3], [ 1, 3, 6, 9, 12], [ 1, 3, 5, 8, 11]]) _ == 1 array([[0, 0, 1, 0, 0], [1, 0, 0, 0, 0], [0, 0, 0, 1, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0]], type=Bool) The first accumulate makes everything to the left of a 1 >0, and the second accumulate makes it >1. Jeff Jeff, Your solution works very well. I tried to do something similar, but with N.cumsum instead of N.add.accumuluate. However, I never did the second step, so I ended up with two "1:s" in each row and was, therefore, never able to do the booelan comparison. Thanks for yopur help! Carl Jul 18 '05 #5

### This discussion thread is closed

Replies have been disabled for this discussion.