3

Just a short question, I am trying to import a complex array (matrix) from Python to Mathematica by first writing to a csv. file. When I Import the csv. array to Mathematica it is in a form (matrix elements are wrapped in round brackets with imaginary part denoted with Python imaginary part symbol 'j') that is not compatible with Mathematica as indicated by the code example (2x2 matrix) below: The matrix $A$ that I am importing as an example is: \begin{pmatrix} i &2 \\ 3 & 4 \end{pmatrix}

A = Import["C:\\Users\\JohnDoe\\Documents\\PycharmProjects\\pythonProject\\foo.csv", "Data"]

where the output of imported array A in Mathematica is:

{{(0.00000000000000000e+00+1.00000000000000000e+00j),(2.00000000000000000e+00+0.00000000000000000e+00j)},
{(3.00000000000000000e+00+0.00000000000000000e+00j), (4.00000000000000000e+00+0.00000000000000000e+00j)}}

Can anyone advise on how to process the array after importing such that it is in a standard Mathematica form without brackets (and standard Mathematica imaginary part)?

Thanks for any assistance.

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
John Doe
  • 371
  • 1
  • 11

1 Answers1

8

In Python

To reproduce the same result, I use the following code in python:

import numpy

a = numpy.asarray([ [1j,2+0j], [3+0j,4+0j] ])

In python when you want to export the array in CSV file with Numpy, use fmt to change the default formatting (i stands for integer, see here for more information):

numpy.savetxt("foo.csv", a, delimiter=",", fmt="%i")

Now you will have a file containing the following data:

File: foo.csv

(0+1j), (2+0j) (3+0j), (4+0j)

In Mathematica

First import the file:

data = Import["C:\\foo.csv"];

then define a function to replace j with I and remove the paranthesis and interpret that as a complex number:

toComplex[s_String] := 
 Interpreter["ComplexNumber"][
  StringReplace[s, {"j" -> "I", "(" -> "", ")" -> ""}]]

Now apply the function to every element you'd imported:

Map[toComplex, data, {2}]

(Out: {{I, 2}, {3, 4}} )

Another Solution

If possible, you can use ExternalEvaluate["Python", ... ] to convert to Mathematica built-in data types directly:

a = ExternalEvaluate["Python", "[[1j,2+0j],[3+0j,4+0j]]"]

(Out: {{0. + 1. I, 2. + 0. I}, {3. + 0. I, 4. + 0. I}} )

Update - Mathematica to Python

Mathematica

data = {{0. + 1. I, 2. + 0. I}, {3. + 0. I, 4. + 0. I}};

Export["C:\bar.csv", StringReplace[ExportString[data, "CSV"], "*I" -> "j"], "Text"]

File: bar.csv

0.+1.j,2.+0.j
3.+0.j,4.+0.j

Python

With Numpy:

import numpy as np
result1= np.vectorize(complex)(np.genfromtxt('bar.csv', delimiter=',',dtype='str'))

print(result1)

Out: [[0.+1.j 2.+0.j]

[3.+0.j 4.+0.j]]

print(result1[0][1].real)

Out: 2.0

Pure Python:

result2 = []
delimiter=','
with open('bar.csv','r') as f:
    for line in f.readlines():
        result2.append([complex(i) for i in line.strip().split(delimiter)])

print(result2)

Out: [[1j, (2+0j)], [(3+0j), (4+0j)]]

print(result2[0][1].real)

Out: 2.0

Update 2 - Small numbers

Mathematica

SeedRandom[1234];
data = RandomComplex[{0, 1 + 1 I}, {2, 2}]*10^-8;

Export["C:\foo2.csv", StringReplace[ExportString[data, "CSV"], {"^" -> "e", "I" -> "j", "I" -> "j"}], "Text"]

Re[data[[1, 1]]] // InputForm (Out: 8.766084925741931^-9 *)

Python

import numpy as np

result3=np.vectorize(complex)(np.genfromtxt(r"C:\imag2.csv", delimiter=',',dtype='str'))

print(result3[0][0].real)

Out: 8.766084925741931e-09

Ben Izd
  • 9,229
  • 1
  • 14
  • 45