Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
按julia中的公共列值合并数组_Julia_Array Merge - Fatal编程技术网

按julia中的公共列值合并数组

按julia中的公共列值合并数组,julia,array-merge,Julia,Array Merge,假设Julia中有以下3个数组: 5.03.5 6.0 3.6 7.0 3.0 5.04.5 6.0 4.7 8.0 3.0 5.04.0 6.0 3.2 8.0 4.0 我想将3个数组合并到一个数组中,通过第一列的公共值,对第二列的值求和。结果必须是以下数组: 5.0 12 6.0 11.5 7.0 3.0 8.0 7.0 我尝试了vcat和reduce,但没有得到假装的结果。是否有一种相对简单的方法来编写指令,避免耗时的代码?谢谢大家! 可能有很多方法可以做到这一点。如果您想避免编

假设Julia中有以下3个数组:

5.03.5
6.0  3.6
7.0 3.0

5.04.5
6.0  4.7
8.0 3.0

5.04.0
6.0  3.2
8.0 4.0

我想将3个数组合并到一个数组中,通过第一列的公共值,对第二列的值求和。结果必须是以下数组:

5.0 12
6.0  11.5
7.0  3.0
8.0 7.0


我尝试了
vcat
reduce
,但没有得到假装的结果。是否有一种相对简单的方法来编写指令,避免耗时的代码?谢谢大家!

可能有很多方法可以做到这一点。如果您想避免编码,可以使用DataFrames包。这不是最快的解决方案,但它很短

假设已将数组定义为变量:

x = [5.0  3.5
     6.0  3.6
     7.0  3.0]

y = [5.0  4.5
     6.0  4.7
     8.0  3.0]

z = [5.0  4.0
     6.0  3.2
     8.0  4.0]
然后你可以做:

using DataFrames
Matrix(aggregate(DataFrame(vcat(x,y,z)), :x1, sum))

:x1
部分是因为在默认情况下,
数据帧
的第一列被称为
:x1
,如果您没有给它一个明确的名称。在此配方中,我们将矩阵转换为数据帧,将其聚合并将结果转换回矩阵。

无需额外包装,可能的解决方案如下

function aggregate(m::Array{<:Number,2}...)

    result=sortrows(vcat(m...))

    n = size(result,1)
    if n <= 1
        return result
    end 

    key_idx=1
    key=result[key_idx,1]

    for i in 2:n
      if key==result[i,1]
          result[key_idx,2:end] += result[i,2:end]
      else
          key = result[i,1]
          key_idx += 1
          result[key_idx,1]     = key 
          result[key_idx,2:end] = result[i,2:end]
      end
    end

    return result[1:key_idx,:]
end   
印刷品:

4×2 Array{Float64,2}:
 5.0  12.0
 6.0  11.5
 7.0   3.0
 8.0   7.0

注:鉴于以下两个假设,此解决方案也适用于任意数量的列:

function f_ag(x::Matrix{T}...)::Matrix{T} where {T<:Number}
    isempty(x) && error("Empty input")
    any([ size(y,2) != 2 for y in x ]) && error("Input matrices must have two columns")
    length(x) == 1 && return copy(x[1]) #simple case shortcut
    nxmax = [ size(y,1) for y in x ]
    nxarrinds = find(nxmax .> 0)
    nxrowinds = ones(Int, length(nxarrinds))
    z = Tuple{T,T}[]
    while !isempty(nxarrinds)
        xmin = minimum(T[ x[nxarrinds[j]][nxrowinds[j], 1] for j = 1:length(nxarrinds) ])
        minarrinds = Int[ j for j = 1:length(nxarrinds) if x[nxarrinds[j]][nxrowinds[j], 1] == xmin ]
        rowsum = sum(T[ x[nxarrinds[k]][nxrowinds[k], 2] for k in minarrinds ])
        push!(z, (xmin, rowsum))
        for k in minarrinds
            nxrowinds[k] += 1
        end
        for j = length(nxarrinds):-1:1
            if nxrowinds[j] > nxmax[nxarrinds[j]]
                deleteat!(nxrowinds, j)
                deleteat!(nxarrinds, j)
            end
        end
    end
    return [ z[n][j] for n = 1:length(z), j = 1:2 ]
end
  • 对每个输入数组的第一列进行排序
  • 每个输入数组的第一列是唯一的
  • 然后,对于大多数输入组合(即输入数组的数量、数组的大小),通过利用假设,以下算法应显著优于其他答案:

    function f_ag(x::Matrix{T}...)::Matrix{T} where {T<:Number}
        isempty(x) && error("Empty input")
        any([ size(y,2) != 2 for y in x ]) && error("Input matrices must have two columns")
        length(x) == 1 && return copy(x[1]) #simple case shortcut
        nxmax = [ size(y,1) for y in x ]
        nxarrinds = find(nxmax .> 0)
        nxrowinds = ones(Int, length(nxarrinds))
        z = Tuple{T,T}[]
        while !isempty(nxarrinds)
            xmin = minimum(T[ x[nxarrinds[j]][nxrowinds[j], 1] for j = 1:length(nxarrinds) ])
            minarrinds = Int[ j for j = 1:length(nxarrinds) if x[nxarrinds[j]][nxrowinds[j], 1] == xmin ]
            rowsum = sum(T[ x[nxarrinds[k]][nxrowinds[k], 2] for k in minarrinds ])
            push!(z, (xmin, rowsum))
            for k in minarrinds
                nxrowinds[k] += 1
            end
            for j = length(nxarrinds):-1:1
                if nxrowinds[j] > nxmax[nxarrinds[j]]
                    deleteat!(nxrowinds, j)
                    deleteat!(nxarrinds, j)
                end
            end
        end
        return [ z[n][j] for n = 1:length(z), j = 1:2 ]
    end
    
    为此:

    rowsum = input_func(T[ x[nxarrinds[k]][nxrowinds[k], 2:end] for k in minarrinds ])
    
    现在你可以输入任何你喜欢的函数,并且在你的输入矩阵中有任意数量的附加列


    这里可能还可以添加一些额外的优化,例如预分配
    z
    ,只有两个输入矩阵时的专用例程,等等,但我不打算为它们操心。

    太棒了!很好的解决方案!正在创建聚合函数。将对所有3个数组中的第一列进行排序。这是事故吗?如果没有,那么有些算法比目前提供的两种算法都要快得多。是的,第一列总是被排序的!:-)真的吗?是的,一个
    while
    循环,它同时向下推进所有输入数组的第一列。但条件逻辑会有点混乱。我今天没时间,但我明天会回来试试。好吧,我很好奇:-)做完了。我假设了排序顺序和唯一性,因为这使它不那么复杂。只是一点注释:排序的是每个数组的第一列,而不是第一行。无论如何,我可以转置每个数组。否则,谢谢你的辛勤工作@酷啊!代码本身是正确的,只是我的文本错了。我不打电话的时候会修好的。如果我的回答是有帮助的,那么给这个回答投上一票可能是个好主意(其他回答也是如此)。干杯。已经修复了文本OK!谢谢我刚刚检查了代码,事实上,这只是一个文本问题。。。对不起,麻烦了。。。。谢谢你的精彩工作!!我觉得有趣的是,你提到我们可以根据自己喜欢的功能调整线条。我想实现它是为了计算值的平均值,而不是它们的总和;-)
    rowsum = input_func(T[ x[nxarrinds[k]][nxrowinds[k], 2:end] for k in minarrinds ])