Юлия: Как преобразовать числовую строку с символом питания "^" в число с плавающей запятой - PullRequest
1 голос
/ 19 марта 2019

У меня проблемы с преобразованием массива числовых строк в массив соответствующих чисел с плавающей запятой.(Гипотетический) строковый массив:

arr = ["8264.", "7.1050^-7", "9970.", "2.1090^-6", "5.2378^-7"]

Я хотел бы преобразовать его в:

arr = [8264., 1.0940859076672388e-6, 9970., 0.011364243260505457, 9.246079446497013e-6]

Как новичок Юлии, я понятия не имею, как заставить оператора power«^» в формате строки, чтобы сделать правильную работу в преобразовании.Я высоко ценю ваши предложения!

Ответы [ 2 ]

4 голосов
/ 19 марта 2019

Эта функция будет анализировать обе формы без показателя степени.

function foo(s)
    a=parse.(Float64,split(s,'^'))
    length(a)>1 && return a[1]^a[2]
    a[1]
end
2 голосов
/ 19 марта 2019

Довольно некрасиво, но выполняет свою работу:

eval.(Meta.parse.(arr))

UPDATE:

Позвольте мне немного рассказать о том, что это делает и почему это не очень хороший стиль.

Meta.parse преобразует String в эссе Джулии Expr. Точка указывает, что мы хотим транслировать Meta.parse на каждую строку в arr, то есть применять ее к каждому элементу. После этого мы используем eval - снова транслируется - для оценки выражений.

Это дает правильный результат, так как буквально принимает каждую строку как «команду» Джулии и, следовательно, знает, что ^ указывает на степень. Однако, помимо того, что он медленный, он потенциально небезопасен, поскольку можно ввести произвольный код Джулии.

UPDATE:

Более безопасный и быстрый способ получить желаемый результат - определить короткую функцию, которая выполняет преобразование:

julia> function mystr2float(s)
           !occursin('^', s) && return parse(Float64, s)
           x = parse.(Float64, split(s, '^'))
           return x[1]^x[2]
       end
mystr2float (generic function with 1 method)

julia> mystr2float.(arr)
5-element Array{Float64,1}:
 8264.0
    1.0940859076672388e-6
 9970.0
    0.011364243260505457
    9.246079446497013e-6

julia> using BenchmarkTools

julia> @btime eval.(Meta.parse.($arr));
  651.000 μs (173 allocations: 9.27 KiB)

julia> @btime mystr2float.($arr);
  5.567 μs (18 allocations: 1.02 KiB)

UPDATE:

Сравнение производительности с предложением @ dberge ниже:

julia> @btime mystr2float.($arr);
  5.516 μs (18 allocations: 1.02 KiB)

julia> @btime foo.($arr);
  5.767 μs (24 allocations: 1.47 KiB)
...