Ruby CSV gem 返回 Infinity 而不是 double
Ruby CSV gem returning Infinity instead of double
我有一个方法可以处理 CSV 文件并上传到 Postgres。
CSV.foreach(path, converters: :all)
遇到数字比如“2.02E+17”就上传“2.0150519e+17”,遇到“20150515E000590”就上传"Infinity".
如果我设置
CSV.foreach(path)
遇到“2.02E+17”时,它正在将“20150519E000010”和“20150515E000590”上传为“20150515E000590”。
我想上传 Excel 中显示的内容。所以在“2.02E+17”的情况下我想上传“2.02E+17”,但在“20150515E000590”的情况下我想上传“20150515E000590”而不是"Infinity"。我想我的问题是如何让 CSV 不使用 "Infinity"?
覆盖“20150515E000590”
首先,Postgres 可以在没有 Ruby 帮助的情况下处理加载 CSV。至于你的问题...
CSV 不定义数据类型,因此每当您将 CSV 数据读入需要数据类型(如 Excel 或 Ruby)的内容时,程序都必须猜测。
当Excel看到20150519E000010
时,猜测这是科学记数法20150519e10即20150519×1010。 Excel 区分电子表格中的基础 数据 和 显示 的方式,因此在本例中它选择了显示该数字的更短方式:2.02E+17
。因此,即使 Excel 向您显示 2.02E+17
,文件中的 实际数据 是 20150519E000010
.
当您读取 Ruby 中的 CSV 并告诉它转换为 Ruby 的数据类型时,它会做出相同的猜测(即科学记数法),但您会得到不同的显示:2.0150519e+17
。这应该是预料之中的,因为 2.02E+17
是 Excel 缩短显示数字的方式 。 Ruby 的数据类型不符合 Excel。这也解释了为什么20150515E00059
变成了Infinity
。 20150515×1059 对于 Ruby 的浮点数据类型来说太大了,所以 Ruby 将其转换为最大可能的浮点数:Infinity.
但是,我强烈怀疑Excel和Ruby都是错误的。当我看到 20150515E000059
时,它看起来像 2015-05-15 00:00:59
。这不是科学计数法中的数字,而是时间戳!您可以定义一个自定义转换器来处理格式:
CSV::Converters[:mytime] = lambda do |s|
DateTime.parse(s.tr(?E, ?T)) rescue s
end
CSV.parse("20150515000019", converters: :mytime)
# [[#<DateTime: 2015-05-15T00:00:19+00:00 ((2457158j,19s,0n),+0s,2299161j)>]]
我有一个方法可以处理 CSV 文件并上传到 Postgres。
CSV.foreach(path, converters: :all)
遇到数字比如“2.02E+17”就上传“2.0150519e+17”,遇到“20150515E000590”就上传"Infinity".
如果我设置
CSV.foreach(path)
遇到“2.02E+17”时,它正在将“20150519E000010”和“20150515E000590”上传为“20150515E000590”。
我想上传 Excel 中显示的内容。所以在“2.02E+17”的情况下我想上传“2.02E+17”,但在“20150515E000590”的情况下我想上传“20150515E000590”而不是"Infinity"。我想我的问题是如何让 CSV 不使用 "Infinity"?
覆盖“20150515E000590”首先,Postgres 可以在没有 Ruby 帮助的情况下处理加载 CSV。至于你的问题...
CSV 不定义数据类型,因此每当您将 CSV 数据读入需要数据类型(如 Excel 或 Ruby)的内容时,程序都必须猜测。
当Excel看到20150519E000010
时,猜测这是科学记数法20150519e10即20150519×1010。 Excel 区分电子表格中的基础 数据 和 显示 的方式,因此在本例中它选择了显示该数字的更短方式:2.02E+17
。因此,即使 Excel 向您显示 2.02E+17
,文件中的 实际数据 是 20150519E000010
.
当您读取 Ruby 中的 CSV 并告诉它转换为 Ruby 的数据类型时,它会做出相同的猜测(即科学记数法),但您会得到不同的显示:2.0150519e+17
。这应该是预料之中的,因为 2.02E+17
是 Excel 缩短显示数字的方式 。 Ruby 的数据类型不符合 Excel。这也解释了为什么20150515E00059
变成了Infinity
。 20150515×1059 对于 Ruby 的浮点数据类型来说太大了,所以 Ruby 将其转换为最大可能的浮点数:Infinity.
但是,我强烈怀疑Excel和Ruby都是错误的。当我看到 20150515E000059
时,它看起来像 2015-05-15 00:00:59
。这不是科学计数法中的数字,而是时间戳!您可以定义一个自定义转换器来处理格式:
CSV::Converters[:mytime] = lambda do |s|
DateTime.parse(s.tr(?E, ?T)) rescue s
end
CSV.parse("20150515000019", converters: :mytime)
# [[#<DateTime: 2015-05-15T00:00:19+00:00 ((2457158j,19s,0n),+0s,2299161j)>]]