1

I can't find a way to properly read a csv file containing complex numbers in the following form:

-5.07248931892817e-05+2.50260543778902e-18i,-5.0723848172051e-05+2.870855441657444e-17i,...

Example file available here

user40761
  • 121
  • 4
  • My preference is to read the entire file in unaltered as a string, replace e with *^ and i with I, and then ImportString it. – Oleksandr R. Jun 15 '16 at 13:46

2 Answers2

2

SemanticImport will handle it. Specify the column types explicitly. Example with one column:

SemanticImportString[
 "-5.07248931892817e-05+2.50260543778902e-18i
 -5.0723848172051e-05+2.870855441657444e-17i",
 {"ComplexNumber"}
 ]

This returns a Dataset which you can convert to a list using Normal.


Update: I can import your file without problems in M10.0.2 like this:

str = Import["~/Downloads/f2.csvNk.csv", "String"];
Normal@SemanticImportString[
  StringReplace[str, "," -> "\n"], {"ComplexNumber"}]

It's good practice to create tables with few columns and many rows. In this case, use newline as a separator instead of commas. I achieve this with StringReplace.

Szabolcs
  • 234,956
  • 30
  • 623
  • 1,263
  • I'm obtaining Expression -0.0000507249+2.50261*10^-18 I at position {1} should be of type TypeSystemAnyType. >>` – user40761 Jun 15 '16 at 11:39
  • @jset It's impossible to tell what is going wrong unless we have a dataset that triggers the problem. The code I posted works in M10.4 and M10.0. – Szabolcs Jun 15 '16 at 11:50
  • I've inserted an example file in the question text (link). I'm using mathematica 10.0 on linux – user40761 Jun 15 '16 at 12:49
  • @jset Just to be sure: do you have 10.0.2? If not you really should upgrade to at least 10.0.2. – Szabolcs Jun 15 '16 at 12:57
  • I know, on my personal notebook I have it, but my institution doesn't have it. Thank you – user40761 Jun 15 '16 at 13:07
  • @jset I updated the post. Did you convert to one-column format before trying this (since I said that the format should be specified for each column)? – Szabolcs Jun 15 '16 at 13:24
  • thank you. I'm still obtaining the following error Dataset::invatom: Expression -0.0000507249+2.50261*10^-18 I at position {1} should be of type TypeSystem``AnyType. >> , but I can bypass it by taking the first element of the DataSet (data=normal@Semantic... ; data[[1]]) . – user40761 Jun 15 '16 at 13:43
  • @jset It might be a bug in 10.0.0 then. Maybe try writing to your sysadmin and explain to them that 10.0.2 is free to those who have 10.0.0 and that 10.0.0 is very buggy and really shouldn't be used. In reasonable places they would update. I know that unfortunately in many places they are far from reasonable. – Szabolcs Jun 15 '16 at 13:48
  • I've have a further question. The file I have is generated by Matlab by simply csvwrite(myArrary). Is it possible that there isn't a less artificial way to read it (maybe faster)? – user40761 Jun 15 '16 at 13:50
  • @jset I'm not sure. I know that SemanticImport is not fast. I am not really satisfied with Mathematica's import facilities and sometimes I resort to LibraryLink for speed. If you are using MATLAB and Mathematica together, then you can consider using the MATLink package for fast an easy data transfer, or you can use a more convenient file format such as v5 .mat files (native to MATLAB). Another choice is HDF5 but it doesn't have native support for complex numbers so it will only be convenient if you split to ReIm – Szabolcs Jun 16 '16 at 13:59
0

There is another solution, different from the one posted by @Szabolcs. It deals with string replacing and then converting to expression:

readMatlabComplex[file_] :=ToExpression[
StringSplit[
StringReplace[
ReadList[file, "String"]
 , {"e" -> "*10^", "i" -> "*I"}]
, ","]]

It is about 10 times faster.

user40761
  • 121
  • 4