Ale*_*arp 3 python arrays numpy vectorization
我有一个整数数组:
[int1, int2, ..., intn]
Run Code Online (Sandbox Code Playgroud)
我想计算这些整数的二进制表示中有多少非零位。
例如:
bin(123) -> 0b1111011, there are 6 non-zero bits
Run Code Online (Sandbox Code Playgroud)
当然,我可以遍历整数、用途bin()和count('1')函数的列表,但我正在寻找矢量化的方法来做到这一点。
由于 numpy 与 python 不同,整数大小有限,因此您可以将\xc3\x93scar L\xc3\xb3pez提出的位旋转解决方案改编为快速计算正整数中非零位的方法(最初来自此处),以便可移植,快速解决方案:
\ndef bit_count(arr):\n # Make the values type-agnostic (as long as it\'s integers)\n t = arr.dtype.type\n mask = t(-1)\n s55 = t(0x5555555555555555 & mask) # Add more digits for 128bit support\n s33 = t(0x3333333333333333 & mask)\n s0F = t(0x0F0F0F0F0F0F0F0F & mask)\n s01 = t(0x0101010101010101 & mask)\n\n arr = arr - ((arr >> 1) & s55)\n arr = (arr & s33) + ((arr >> 2) & s33)\n arr = (arr + (arr >> 4)) & s0F\n return (arr * s01) >> (8 * (arr.itemsize - 1))\nRun Code Online (Sandbox Code Playgroud)\n该函数的第一部分将数量 0x5555...、0x3333...等截断为arr实际组成的整数类型。其余部分仅执行一组位调整操作。
对于 100000 个元素的数组,此函数比 Ehsan 的方法快约 4.5 倍,比 Valdi Bo 的方法快约 60 倍:
\na = np.random.randint(0, 0xFFFFFFFF, size=100000, dtype=np.uint32)\n%timeit bit_count(a).sum()\n# 846 \xc2\xb5s \xc2\xb1 16.5 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 1000 loops each)\n%timeit m1(a)\n# 3.81 ms \xc2\xb1 24 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 100 loops each)\n%timeit m2(a)\n# 49.8 ms \xc2\xb1 97.5 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 10 loops each)\nRun Code Online (Sandbox Code Playgroud)\nm1并按m2原样取自@Ehsan\'s 答案。
假设您的数组是a,您可以简单地执行以下操作:
np.unpackbits(a.view('uint8')).sum()
Run Code Online (Sandbox Code Playgroud)
例子:
a = np.array([123, 44], dtype=np.uint8)
#bin(a) is [0b1111011, 0b101100]
np.unpackbits(a.view('uint8')).sum()
#9
Run Code Online (Sandbox Code Playgroud)
比较使用benchit:
#@Ehsan's solution
def m1(a):
return np.unpackbits(a.view('uint8')).sum()
#@Valdi_Bo's solution
def m2(a):
return sum([ bin(n).count('1') for n in a ])
in_ = [np.random.randint(100000,size=(n)) for n in [10,100,1000,10000,100000]]
Run Code Online (Sandbox Code Playgroud)
m1明显更快。
| 归档时间: |
|
| 查看次数: |
170 次 |
| 最近记录: |