You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Julia中把逗号为小数点的String31列转为Float类型的方法

解决DataFrame中逗号小数点转数值类型的问题

问题背景

我有一个包含190列的DataFrame,这些列的格式为String31,使用逗号作为小数点分隔符。需要将这些逗号替换为句号,然后转换为数值格式。

尝试了以下代码,但转换后的结果仍以类似2.0361331369e8的形式显示(误以为是字符串,实际是浮点数的科学计数法):

function custom_parse(x::String, default::Float64)
    try
        return parse(Float64, x)
    catch
        return default
    end
end

for col in names(csv_coop_completo_1993a2022)[4:end]
    csv_coop_completo_1993a2022[!, col] = replace.(string.(csv_coop_completo_1993a2022[!, col]), "," => ".")
    csv_coop_completo_1993a2022[!, col] = map(x -> custom_parse(x, 0.0), csv_coop_completo_1993a2022[!, col])
end

CSV示例数据:

cnpj,ano,razao_social,10000007,11000006,11200002,39999993,60000002,61000001,61100004
171973,199312,COOPSCET,"5651,44","5651,44","5651,44","5651,44","5651,44","5651,44","8994,50"
379891,199312,CECMF CIMENTO TOCANTINS LTDA,"7429594,11","2759951,05","2759951,05","7429594,11","7161085,08","7161085,08","12550184,27"
617290,199312,"CECME SENAI-DF, LTDA","1500909,37","86432,56","86432,31","2632612,27","1573059,16","1573059,16","157922,83"
694877,199312,CECM SERV EXEC FED SECSA�DE DF,"22638658,49","306499,15","304001,15","25747440,55","24006473,31","24006473,31","20193139,66"
968602,199312,CCLA VALE S�O PATRICIO LTDA,"205124653,22","160604715,50","160469198,11","247012935,13","127063766,45","127063766,45","85617744,60"

问题分析

你看到的2.0361331369e8其实是浮点数的科学计数法显示,并非字符串。但原代码存在冗余步骤:先转换为字符串再替换,再单独解析,效率较低,且可能因中间步骤导致类型推断异常。

解决方案

方案1:简化循环逻辑,合并替换与解析

将逗号替换和浮点数解析合并到一个函数中,减少中间变量,确保类型正确转换:

function custom_parse(x::AbstractString, default::Float64=0.0)
    try
        return parse(Float64, replace(x, "," => "."))
    catch
        return default
    end
end

# 遍历目标列批量转换
for col in names(csv_coop_completo_1993a2022)[4:end]
    csv_coop_completo_1993a2022[!, col] = custom_parse.(csv_coop_completo_1993a2022[!, col])
end

方案2:用transform!批量处理(更简洁高效)

利用DataFrames.jl的transform!结合ByRow,实现更简洁的批量列转换:

using DataFrames

# 定义转换函数:替换逗号为句号,解析为浮点数,失败返回0.0
parse_comma_float(x) = tryparse(Float64, replace(x, "," => ".")) |> something(0.0)

# 批量转换第4列及以后的所有列,保留原列名
transform!(csv_coop_completo_1993a2022, names(csv_coop_completo_1993a2022)[4:end] .=> ByRow(parse_comma_float); renamecols=false)

方案3:读取CSV时直接处理(根源解决)

如果还未读取CSV文件,建议在读取阶段就指定小数点分隔符,直接生成数值类型列:

using CSV, DataFrames

# 读取时指定逗号为小数点分隔符,自动推断数值类型
df = CSV.read("your_file.csv", DataFrame; decimal=',')

# 若需强制指定列类型,可补充types参数
df = CSV.read("your_file.csv", DataFrame; decimal=',', types=Dict(zip(names(df)[4:end], repeat([Float64], 190))))

验证转换结果

转换后可通过以下代码确认列类型是否为Float64:

# 查看某一列的类型
println(eltype(csv_coop_completo_1993a2022[!, "10000007"]))

内容的提问来源于stack exchange,提问作者RxT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 00:12:33