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



我有以下DataFrame:

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是第一年的PV,第二年的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中传递我的代码的解决方案。对于分组操作没有问题,但我在重塑/重命名部分有更多问题。

如果你有任何想法,我将非常感激。

谢谢你的帮助

编辑:

按照您的建议,我已经安装了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。我只是为了展示如何在实践中使用它(当然,这是不需要的)。

您可以在处理的任何阶段之后添加@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)

作为你的转换

最新更新