Does numpy have functions to convert between e.g. an array of uint32 and uint8, where the uint32 array is a packed version of the uint8 array (selecting little/big endian)?
Neal Becker wrote:
Does numpy have functions to convert between e.g. an array of uint32 and uint8, where the uint32 array is a packed version of the uint8 array (selecting little/big endian)?
I've been thinking about making a ufunc (in python) to do this, but have no idea how to make a ufunc for a function that consumes 4 consecutive values of it's input and produces an output array of 1/4 the size of the input. Is that possible?
Doesn't .view work for that? Travis Sent from my iPhone On Jul 29, 2009, at 6:57 AM, Neal Becker <ndbecker2@gmail.com> wrote:
Neal Becker wrote:
Does numpy have functions to convert between e.g. an array of uint32 and uint8, where the uint32 array is a packed version of the uint8 array (selecting little/big endian)?
I've been thinking about making a ufunc (in python) to do this, but have no idea how to make a ufunc for a function that consumes 4 consecutive values of it's input and produces an output array of 1/4 the size of the input. Is that possible?
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
Travis Oliphant wrote:
Doesn't .view work for that?
Travis
Sent from my iPhone
On Jul 29, 2009, at 6:57 AM, Neal Becker <ndbecker2@gmail.com> wrote:
Neal Becker wrote:
Does numpy have functions to convert between e.g. an array of uint32 and uint8, where the uint32 array is a packed version of the uint8 array (selecting little/big endian)?
I've been thinking about making a ufunc (in python) to do this, but have no idea how to make a ufunc for a function that consumes 4 consecutive values of it's input and produces an output array of 1/4 the size of the input. Is that possible?
Can 'view' switch byteorder? Doesn't seem to work:
import numpy as np a = np.arange(10, dtype=np.uint32) b1 = a.view (np.dtype(np.uint32).newbyteorder('<')) c1 = b1.view(np.uint8) b2 = a.view (np.dtype(np.uint32).newbyteorder('>')) c2 = b2.view(np.uint8) print c1 print c2 [0 0 0 0 1 0 0 0 2 0 0 0 3 0 0 0 4 0 0 0 5 0 0 0 6 0 0 0 7 0 0 0 8 0 0 0 9 0 0 0] [0 0 0 0 1 0 0 0 2 0 0 0 3 0 0 0 4 0 0 0 5 0 0 0 6 0 0 0 7 0 0 0 8 0 0 0 9 0 0 0]
Does numpy have functions to convert between e.g. an array of uint32 and uint8, where the uint32 array is a packed version of the uint8 array (selecting little/big endian)?
You could use the ndarray constructor to look at the memory differently: In : a = numpy.arange(240, 260, dtype=numpy.uint32) In : a Out: array([240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259], dtype=uint32) In : b = numpy.ndarray(shape=(len(a)*4,), dtype=numpy.uint8, buffer=a) In : b Out: array([240, 0, 0, 0, 241, 0, 0, 0, 242, 0, 0, 0, 243, 0, 0, 0, 244, 0, 0, 0, 245, 0, 0, 0, 246, 0, 0, 0, 247, 0, 0, 0, 248, 0, 0, 0, 249, 0, 0, 0, 250, 0, 0, 0, 251, 0, 0, 0, 252, 0, 0, 0, 253, 0, 0, 0, 254, 0, 0, 0, 255, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 2, 1, 0, 0, 3, 1, 0, 0], dtype=uint8) I assume for selecting little/big-endian going the other way, you could use the other methods of specifying dtypes that allow for byte- order descriptors. (Like dtype objects or the format strings.) Zach
2009/7/29 Zachary Pincus <zachary.pincus@yale.edu>:
Does numpy have functions to convert between e.g. an array of uint32 and uint8, where the uint32 array is a packed version of the uint8 array (selecting little/big endian)?
You could use the ndarray constructor to look at the memory differently:
In : a = numpy.arange(240, 260, dtype=numpy.uint32) In : a Out: array([240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259], dtype=uint32)
In : b = numpy.ndarray(shape=(len(a)*4,), dtype=numpy.uint8, buffer=a)
In : b Out: array([240, 0, 0, 0, 241, 0, 0, 0, 242, 0, 0, 0, 243, 0, 0, 0, 244, 0, 0, 0, 245, 0, 0, 0, 246, 0, 0, 0, 247, 0, 0, 0, 248, 0, 0, 0, 249, 0, 0, 0, 250, 0, 0, 0, 251, 0, 0, 0, 252, 0, 0, 0, 253, 0, 0, 0, 254, 0, 0, 0, 255, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 2, 1, 0, 0, 3, 1, 0, 0], dtype=uint8)
I assume for selecting little/big-endian going the other way, you could use the other methods of specifying dtypes that allow for byte- order descriptors. (Like dtype objects or the format strings.)
Something like: In [17]: np.dtype(np.int32).newbyteorder('>') Out[17]: dtype('>i4') In [18]: dt = np.dtype(np.int32).newbyteorder('>') In [19]: x = np.array([123, 456, 789], dtype=dt) In [20]: x.view(np.uint8) Out[20]: array([ 0, 0, 0, 123, 0, 0, 1, 200, 0, 0, 3, 21], dtype=uint8) Regards Stéfan
Stéfan van der Walt wrote:
2009/7/29 Zachary Pincus <zachary.pincus@yale.edu>:
Does numpy have functions to convert between e.g. an array of uint32 and uint8, where the uint32 array is a packed version of the uint8 array (selecting little/big endian)?
You could use the ndarray constructor to look at the memory differently:
In : a = numpy.arange(240, 260, dtype=numpy.uint32) In : a Out: array([240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259], dtype=uint32)
In : b = numpy.ndarray(shape=(len(a)*4,), dtype=numpy.uint8, buffer=a)
In : b Out: array([240, 0, 0, 0, 241, 0, 0, 0, 242, 0, 0, 0, 243, 0, 0, 0, 244, 0, 0, 0, 245, 0, 0, 0, 246, 0, 0, 0, 247, 0, 0, 0, 248, 0, 0, 0, 249, 0, 0, 0, 250, 0, 0, 0, 251, 0, 0, 0, 252, 0, 0, 0, 253, 0, 0, 0, 254, 0, 0, 0, 255, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 2, 1, 0, 0, 3, 1, 0, 0], dtype=uint8)
I assume for selecting little/big-endian going the other way, you could use the other methods of specifying dtypes that allow for byte- order descriptors. (Like dtype objects or the format strings.)
Something like:
In [17]: np.dtype(np.int32).newbyteorder('>') Out[17]: dtype('>i4')
In [18]: dt = np.dtype(np.int32).newbyteorder('>')
In [19]: x = np.array([123, 456, 789], dtype=dt)
In [20]: x.view(np.uint8) Out[20]: array([ 0, 0, 0, 123, 0, 0, 1, 200, 0, 0, 3, 21], dtype=uint8)
Regards Stéfan
Can 'view' switch byteorder? Doesn't seem to work: import numpy as np a = np.arange(10, dtype=np.uint32) b1 = a.view (np.dtype(np.uint32).newbyteorder('<')) c1 = b1.view(np.uint8) b2 = a.view (np.dtype(np.uint32).newbyteorder('>')) c2 = b2.view(np.uint8) print c1 print c2 [0 0 0 0 1 0 0 0 2 0 0 0 3 0 0 0 4 0 0 0 5 0 0 0 6 0 0 0 7 0 0 0 8 0 0 0 9 0 0 0] [0 0 0 0 1 0 0 0 2 0 0 0 3 0 0 0 4 0 0 0 5 0 0 0 6 0 0 0 7 0 0 0 8 0 0 0 9 0 0 0]
Wed, 29 Jul 2009 10:20:19 -0400, Neal Becker kirjoitti: [clip]
Can 'view' switch byteorder? Doesn't seem to work: [clip]
I think not: view only alters the dtype, ie., the interpretation of the block of memory. It does not physically reorder the data in memory, which is necessary for unpacking to a different byte order. The reliable way to unpack seems to be np.asarray(a, dtype='<u4').view('u1') which avoids copies when possible. Of course, you could do if a.dtype.newbyteorder('<') != a.dtype: a.byteswap(True) b = a.view('u1') to byte-swap in-place to little-endian order. -- Pauli Virtanen
participants (5)
-
Neal Becker
-
Pauli Virtanen
-
Stéfan van der Walt
-
Travis Oliphant
-
Zachary Pincus