Julia中遍历列向量转换DataFrame列类型的问题求助
DataFrame中String31类型列转数值型的问题
CSV.read导入DataFrame后,部分含"YR"的列是String31类型,需要转换为数值型,但多次尝试均失败,以下是尝试过程及解决方法:
已尝试的方法及报错
方法1:使用transform!结合parse
代码:
col_years = contains.(names(df),"YR") transform!(df, names(df)[col_years] .=> ByRow(x->parse(Number, x)), renamecols = false)
报错:
MethodError: no method matching parse(::Type{Number}, ::String31) Closest candidates are: parse(::Type{T}, ::AbstractString; base) where T<:Integer at parse.jl:240 parse(::Type{T}, ::AbstractString; kwargs...) where T<:Real at parse.jl:379 parse(::Type{P}, ::AbstractString; kwargs...) where P<:FilePathsBase.AbstractPath at ~/.julia/packages/FilePathsBase/9kSEl/src/path.jl:77
将Number替换为Int后,又出现新错误:
ArgumentError: invalid base 10 digit '.' in "80.0511140452116"
方法2:循环使用convert转换
代码:
for c in names(df)[col_years] df[!, c] = convert.(Number, df[!, c]) end
报错信息与方法1类似。
测试用DataFrame(普通String可转Float64,但实际场景的String31不行):
f = DataFrame(Series = ["SP.POP.DPND"], YR1960 = ["80.0511140452116"], YR1961 = ["80.2223403638055"], YR1962 = ["80.4019428356728"])
解决方法
原因分析
Number是抽象类型,parse函数不支持直接解析到抽象类型,必须使用具体的数值子类型(比如Float64,因为数据包含小数,无法用Int)。- String31属于
AbstractString的子类,parse(::Type{Float64}, ::AbstractString)是有内置方法的,直接指定Float64即可处理。
修正后的方法
方法1:修改transform!代码
col_years = contains.(names(df),"YR") transform!(df, names(df)[col_years] .=> ByRow(x->parse(Float64, x)), renamecols = false)
方法2:修改循环转换代码
for c in names(df)[col_years] df[!, c] = parse.(Float64, df[!, c]) end
优化方案:导入时直接指定列类型
避免后续转换,在CSV.read时直接指定目标列的类型:
using CSV, DataFrames # 先获取文件列名,筛选出含"YR"的列 yr_cols = filter(x -> contains(x, "YR"), CSV.getfieldnames("your_file.csv")) # 导入时指定这些列的类型为Float64 df = CSV.read("your_file.csv", DataFrame; types=Dict(col => Float64 for col in yr_cols))
内容的提问来源于stack exchange,提问作者Vince
相关产品推荐
相关产品推荐

