Arrays 基于阵列中的分组(和条件)创建阵列
因此,我将以下数组构造为数组{Tuple{Int,Float64,Int,Int},1},但它也可以是数组数组数组,其中Tuple的第一个元素是ID,第二个是表示成本的数字。我想做的是按ID分组,然后取该ID的最便宜成本和第二便宜成本之间的成本差,如果没有第二成本,成本差应该是typemaxFloat64-firstcost。关于元组的第三个和第四个元素,我想保留第一个成本或最小成本的元素。 我所拥有的例子Arrays 基于阵列中的分组(和条件)创建阵列,arrays,performance,julia,Arrays,Performance,Julia,因此,我将以下数组构造为数组{Tuple{Int,Float64,Int,Int},1},但它也可以是数组数组数组,其中Tuple的第一个元素是ID,第二个是表示成本的数字。我想做的是按ID分组,然后取该ID的最便宜成本和第二便宜成本之间的成本差,如果没有第二成本,成本差应该是typemaxFloat64-firstcost。关于元组的第三个和第四个元素,我想保留第一个成本或最小成本的元素。 我所拥有的例子 (1, 223.2, 2, 2) (1, 253.2, 3, 2) (2, 220.0,
(1, 223.2, 2, 2)
(1, 253.2, 3, 2)
(2, 220.0, 4, 6)
(3, 110.0, 1, 4)
(3, 100.0, 3, 8)
我想要的示例:
(1, 30.0, 2, 2)
(2, typemax(Float64)-220.0, 4, 6)
(3,10.0, 3, 8)
这是一种方法:
A = [(1, 223.2, 2, 2), (1, 253.2, 3, 2), (2, 220.0, 4, 6), (3, 110.0, 1, 4), (3, 100.0, 3, 8)]
function f(a)
aux(b::Vector) = (b[1][1], (length(b) == 1 ? typemax(Float64) : b[2][2]) - b[1][2], b[1][3:4]...)
sort([aux(sort(filter(x -> x[1] == i, a))) for i in Set(map(first, a))])
end
@show f(A)
有一个SplitApplyCombine.jl,它实现了类似于DataFrames中的SplitApplyCombine逻辑,这并不奇怪。这是一个例子,在这个例子中,我将远离简单的一行程序/简短的解决方案,并更明确地写出一些东西,以使代码可读性和可理解性,如果其他人或您自己在几个月的时间内!内容如下:
julia> tups = [(1, 223.2, 2, 2)
(1, 253.2, 3, 2)
(2, 220.0, 4, 6)
(3, 110.0, 1, 4)
(3, 100.0, 3, 8)]
5-element Array{Tuple{Int64,Float64,Int64,Int64},1}:
(1, 223.2, 2, 2)
(1, 253.2, 3, 2)
(2, 220.0, 4, 6)
(3, 110.0, 1, 4)
(3, 100.0, 3, 8)
julia> using SplitApplyCombine
julia> function my_fun(x) # function to apply
if length(x) == 1
return (x[1][1], typemax(Float64) - x[1][2], x[1][3], x[1][4])
else
return (x[1][1], -diff(sort(getindex.(x, 2), rev = true)[1:2]), x[1][4])
end
end
my_fun (generic function with 1 method)
julia> [my_fun(x) for x in group(first, tups)] # apply function group wise
3-element Array{Tuple{Int64,Any,Int64,Vararg{Int64,N} where N},1}:
(2, Inf, 4, 6)
(3, [10.0], 4)
(1, [30.0], 2)
如果性能是一个问题,您可能想考虑一下我的乐趣,并做一些分析,看看是否以及如何改进它-我在这里做的唯一一件事是使用diff从排序数组的第二个元素中减去第一个元素,以避免两次排序。您使用的是DataFrames.jl吗?它类似于Python的熊猫,可能非常适合解决此类问题。嗨!我没有使用dataframes,我正在使用算法,所以我认为使用dataframes会更困难。好的,这是有道理的,dataframes.jl中有一个groupby函数,这正是您所需要的,所以使用它可能不会有太多开销?是的,我现在正在使用,但这是最后的手段,我正在寻找改进:谢谢,这个例子非常好用,我将在我的代码中尝试。