0

Is there a faster way of reading a buffer of integers to an array of complex numbers?

This works good (if buffer is with floats):

import numpy, struct
binary_string = struct.pack('2f', 1,2)
print numpy.frombuffer(binary_string, dtype=numpy.complex64)
# [ 1. + 2.j]

But, if readed buffer is with integers, there is a problem:

import numpy, struct
binary_string = struct.pack('2i', 1,2)
print numpy.frombuffer(binary_string, dtype=numpy.complex64)
# [  1.40129846e-45 +2.80259693e-45j]

So, I can't find any faster way to convert it except with a slicing:

import numpy, struct
#for int32
binary_string = struct.pack('2i', 1,2)
ints = numpy.frombuffer(binary_string, dtype=numpy.int32)
print ints[::2] + 1j*ints[1::2]
# [ 1. + 2.j]

#for int16
binary_string = struct.pack('2H', 1,2)
ints = numpy.frombuffer(binary_string, dtype=numpy.int16)
print ints[::2] + 1j*ints[1::2]
# [ 1. + 2.j]

Also, is there any of a "complex number with integers" datatype, so a result could look like:

[1 + 2j]

Thanks.

VVV
  • 53
  • 5
  • About the part about complex numbers, you can check out this [thread](http://stackoverflow.com/questions/8370637/complex-numbers-usage-in-python) – MaTh Jan 08 '16 at 11:15
  • "faster" is almost never the right goal. – stark Jan 08 '16 at 11:58
  • ok about "faster", but is there some "native" numpy method except slicing? – VVV Jan 08 '16 at 12:07

1 Answers1

2

For a string packed with 4-byte ints you could use:

In [35]: np.frombuffer(struct.pack('2i', 1,2), dtype='i4').astype(np.float32).view(np.complex64)
Out[35]: array([ 1.+2.j], dtype=complex64)

For a string packed with 2-byte ints you could use:

In [34]: np.frombuffer(struct.pack('2H', 1,2), dtype='i2').astype(np.float32).view(np.complex64)
Out[34]: array([ 1.+2.j], dtype=complex64)

The idea here is to let np.frombuffer read the string using an integer dtype appropriate for the string. Then use astype to preserve the integer values but change the underlying representation to float32s. Then use view to reinterpret the underlying data as complex64s (so every two float32s get regarded as one complex64).

unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • That's really make my script to works faster (for about 40%), and it is a native method other than slicing. Thanks. Thanks. Thanks. – VVV Jan 08 '16 at 14:11