Numpy整型位长度

slsn1g29  于 2022-11-10  发布在  其他
关注(0)|答案(3)|浏览(155)

我想要找出用二进制表示无符号umpy整数(或整数数组中的每个元素)所需的位数,就像pythonint.bit_length()所做的那样,但似乎numpy没有等价的函数。
例如:

>>> int(0b1000).bit_length()
4
>>> np.uint8(0b1000).bit_length()
AttributeError: 'numpy.uint8' object has no attribute 'bit_length'

有谁能帮我找出正确的功能吗?我目前的方法是将每个数组元素转换为一个pythonint,以求出位长度,为了速度和清晰度,这似乎是一个糟糕的选择:

np.vectorize(lambda np_int: int(np_int).bit_length())
n8ghc7c1

n8ghc7c11#

您可以取数组的log2的上限。

import numpy as np

x = np.random.randint(0, 100, size=30)
x

# returns:

array([92,  7, 53, 24, 85, 53, 78, 52, 99, 91, 79, 40, 82, 34, 18, 26, 20,
        7, 47, 38, 78, 50, 15, 12, 54,  3, 91, 82, 22, 90])

np.ceil(np.log2(x)).astype(int)

# returns:

array([7, 3, 6, 5, 7, 6, 7, 6, 7, 7, 7, 6, 7, 6, 5, 5, 5, 3, 6, 6, 7, 6,
       4, 4, 6, 2, 7, 7, 5, 7])
nkkqxpd9

nkkqxpd92#

试试这个:

np.uint8(0b1000).nbytes*8

其中,末尾的*8只是每字节的位数

vngu2lb8

vngu2lb83#

经典的位翻转黑客算法应该很容易适应NumPy:
Https://graphics.stanford.edu/~seander/bithacks.html#IntegerLog
下面是32位无符号整数的变体:

def bit_length(v):
  r =     (v > 0xFFFF) << 4; v >>= r
  shift = (v > 0xFF  ) << 3; v >>= shift; r |= shift
  shift = (v > 0xF   ) << 2; v >>= shift; r |= shift
  shift = (v > 0x3   ) << 1; v >>= shift; r |= shift
  return r | (v >> 1)

在给定向量化的情况下,对于非常大的列表和数字(默认情况下,双精度数的尾数大小为2^53),使用浮点log2方法可能会获得更好的性能。这并不是很慢。Numpy需要提供CTZ或CLZ函数,否则这里只会发生计数器前导零或反尾随零。顺便说一句,浮点log2所做的并不比这些相同的CPU类型操作多得多。因此,它可能并不像看起来那样效率低下。

相关问题