In my workflow, I typically use C++ for production code and Python for data
post-processing and data analysis. A major annoyance is that NumPy’s
genfromtxt does not recognize the C++ complex number format.
Of course, one could write their own I/O for their C++ production codes, but most libraries have built-in I/O functions and it’s just a pain. It’s much easier to get Python to read the C++ format!
The Issue
C++ represents a given complex number \(z=a+ib\) as (a,b). When using
genfromtxt to read a file containing an array of complex numbers, the obvious
import numpy as np
x = np.genfromtxt("file", dtype=complex)
yields NaNs for the real part and 0s for the imaginary part. To get Python
to understand the format, an easy solution is to first parse the elements of the
array as strings, then use a lambda function to effectively cast the strings
as complex numbers. Here’s the code.
The Code
def LoadComplexData(file,**genfromtext_args):
"""
Load complex data in the C++ format in numpy.
"""
array_as_strings = np.genfromtext(file,dtype=str,**genfromtext_args)
complex_parser = np.vectorize(lambda x: complex(*eval(x)))
return complex_parser(array_as_strings)
First, we load the array of complex numbers as an array of strings in Python.
Then, we use np.vectorize to define a callable that takes each of the array
and applies the complex(*eval(x)) to it. eval() takes the string and evaluates
it to a tuple of floats. The * operator unpacks the tuple such that we are calling
complex(a,b) properly. This returns a complex number in Python format.
A solution based on a genfromtxt converter could be more elegant, but I wasn’t
able to find a way to apply a converter to every column of the input file
instead of a specific column.
You can try it for yourself with these files. This was tested with Numpy v1.14.5.
comments powered by Disqus