[Numpy-discussion] byteswap questions

Francesc Altet faltet at carabos.com
Tue Nov 1 01:37:26 CST 2005


El dl 31 de 10 del 2005 a les 16:53 -0800, en/na Russell E. Owen va
escriure:
> I've got a module that can send array data to ds9. It screws up on 
> byteswapped data and I'm trying to fix it.

I don't exactly know what a ds9 is, but I'm supposing here that it is
kind of an exotic computer.

> I need to know if the order is bigendian or littleendian, and I can't 
> find a documented way to get that, just an undocumented attribute 
> _byteorder.

Yes, it's undocumented, but as far as I can tell, this works flawlessly
in numarray.

> 2) If the array is not in native byte order, make a native byte ordered 
> copy before sending it.
> 
> The following seems to work:
> if arr.isbyteswapped():
>   arr = arr.copy()
> 
> but is this the recommended way to get native-order copy?

If you can afford doing a memory copy, yes, I think this is a good way
to do it.

> - Is "copy" guaranteed to return a copy in native byte order? The 
> documentation doesn't say.

It does:

In [23]:a._byteorder
Out[23]:'big'

In [24]:a.copy()._byteorder
Out[24]:'little'

In general, copy() will return you a well-behaved (native-byte ordered,
non-strided and non-offsetted) array.

> - I was tempted to use num.array(arr) to make the copy, but the 
> documentation doesn't say what "array" does if the input is a already a 
> numarray array.

This also works:

In [25]:array(a)._byteorder
Out[25]:'little'

and it is very similar to copy() in performance:

In [34]:t1=Timer("b=a.copy()","import numarray;
a=numarray.arange(10);a.byteswap();a._byteorder='big'")

In [35]:t1.repeat(3,10000)
Out[35]:[1.0613389015197754, 1.0313379764556885, 1.0303771495819092]

In [36]:t2=Timer("b=numarray.array(a)","import numarray;
a=numarray.arange(10);a.byteswap();a._byteorder='big'")

In [37]:t2.repeat(3,10000)
Out[37]:[1.2250277996063232, 1.2067301273345947, 1.2336349487304688]

(perhaps copy is just a little bit faster)

> As an aside, I tried to use the byteswapped method, but it has a totally 
> different effect:
> 
> >>> d
> array([[-9012., -9012., -9012., ..., -9012., -9012., -9012.],
> ...type=Float32)
> >>> d.isbyteswapped()
> 1
> >>> dcopy = d.copy()
> >>> d
> array([[-9012., -9012., -9012., ..., -9012., -9012., -9012.],
>  ...type=Float32)
> >>> dcopy.isbyteswapped()
> 0
> >>> dswap = d.byteswapped()
> >>> dswap
> array([[  1.91063654e-38,   1.91063654e-38,   1.91063654e-38, ...,
>   ...type=Float32)
> 
> which I guess means I'd have to byteswap the byteswapped data. Aargh.

This is the intended behaviour. From the docstrings:

In [59]:a.byteswap?
[snip...]
Docstring:
    Byteswap data in place, leaving the _byteorder attribute untouched.


So, you already have done a byteswapping, but you still need to tell the
object that its byteorder has actually changed (if don't, numarray will
convert the data to you local native order before printing it on the
flight). Just issue a:

dswap._byteorder = {"little":"big","big":"little"}[dswap._byteorder]

and you are done. In fact, using byteswap() does the conversion
in-place, and doesn't need a memory copy. This is actually faster than
doing a copy() much of the times:

In [60]:t3=Timer("b=a.byteswap();a._byteorder='little'","import
numarray; a=numarray.arange(10);a.byteswap();a._byteorder='big'")

In [61]:t3.repeat(3,10000)
Out[61]:[0.23770284652709961, 0.23195695877075195, 0.23380589485168457]


Cheers,

-- 
>0,0<   Francesc Altet     http://www.carabos.com/
V   V   Cárabos Coop. V.   Enjoy Data
 "-"






More information about the Numpy-discussion mailing list