【问题标题】:In a one dimensional numpy array of 1's and 0's, how can I convert the next n elements following a 1 to 0's?在 1 和 0 的一维 numpy 数组中,如何将 1 之后的下 n 个元素转换为 0?
【发布时间】:2021-10-12 12:34:59
【问题描述】:

对于 1 和 0 的一维 numpy 数组,我如何有效地“屏蔽”数组,以便在出现 1 后,将数组的下 n 个元素转换为零。在 n 个元素通过后,模式会重复,这样会保留下一次出现的第一个 1,然后再保留 n 个零。

保留第一个符合条件的 1 很重要,因此可以使用简单的掩码,例如: [true, false, false, true ...] 行不通。 此外,数据集非常庞大,因此效率很重要。

我已经编写了粗略的 python 代码来给我想要的结果,但它对于我需要的东西来说太慢了。 这是一个例子:

data = [0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1]
n = 3

newData = []
tail = 0
for x in data:
    if x == 1 and tail <= 0:
        newData.append(1)
        tail = n
    else:
        newData.append(0)
        tail -= 1
print(newData)

新数据:[0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1]

这个问题有可能有一个矢量化的 numpy 解决方案吗? 我正在处理数以万计的数组,每个数组中有超过一百万个元素。到目前为止,使用 numpy 函数是管理此问题的唯一方法。

【问题讨论】:

    标签: python numpy vectorization numpy-ndarray masked-array


    【解决方案1】:

    你可以这样做:-

    N = 3
    data = [0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1]
    newData = data.copy()
    i = 0
    M = [0 for _ in range(N)]
    while i < len(newData) - N:
        if newData[i] == 1:
            newData[i + 1:i + 1 + N] = M
            i += N
        i += 1
    
    print(newData)
    

    【讨论】:

    • 这比我的代码效率更高,但我希望有一个矢量化的 numpy 解决方案可以更快地解决我的问题
    • @ArnoBooysen 它怎么可能成倍地更快?
    • @KellyBundy 正如您在使用矢量化 numpy 函数而不是迭代数组时看到的相对于数组大小的指数时间节省。我假设向量化函数所花费的时间不会像迭代那样随数组大小线性增加?
    • 我的解决方案其实很快。我将代码包装到一个函数中,并使用 time.perf_counter() 记录一百万次迭代的开始和结束,我发现它花费了大约 1.7 秒。您是否需要它每次迭代都快于 1.7E-6?
    • @ArnoBooysen 矢量化函数的时间如何不会线性增加?
    【解决方案2】:

    据我所知,在 numpy 中没有完全可以做到这一点的选项。不过,您仍然可以使用 numpy 来减少获取索引的时间。

    data = [0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1]
    n=3
    def get_new_data(data,n):
      new_data = np.zeros(len(data))
      non_zero = np.argwhere(data).ravel()
      idx = non_zero[0]
      new_data[idx] =1
      idx += n
      for i in non_zero[1:]:
        if i > idx:
          new_data[i] = 1
          idx+=n
      return new_data
    get_new_data(data, n)
    

    这样的函数应该会给你一个更好的运行时间,因为你没有循环整个数组。

    如果这对你来说仍然不是最优的,你可以看看使用numba,它与 numpy 配合得很好,并且相对容易使用。

    【讨论】:

    • 这更简单,而且我看到的数据写入操作非常少。朝同一个方向前进+1
    猜你喜欢
    • 2022-11-13
    • 1970-01-01
    • 2021-05-17
    • 1970-01-01
    • 1970-01-01
    • 2023-01-19
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    相关资源
    最近更新 更多