使用NumPy中的binary_repr对数字数组或替代方法进行编码 - Python

2024-04-16 21:19:21 发布

您现在位置:Python中文网/ 问答频道 /正文

使用下面的代码,我试图将一个数字列表转换为二进制数,但出现错误

import numpy as np

lis=np.array([1,2,3,4,5,6,7,8,9])
a=np.binary_repr(lis,width=32)

运行程序后的错误是

Traceback (most recent call last):

File "", line 4, in a=np.binary_repr(lis,width=32)

File "C:\Users.......", in binary_repr if num == 0:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

有办法解决这个问题吗?


Tags: 代码inimportnumpy列表错误np二进制
3条回答

您可以使用^{}来解决此问题。在

>>> lis=np.array([1,2,3,4,5,6,7,8,9])
>>> a=np.binary_repr(lis,width=32)
>>> binary_repr_vec = np.vectorize(np.binary_repr)
>>> binary_repr_vec(lis, width=32)
array(['00000000000000000000000000000001',
       '00000000000000000000000000000010',
       '00000000000000000000000000000011',
       '00000000000000000000000000000100',
       '00000000000000000000000000000101',
       '00000000000000000000000000000110',
       '00000000000000000000000000000111',
       '00000000000000000000000000001000',
       '00000000000000000000000000001001'], dtype='<U32')

正如documentation on ^{}所说:

num : int

    Only an integer decimal number can be used.

但是,您可以将此操作矢量化,例如:

np.vectorize(np.binary_repr)(lis, 32)

这就给了我们:

^{pr2}$

或者,如果经常需要,可以将矢量化变量存储在变量中:

binary_repr_vector = np.vectorize(np.binary_repr)
binary_repr_vector(lis, 32)

当然,结果是一样的:

>>> binary_repr_vector = np.vectorize(np.binary_repr)
>>> binary_repr_vector(lis, 32)
array(['00000000000000000000000000000001',
       '00000000000000000000000000000010',
       '00000000000000000000000000000011',
       '00000000000000000000000000000100',
       '00000000000000000000000000000101',
       '00000000000000000000000000000110',
       '00000000000000000000000000000111',
       '00000000000000000000000000001000',
       '00000000000000000000000000001001'], dtype='<U32')

方法1

这是一个向量化的数字数组,利用^{}-

def binary_repr_ar(A, W):
    p = (((A[:,None] & (1 << np.arange(W-1,-1,-1)))!=0)).view('u1')
    return p.astype('S1').view('S'+str(W)).ravel()

样本运行-

^{pr2}$

方法2

另一个矢量化的数组赋值-

def binary_repr_ar_v2(A, W):
    mask = (((A[:,None] & (1 << np.arange(W-1,-1,-1)))!=0))
    out = np.full((len(A),W),48, dtype=np.uint8)
    out[mask] = 49
    return out.view('S'+str(W)).ravel()

或者,直接使用掩码来获取字符串数组-

def binary_repr_ar_v3(A, W):
    mask = (((A[:,None] & (1 << np.arange(W-1,-1,-1)))!=0))
    return (mask+np.array([48],dtype=np.uint8)).view('S'+str(W)).ravel()

请注意,最终输出将是中间输出之一的视图。因此,如果需要它有自己的内存空间,只需附加.copy()。在


大型输入数组上的计时-

In [49]: np.random.seed(0)
    ...: A = np.random.randint(1,1000,(100000))
    ...: W = 32

In [50]: %timeit binary_repr_ar(A, W)
    ...: %timeit binary_repr_ar_v2(A, W)
    ...: %timeit binary_repr_ar_v3(A, W)
1 loop, best of 3: 854 ms per loop
100 loops, best of 3: 14.5 ms per loop
100 loops, best of 3: 7.33 ms per loop

从其他发布的解决方案-

In [22]: %timeit [np.binary_repr(i, width=32) for i in A]
10 loops, best of 3: 97.2 ms per loop

In [23]: %timeit np.frompyfunc(np.binary_repr,2,1)(A,32).astype('U32')
10 loops, best of 3: 80 ms per loop

In [24]: %timeit np.vectorize(np.binary_repr)(A, 32)
10 loops, best of 3: 69.8 ms per loop

^{}-

In [5]: %timeit bin_rep(A,32)
548 µs ± 1.02 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [6]: %timeit bin_rep(A,31)
2.2 ms ± 5.55 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

相关问题 更多 >