How can I effectively convert a numpy.int8 array into place into a numpy.uint8 array with a variable value?

I have a large array with numeric bytes ( dtype int8 ). It contains values ​​ranging from -128 to +127. I would like to efficiently convert an array of unsigned bytes ( dtype uint8 ) by adding 128 to each element, such that -128 β†’ 0, 0 β†’ 128, +127 β†’ 255, etc. Therefore, of course, the results are still saved fits into an unsigned byte.

A simple item-by-element addition that gives the correct numerical result, but creates an array of results using twice as much memory ( dtype int16 ) in addition to the original array, although only low bytes of the result elements are needed.

 >>> import numpy >>> a = numpy.array( [-128, -1, 0, 1, 127 ], dtype=numpy.int8) >>> b = a + 128 >>> b array([ 0, 127, 128, 129, 255], dtype=int16) 

Is there a way to control the dtype array of results like uint8 ?

An alternative approach to changing values ​​in place and casting data into a new type, for example:

 >>> for i in xrange(0, 5): ... if a[i] < 0: ... a[i] -= 128 ... elif a[i] >= 0: ... a[i] += 128 ... >>> a array([ 0, 127, -128, -127, -1], dtype=int8) >>> a.view(dtype=numpy.uint8) array([ 0, 127, 128, 129, 255], dtype=uint8) 

much more efficient than space, but very expensive time for large arrays with conversion in Python.

How can I do this conversion in place and quickly?

+7
source share
2 answers
  import numpy as np
 a = np.array ([- 128, -1, 0, 1, 127], dtype = np.int8)
 a = a.view (np.uint8)
 a + = 128
 print a
 # -> array ([0, 127, 128, 129, 255], dtype = uint8)

This does not create a copy, and all operations are performed on site.

EDIT : it is safer to drop first in uint --- unsigned wrapping. EDIT2 : s / numpy / np / g;

+14
source
 In [18]: a = numpy.array( [-128, -1, 0, 1, 127 ], dtype=numpy.int8) In [19]: z = a.view(dtype=numpy.uint8) In [20]: z += 128 In [21]: z Out[21]: array([ 0, 127, 128, 129, 255], dtype=uint8) 

I hope I did not understand the wrong requirements.

+1
source

All Articles