【问题标题】:Extracting contiguous rows in an array提取数组中的连续行
【发布时间】:2019-02-20 06:52:08
【问题描述】:

以下python代码

df['tag'] = df['Value'] < 1.0 
df['mask'] = np.where(df['tag'],1,0)
first = df.index[df['tag'] & ~ df['tag'].shift(1).fillna(False)]
last = df.index[df['tag'] & ~ df['tag'].shift(-1).fillna(False)]
pr = [(i, j) for i, j in zip(first, last) if j > i + 1]

返回一个数组 pr,其中包含小于值 1 的连续行的元组。我尝试将这个 Julia 翻译成部分范围,如下所示:

df[:tag]=df[:Value] .< 1.0
df[:mask]=zeros(length(df[:tag]))

df[:mask][df[:tag].==true] .= 1
df[:mask][df[:tag].==false] .= 0

如何在 Julia 中复制 first、last、pr 的值?

【问题讨论】:

  • 我实施了没有j &gt; i + 1 条件的解决方案,因为我不清楚为什么需要它。
  • 没有这个条件,一些块的长度为零。我想要大小大于零的块。
  • j &gt; i + 1 意味着j 必须至少为i+2,这意味着块长度至少为3。假设您有一个输入向量[0.5, 0.5]。在此条件下,pr[]。这是你想要的吗?我以为你想在这种情况下获得 [(0,1)](在 Python 中),或者等效地在 Julia 中获得 [(1,2)]

标签: python dataframe julia


【解决方案1】:

我会给你两种可能的方法来解决这个问题。第一个更快,但需要更多代码。第二个更慢,但更短。

function getblocks1(vs)
    blocks = Tuple{Int, Int}[]
    inblock, start = false, 0, 0
    for (i, v) in enumerate(vs)
        if inblock
            if v >= 1.0
                push!(blocks, (start, i-1))
                inblock = false
            end
        else
            if v < 1.0
                start = i
                inblock = true
            end
        end
    end
    inblock && push!(blocks, (start, length(vs)))
    blocks
end

function getblocks2(vs)
    t = [false; vs .< 1.0; false]
    dt = diff(t)
    f = findall(==(1), dt)
    l = findall(==(-1), dt) .- 1
    collect(zip(f, l))
end

要知道的关键是,在 Julia 中 getblocks1 会很快,因为 Julia 中的循环很快,并且该函数试图最小化分配的数量并一次完成所有事情。第二种实现更类似于 Python,但分配更多,并多次遍历整个向量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-01
    • 1970-01-01
    相关资源
    最近更新 更多