我有以下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)
作为你的转换