如何对 julia DataFrame 中的分组记录进行分组和排名

How to group and rank grouped records in a julia DataFrame

在 julia 中,我想在数据框中的一列给出的组内生成一个排名,并根据第二列生成排名。我想将每组中的排名和行数添加到数据框中的新列中。当按 :id 分组并按 :b 排名时,以下内容似乎符合我的要求(这是正确的吗?),但我无法为排名列命名。这是否足够高效,或者我应该在对 :id 和 :b 排序后简单地循环执行?在我的实际 data/application 中,我将拥有数百万行和数十万个唯一组。

 x = DataFrame(id=["a","b","a","c","c","a","c","a","a","c"], 
                b=[2,5,7,8,3,9,1,10,4,6], 
                c=["one","two","three","four","five","six","seven","eight","nine","ten"])
 y = combine(groupby(x,:id), sdf -> sort(sdf,:b), s->1:nrow(s), nrow => :n)

这个输出是正确的,除了我想给 'x1' 一个像 'rank':

这样的列名
 Row │ id      b      c       x1     n     
     │ String  Int64  String  Int64  Int64 
─────┼─────────────────────────────────────
   1 │ a           2  one         1      5
   2 │ a           4  nine        2      5
   3 │ a           7  three       3      5
   4 │ a           9  six         4      5
   5 │ a          10  eight       5      5
   6 │ b           5  two         1      1
   7 │ c           1  seven       1      4
   8 │ c           3  five        2      4
   9 │ c           6  ten         3      4
  10 │ c           8  four        4      4

这是给排名列命名的方法:

julia> combine(groupby(x,:id), sdf -> sort(sdf,:b), s->(rank=1:nrow(s),), nrow => :n)
10×5 DataFrame
 Row │ id      b      c       rank   n
     │ String  Int64  String  Int64  Int64
─────┼─────────────────────────────────────
   1 │ a           2  one         1      5
   2 │ a           4  nine        2      5
   3 │ a           7  three       3      5
   4 │ a           9  six         4      5
   5 │ a          10  eight       5      5
   6 │ b           5  two         1      1
   7 │ c           1  seven       1      4
   8 │ c           3  five        2      4
   9 │ c           6  ten         3      4
  10 │ c           8  four        4      4

或(这对我来说似乎更干净)

julia> combine(groupby(x,:id), sdf -> sort(sdf,:b), :id => eachindex => :rank, nrow => :n)
10×5 DataFrame
 Row │ id      b      c       rank   n
     │ String  Int64  String  Int64  Int64
─────┼─────────────────────────────────────
   1 │ a           2  one         1      5
   2 │ a           4  nine        2      5
   3 │ a           7  three       3      5
   4 │ a           9  six         4      5
   5 │ a          10  eight       5      5
   6 │ b           5  two         1      1
   7 │ c           1  seven       1      4
   8 │ c           3  five        2      4
   9 │ c           6  ten         3      4
  10 │ c           8  four        4      4

(有一个 PR 打开以添加一个选项以更轻松地添加行号 --- 如果您觉得有用,请在此处发表评论)

关于您关于性能的问题,以下可能更快;权衡是在对大数据帧进行一次排序与多次对小数据帧进行排序之间进行权衡:

transform!(groupby(sort(x, [:id, :b]), :id), :id => eachindex => :rank, nrow => :n)

当您运行在您的完整数据集上进行比较时,如果能得到有关比较的反馈会很有趣。