我有一个包含两列 a 和 b 的数据框,目前两列看起来都像 a 列,但我想添加分隔符,以便 b 列如下所示。我尝试过使用包format.jl。但我还没有得到我想要的结果。也许值得一提的是,两列都是 Int64,列名 a 和 b 都是符号类型。
a | b
150000 | 1500,00
27 | 27,00
16614 | 166,14
除了使用 format.jl 之外,还有其他方法可以解决这个问题吗?或者 format.jl 是正确的选择吗?
假设您希望逗号位于其典型位置而不是如何书写它们,这是一种方法:
julia> using DataFrames, Format
julia> f(x) = format(x, commas=true)
f (generic function with 1 method)
julia> df = DataFrame(a = [1000000, 200000, 30000])
3×1 DataFrame
Row │ a
│ Int64
─────┼─────────
1 │ 1000000
2 │ 200000
3 │ 30000
julia> transform(df, :a => ByRow(f) => :a_string)
3×2 DataFrame
Row │ a a_string
│ Int64 String
─────┼────────────────────
1 │ 1000000 1,000,000
2 │ 200000 200,000
3 │ 30000 30,000
如果您想要替换该行,请使用
transform(df, :a => ByRow(f), renamecols=false)
。
如果您只想要输出向量而不是更改 DataFrame,则可以使用 format.(df.a, commas=true)
您可以编写自己的函数
f
来实现相同的行为,但您也可以使用 别人已经在 Format.jl 包中编写的函数。
但是,一旦将数据转换为上述
String
,您将无法过滤/排序/分析 DataFrame 中的数值数据。我建议您使用 PrettyTables 包在打印步骤中应用格式(而不是修改 DataFrame 本身以包含字符串)。这可以一次性格式化整个 DataFrame。
julia> using DataFrames, PrettyTables
julia> df = DataFrame(a = [1000000, 200000, 30000], b = [500, 6000, 70000])
3×2 DataFrame
Row │ a b
│ Int64 Int64
─────┼────────────────
1 │ 1000000 500
2 │ 200000 6000
3 │ 30000 70000
julia> pretty_table(df, formatters = ft_printf("%'d"))
┌───────────┬────────┐
│ a │ b │
│ Int64 │ Int64 │
├───────────┼────────┤
│ 1,000,000 │ 500 │
│ 200,000 │ 6,000 │
│ 30,000 │ 70,000 │
└───────────┴────────┘
(编辑以反映问题中的更新规格)
julia> df = DataFrame(a = [150000, 27, 16614]);
julia> function insertdecimalcomma(n)
if n < 100
return string(n) * ",00"
else
return replace(string(n), r"(..)$" => s",\1")
end
end
insertdecimalcomma (generic function with 1 method)
julia> df.b = insertdecimalcomma.(df.a)
julia> df
3×2 DataFrame
Row │ a b
│ Int64 String
─────┼─────────────────
1 │ 150000 1500,00
2 │ 27 27,00
3 │ 16614 166,14
请注意,在此更改后,
b
列必然是String
,因为整数类型无法在其中存储格式信息。
如果您有大量数据并发现需要更好的性能,您可能还想使用
InlineStrings
包:
julia> #same as before upto the function definition
julia> using InlineStrings
julia> df.b = inlinestrings(insertdecimalcomma.(df.a))
3-element Vector{String7}:
"1500,00"
"27,00"
"166,14"
这会将
b
列的数据存储为固定大小的字符串(此处为 String7
类型),通常将其视为普通 String
,但性能会显着提高。
可能有人会在这里搜索空格千位分隔符我编写了以下基于正则表达式的转录:
#first conversion of a float to string (w/o scientific notation)
str = @sprintf("%.2f",nbr)
matches = eachmatch(r"\d{1,3}(?=(?:\d{3})+(?!\d))", str)
decimal_match = match(r"\d{3}\.\d+$", str)
... vcat the vector of matches with decimal part, then join with " "...
你只需要处理向上的数字< 100.00 as the regex doesn't account for them (it's simplistic but do the job). I use this function as a formatter in a pretty print of a DataFrame.