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 have existing numpy array (uint8) which looks like this:

(Values are 8bit, i am interested only in last 3 of them)

[
    [ 00000AAA, 00000BBB, 00000CCC ],
    [ 00000FFF, 00000EEE, 00000DDD ],
    [ 00000GGG, 00000HHH, 00000III ],
    [ 00000LLL, 00000KKK, 00000JJJ ]
]

And in the end I would like to have data in this form:

[01AAABBB, 01CCCDDD 01EEEFFF, 01GGGHHH, 01IIIJJJ, 01KKKLLL]

Also, every second row is reversed.

Currently i have a long and winding code whitch iterates over the original list row-by-row and cell-by-cell, shifts and adds data, but that is not efficient enough.

Are there any good and efficinet methods solving that problem?

share|improve this question
    
Does the input array always have shape (4, 3)? –  Warren Weckesser Jul 27 at 13:45
    
No, but the actual problem has always shape (100,300) –  zidik Jul 27 at 13:47
    
To be sure: you want new array where each element is a combination of one odd element and 1000* an even element, plus 01000000; where the order of parsing is "up-and-down" through the original array? –  mdurant Jul 27 at 13:52
    
Maybe, you should consider to write a library in C/Fortran. –  Stefan Jul 27 at 14:33

1 Answer 1

up vote 5 down vote accepted

Here's an approach using Numpy built-in commands and vector style indexing, so it's pretty compact (and should be quicker than iterating):

Updated with suggestions from comments

# Reverse direction of every second row
unsnaked_array       = np.array(inp_array)
unsnaked_array[1::2] = inp_array[1::2, ::-1]

# Change to one long array
unsnaked_array = unsnaked_array.ravel()
unsnaked_array &= 0x7    # Extra safety :)    

# Sum every pair of elements (with first element rolled) and add required bit
result_array = (unsnaked_array[::2]<<3) + unsnaked_array[1::2] + (1<<6)
share|improve this answer
1  
Nice and simple, +1. The odd row reversal can be done more efficiently as arr[1::2] = arr[1::2, ::-1]. I would probably have thrown an arr &= 0x7 to make sure that onlt the 3 LSB were used, but that may be being too cautious. –  Jaime Jul 27 at 15:47
    
For some reason I can't the in-place reverse to work, the last element of each reversed row is set to the first… e.g.for an input of [[1, 2, 3], [4, 5, 6]] I get [[1, 2, 3], [6, 5, 6]]. Weird. –  Pokey McPokerson Jul 27 at 16:10
1  
The reversal happens in-place, so you overwrite the data as the reverse takes place. If you use the same syntax into a different array, it will work. –  mdurant Jul 27 at 16:22
1  
Thank you! that solved the problem! The first in pairs should be shifted (unsnaked_array[::2]<<3) + unsnaked_array[1::2] I just replaced 20 lines of ugly code with 5 –  zidik Jul 27 at 17:00
    
There was a bug @user3816595, see the updated answer.. –  Pokey McPokerson Jul 28 at 18:55

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.