4

How can I create an array based on certain conditions in another array. For example, if I have an array that gives me a Base number, a start and end number, and then multiple other Base numbers. I want to create a new matrix that lists the Base number, the loop number (based on start/end) and then the other Base number associated with this, while ignoring 0's. I am trying to find a way to do this without using a for loop.

For example, how can I get array B from array A.

           Base Start End Base1 Base2 Base3
A=np.array([[100,  1,   2,  101,  102,  103],
            [101,  3,   4,  100,  103,    0]])


B=np.array[[100,1,101,1],
           [100,1,102,1],
           [100,1,103,1],
           [100,2,101,2],
           [100,2,102,2],
           [100,2,103,2],
           [101,3,100,3],
           [101,3,103,3],
           [101,4,100,4],
           [101,4,103,4]]

Thanks for the help!

3
  • 3
    You might be able to do this with a messy combination of numpy.tile and numpy.repeat, but why go to such lengths to not use a loop? Commented Mar 3, 2014 at 21:17
  • 1
    I don't understand your target format. Why does row 4 of B end with a 1 instead of a 2? If you post a slow version with explicit loops, that would make it easier for us to understand exactly what you want to do. Commented Mar 3, 2014 at 23:40
  • Sorry that was an error on my part, rows 4-6 should have ended in a 2. Has been edited. Is it clear now or would you like me to break it out more? Commented Mar 4, 2014 at 0:36

2 Answers 2

2

Here you go... nasty list comprehension

A = array([[100,   1,   2, 101, 102, 103], [101,   3,   4, 100, 103,   0]])
B = [[A[i,0], b, c, b] for i in range(len(A)) for b in A[i,1:3] for c in A[i,3:6] if c != 0]

>>> B
[[100, 1, 101, 1],
 [100, 1, 102, 1],
 [100, 1, 103, 1],
 [100, 2, 101, 2],
 [100, 2, 102, 2],
 [100, 2, 103, 2],
 [101, 3, 100, 3],
 [101, 3, 103, 3],
 [101, 4, 100, 4],
 [101, 4, 103, 4]]
Sign up to request clarification or add additional context in comments.

Comments

2

Here you go: pure numpy, no for loops at the python level

C = np.empty((len(A), 2,3,4), np.int)
C[...,0] = A[:,0  ][:,None,None]
C[...,1] = A[:,1:3][:,:   ,None]
C[...,2] = A[:,3: ][:,None,:   ]
C[...,3] = np.arange(len(A)*2).reshape(len(A),2,1)+1

C = C.reshape(-1,4)
C = C[C[:,2]!=0]

print C

edit: minor cleanup

edit2: or for maximum brevity and crypticity (see comment):

C = np.empty((len(A), 2,3,2,2), np.int)
C[...,0,0] = A[:,0  ][:,None,None]
C[...,1,0] = A[:,3: ][:,None,:   ]
C[...,:,1] = A[:,1:3][:,:   ,None,None]

1 Comment

note; the last column appears to me to be redundant, so ive added another method of generating the same pattern; but I am not sure it generalizes to all your use cases; you might just want to write the same pattern to column 3 as to column 1, if that is the expected data layout of some downstream code.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.