Julia:将数字字符串转换为浮点数或整数

38

我正在尝试将从数据库中提取的数字数据写入Float64[]。原始数据以::ASCIIString格式呈现,因此尝试将其推送到数组会出现以下错误:

julia> push!(a, "1")
ERROR: MethodError: `convert` has no method matching convert(::Type{Float64}, ::ASCIIString)
This may have arisen from a call to the constructor Float64(...),
since type constructors fall back to convert methods.
Closest candidates are:
  call{T}(::Type{T}, ::Any)
  convert(::Type{Float64}, ::Int8)
  convert(::Type{Float64}, ::Int16)
  ...
 in push! at array.jl:432

尝试直接转换数据会出现同样的错误:
julia> convert(Float64, "1")
ERROR: MethodError: `convert` has no method matching convert(::Type{Float64}, ::ASCIIString)
This may have arisen from a call to the constructor Float64(...),
since type constructors fall back to convert methods.
Closest candidates are:
  call{T}(::Type{T}, ::Any)
  convert(::Type{Float64}, ::Int8)
  convert(::Type{Float64}, ::Int16)
  ...

在我知道数据是数字的情况下,有没有一种方法可以在推送之前进行转换?

附:我正在使用版本0.4.0


3
顺便提一下,考虑使用tryparse(Float64,x)代替parse。它会返回一个可为空的Float类型,如果字符串无法解析,它将为null。 - Dan Getz
2
好的建议,谢谢。顺便说一句,如果你想写一个答案,我会接受它,否则我会在一两天内为了完整性而写点东西。 - peter-b
3个回答

52
你可以从字符串中解析出一个浮点数,例如parse(Float64,"1")。对于向量的情况,
map(x->parse(Float64,x),stringvec)

将解析整个向量。

顺便提一下,考虑使用tryparse(Float64,x)代替parse。它返回一个Nullable{Float64},如果字符串无法解析,则为null。例如:

isnull(tryparse(Float64,"33.2.1")) == true

通常情况下,如果出现解析错误,我们希望有一个默认值:

strvec = ["1.2","NA","-1e3"]
map(x->(v = tryparse(Float64,x); isnull(v) ? 0.0 : get(v)),strvec)
# gives [1.2,0.0,-1000.0]

2021年的注释:什么是Nullable{T}?它看起来应该是Union{Nothing,T}吗?现在isnull应该改为isnothing(或者=== nothing)吗? - BallpointBen

9

使用parse(Float64,"1")来转换数据类型。

详见:解析规范


1
同时(Julia 1.0已发布),可使用以下链接:https://docs.julialang.org/en/latest/base/numbers/#Base.parse - Reiner Martin
现在是 https://docs.julialang.org/en/v1/base/numbers/#Base.parse。 - Ricoter

0
之前的回答都很好,但是我想进一步展开:
#col1 = df[:,3]
col1 = ["1.2", "NA", "", Base.missing, "-1e3"]

# I do not like writing unreadable code like this:
col2 = map(x->(x=ismissing(x) ? "" : x; x=tryparse(Float64,x); isnothing(x) ? missing : x), col1)

如果原始数据全是数字,则返回 Array{Float64,1}

5-element Array{Union{Missing, Float64},1}:
     1.2
      missing
      missing
      missing
 -1000.0

替代方案(解释):

function convert_to_float(column)
    new_column = map(x -> (
            x = ismissing(x) ? "" : x;  # no method matching tryparse(::Type{Float64}, ::Missing)
            x = tryparse(Float64, x);   # returns: Float64 or nothing
            isnothing(x) ? missing : x; # options: missing, or "", or 0.0, or nothing
            ), column)  # input 
    # returns Array{Float64,1} OR Array{Union{Missing, Float64},1}
    return new_column
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接