微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何重塑、分组和重命名 Julia 数据框?

如何解决如何重塑、分组和重命名 Julia 数据框?

我有以下数据帧:

  Police Product  PV1  PV2  PV3   PM1   PM2  PM3
0       1      AA   10    8   14   150   145  140
1       2      AB   25    4    7   700   650  620
2       3      AA   13   22    5   120    80   60
3       4      AA   12    6   12   250   170  120
4       5      AB   10   13    5   500   430  350
5       6      BC    7   21   12  1200  1000  900

PV1 是第 1 年的 PV,第 2 年的 PV2,.... 我想结合整形和分组操作+一些重命名的东西来获得下面的DF:

  Product Item  Year1  Year2  Year3
0      AA   PV     35     36     31
1      AA   PM    520    395    320
2      AB   PV     35     17     12
3      AB   PM   1200   1080    970
4      BC   PV      7     21     12
5      BC   PM   1200   1000    900 

它通过对产品名称的操作进行分组,并重塑DF以将项目作为列传递并将每个的总和放在新列中。

我找到了一种在 Python 中执行此操作的方法,但我现在正在寻找一种在 Julia 中传递我的代码解决方案。 groupby 操作没问题,但我在重塑/重命名部分有更多问题。

如果您有任何想法,我将不胜感激。

感谢您的帮助

编辑:

按照您的建议,我已经安装了 Julia 1.5 并将 DataFrames pkg 更新为 0.22 版本。结果,代码运行良好。唯一剩下的问题与我的真实 DF 中列名的非恒定长度有关,这使得代码的转换部分不完全适合。我将寻找一种使用正则表达式拆分 char/num 的方法

非常感谢您的时间,并对编辑中的错误表示歉意。

解决方法

可能有几种方法可以做到这一点。这是一个使用内置函数的示例(同时利用了几个高级功能,因此如果您对代码有任何疑问,请发表评论,我可以解释):

julia> using CSV,DataFrames,Chain

julia> str = """
       Police Product  PV1  PV2  PV3   PM1   PM2  PM3
            1      AA   10    8   14   150   145  140
            2      AB   25    4    7   700   650  620
            3      AA   13   22    5   120    80   60
            4      AA   12    6   12   250   170  120
            5      AB   10   13    5   500   430  350
            6      BC    7   21   12  1200  1000  900""";

julia> @chain str begin
           IOBuffer
           CSV.read(DataFrame,ignorerepeated=true,delim=" ")
           groupby(:Product)
           combine(names(df,r"\d") .=> sum,renamecols=false)
           stack(Not(:Product))
           transform!(:variable => ByRow(x -> (first(x,2),last(x,1))) => [:Item,:Year])
           unstack([:Product,:Item],:Year,:value,renamecols = x -> Symbol("Year",x))
           sort!(:Product)
       end
6×5 DataFrame
 Row │ Product  Item    Year1   Year2   Year3
     │ String   String  Int64?  Int64?  Int64?
─────┼─────────────────────────────────────────
   1 │ AA       PV          35      36      31
   2 │ AA       PM         520     395     320
   3 │ AB       PV          35      17      12
   4 │ AB       PM        1200    1080     970
   5 │ BC       PV           7      21      12
   6 │ BC       PM        1200    1000     900

我使用 Chain.jl 只是为了展示如何在实践中使用它(当然它不是必需的)。

您可以在处理的任何阶段后添加 @aside show(_) 注释以查看处理步骤的结果。

编辑:

这是您需要的正则表达式吗(拆分非数字字符后跟数字字符)?

julia> match(r"([^\d]+)(\d+)","fsdfds123").captures
2-element Array{Union{Nothing,SubString{String}},1}:
 "fsdfds"
 "123"

然后就写:

ByRow(x -> match(r"([^\d]+)(\d+)",x).captures)

作为你的转变

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。