【问题标题】:Partition Equivalent in JuliaJulia中的等价分区
【发布时间】:2014-11-16 03:13:18
【问题描述】:

在 Julia 中,Mathematica 的 Partition 函数的等价物是什么?

Mathematica 的Partition[list,n] 接受一个数组并将其划分为长度为n 的非重叠子列表。另一方面,Julia 中的分区函数接受一个数组并将该数组的所有分区放入n 子集。

【问题讨论】:

    标签: arrays wolfram-mathematica julia


    【解决方案1】:

    也许我遗漏了一些东西,但这不是你想要的吗?

    x = [:a,:b,:c,:d,:e,:f]
    n = 2
    reshape(x, (n, div(length(x), n)))
    

    【讨论】:

    • 这正是我想要的。谢谢。
    • 如果长度不能干净地划分为长度为n 的子数组,则此答案将不起作用,例如x = [:a,:b,:c,:d,:e,:f,:g]n=2 将失败。您还会得到一个矩阵,而不是数组数组。
    • @IainDunning,我同意,它没有模仿 Mathematica 中的 Partition 函数。然而,鉴于@Ali 的使用,它可能是需要的。
    【解决方案2】:

    所以在 Mathematica 中:

    In[1]:= Partition[{a, b, c, d, e, f}, 2]
    Out[1]= {{a,b},{c,d},{e,f}}
    

    但在 Julia 中,partitions 函数具有非常不同的含义:

    x = [:a,:b,:c,:d,:e,:f]
    first(partitions(x,2))
    #2-element Array{Array{Symbol,1},1}:
    # [:a,:b,:c,:d,:e]
    # [:f]
    

    它是集合的所有 2 分区的集合。为了得到你想要的,你可以这样做

    yourpart(x,n) = {{x[i:min(i+n-1,length(x))]} for i in 1:n:length(x)}
    

    julia> yourpart([:a,:b,:c,:d,:e,:f], 2)
    3-element Array{Any,1}:
     {:a,:b}
     {:c,:d}
     {:e,:f}
    
    julia> yourpart(x,4)
    2-element Array{Any,1}:
     {[:a,:b,:c,:d]}
     {[:e,:f]}
    

    【讨论】:

    • 为了避免被弃用的警告(从 Julia 0.4.5 开始),你可以写成yourpart(x, n) = [x[i:min(i+n-1,length(x))] for i in 1:n:length(x)]
    【解决方案3】:

    这也有效

    partitioneddata=[data[n:n+pfac] for n=1:offset:length(data)-pfac];
    

    地点:

    • pfac 是您希望新数组每个“多长时间”

    • 偏移量是您希望每个新数组偏移多少个位置

    这可以在下面的例子中看到:

    我们希望将 [1,2,3,4,5,6,7,8,9,10] 划分为长度=2 的新数组,每个数组移动偏移量=1。

    pfac=2
    offset=1
    partitioneddata=[data[n:n+pfac] for n=1:offset:length(data)-pfac]
    8-element Array{Array{Int64,1},1}: 
    [1,2,3]
    [2,3,4]
    [3,4,5]
    [4,5,6]
    [5,6,7]
    [6,7,8]
    [7,8,9]
    [8,9,10]
    

    我知道我参加聚会有点晚了,但希望这会有所帮助!

    【讨论】:

      【解决方案4】:

      这种方法应该 (i) 内存效率更高并且 (ii) 允许例如53 个数据点,每组 10 个。

      """
      returns ranges (i.e. indices to split the data).
      """
      function partition_array_indices(nb_data::Int, nb_data_per_chunk::Int)
          nb_chunks = ceil(Int, nb_data / nb_data_per_chunk)
          ids = UnitRange{Int}[]
          for which_chunk = 1:nb_chunks
              id_start::Int = 1 + nb_data_per_chunk * (which_chunk - 1)
              id_end::Int = id_start - 1 + nb_data_per_chunk
              if id_end > nb_data
                  id_end = nb_data
              end
              push!(ids, id_start:id_end)
          end
          return ids
      end
      

      使用示例:

      x = collect(linspace(0, 1, 53))
      nb_data_per_chunk = 10
      ids = partition_array_indices(length(x), nb_data_per_chunk)
      
      # get first chunk, 10 elements
      x[ids[1]]
      # get last chunk, just 3 elements
      x[ids[end]]
      

      【讨论】:

      • 我认为现在你可以简单地调用 ``` ids = Iterators.partition(x, nb_data_per_chunk) ``` 标准库函数将完全满足你的需要。
      【解决方案5】:

      如果其他人也遇到了将数组分解为 n 部分的相关任务的需要:

      function nfolds(x::AbstractArray, n::Int)
          s = length(x) / n
          [x[round(Int64, (i-1)*s)+1:min(length(x),round(Int64, i*s))] for i=1:n]
      end
      
      julia> map(length, npartition(1:21, 6))
      6-element Array{Int64,1}:
       4
       3
       3
       4
       4
       3 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-26
        相关资源
        最近更新 更多