[英]Most efficient way to forward fill a bit array
想象一下,您有一個隨機填充的位數組(任何數據類型都可以。例如 list、np.array、bitarray、bitmap 等布爾值)。 在 Python 中“前向填充”(從左到右,或第 0 個索引到第 n 個索引)該數組的最快方法是什么,以便在每個已設置為 1 的位之后將 n 位設置為 1?
例如,取下面的數組:
[01000100000]
給定 n=2 前向填充數組將是:
[01110111000]
編輯
假設輸入是一個包含 10,000 個元素的位數組,其中隨機 20% 為真,n=25。 這可以表示為一個 python 列表,其中包含 10,000 個 boolean 元素,其中 20% 是True
。 這也可以表示為具有 0 到 10,000 之間的 2,000 個int
元素的set
。
編輯 2
首先,以下是使用上述參數的一些示例:
new = set()
new.update(*[range(i, i+25) for i in existing])
# 2.34 ms ± 56.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
new = BitMap() # This is a pyroaring BitMap
for e in existing:
new.add_range(e, e+25)
# 461 µs ± 6.02 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
我在下面討論了幾種數據類型。 沒有給定時間,您可能希望將語句設置ans
或重構函數的時間設置為對您有意義的粒度。
# -*- coding: utf-8 -*-
"""
Created on Sun Dec 19 09:08:56 2021
for: https://stackoverflow.com/questions/70397220/most-efficient-way-to-forward-fill-a-bit-array
@author: paddy
"""
from random import sample
n = 2 # bits to the right of set bits to also set
elements = 17
true_percent = 20.0
#%% Using arbitrary precision int
print("\nUsing arbitrary precision int.\n".upper())
from operator import or_
from functools import reduce
# Set some random bits True
bits = sum(1 << r
for r in sample(range(elements), int(true_percent/100 * elements)))
# Set n right-adjacent bits.
ans = reduce(or_, (bits >> x for x in range(n+1)), 0)
# Print
print(f"Random bits = {bits:0{elements}b}")
if 1:
print()
for x in range(n+1):
print(f" {bits >> x:0{elements}b}")
print()
print(f"Answer = {ans:0{elements}b}\n")
#%% Using list.
print("\nUsing list.\n".upper())
from operator import or_
from functools import reduce
bits = [0] * elements
# Set some random bits to 1
for r in sample(range(elements), int(true_percent/100 * elements)):
bits[r] = 1
# Set n right-adjacent bits.
# [0]*x is padding bits on the left.
# zip(*(list1, list2,..)) returns the n'th elements on list1, list2,...
# int(any(...)) or's them.
ans = [int(any(shifts))
for shifts in zip(*([0]*x + bits for x in range(n+1)))]
# Print
print(f"Random bits = {bits}")
if 1:
print()
for x in range(n+1):
print(f" {[0]*x + bits}")
print()
print(f"Answer = {ans}\n")
#%% Using numpy.
# Adapt the list solution to use numpy operators on numpy arrays
#%% Using other ordered collections such as str.
# Convert to and from int solution.
樣品 Output:
USING ARBITRARY PRECISION INT.
Random bits = 01000000010000010
01000000010000010
00100000001000001
00010000000100000
Answer = 01110000011100011
USING LIST.
Random bits = [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0]
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0]
Answer = [0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.