在 julia 的数据框中添加千位分隔符

问题描述 投票:0回答:3

我有一个包含两列 a 和 b 的数据框,目前两列看起来都像 a 列,但我想添加分隔符,以便 b 列如下所示。我尝试过使用包format.jl。但我还没有得到我想要的结果。也许值得一提的是,两列都是 Int64,列名 a 和 b 都是符号类型。

 a      |    b
150000  | 1500,00 
27      | 27,00
16614   | 166,14

除了使用 format.jl 之外,还有其他方法可以解决这个问题吗?或者 format.jl 是正确的选择吗?

formatting julia julia-dataframe
3个回答
3
投票

假设您希望逗号位于其典型位置而不是如何书写它们,这是一种方法:

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 │
└───────────┴────────┘

2
投票

(编辑以反映问题中的更新规格)

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
,但性能会显着提高。


0
投票

可能有人会在这里搜索空格千位分隔符我编写了以下基于正则表达式的转录:

#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.

© www.soinside.com 2019 - 2024. All rights reserved.