Python/Numpy:将bool列表转换为unsigned int

Ste*_*joa 12 python numpy list scipy

  1. 什么是最快(或最"Pythonic")的转换方式

    x = [False, False, True, True]
    
    Run Code Online (Sandbox Code Playgroud)

    12?(如果有这样的方式.)

  2. 如果x是一个numpy.arraybools怎么办?对此有特殊的命令吗?

我有一个大的m-by-n布尔数组,其中每个n元素行代表一个高维特征向量的低维散列.(在上面的例子中,n = 4.)我想知道答案,以便尽可能地压缩我的数据.谢谢.


编辑:谢谢你的回复!使用以下测试代码,

t = 0
for iter in range(500):
    B = scipy.signbit(scipy.randn(1000,20))
    for b in B:
        t0 = time.clock()
        # test code here
        t1 = time.clock()
        t += (t1-t0)
print t
Run Code Online (Sandbox Code Playgroud)

...这是我的Thinkpad笔记本电脑上的运行时间:

当然,我欢迎任何可能确认或反驳我的数据的独立测试!


编辑:在我的答案下面,int(j)改为简单j仍然有效,但运行速度慢六倍!然后,如果使用bool进行铸造,其他答案可能会更快int.但我懒得再测试一切.


编辑:liori在这里公布了独立测试的结果.

Jus*_*eel 10

从各种其他答案中获取各种想法,这是另一种方法:

sum(1<<i for i, b in enumerate(x) if b)
Run Code Online (Sandbox Code Playgroud)

在我的测试中它非常快 - 即使它像疯了一样溢出,也可以使用numpy方法获得大量的数据.我使用liori的测试模块进行测试.史蒂夫的方法,我建议的改变,只是快几点.但是,如果需要一次完成很多这类转换(并且没有太多位),我敢打赌numpy会更快.


Sve*_*ach 6

大多数Pythonic可能是这样的:

sum(2**i*b for i, b in enumerate(x))
Run Code Online (Sandbox Code Playgroud)

很难说它是否也是最快的.

在numpy我会用

numpy.sum(2**numpy.arange(len(x))*x)
Run Code Online (Sandbox Code Playgroud)

但是对于小型阵列来说这不会更快x,并且它不适用于大型阵列,x因为使用机器大小整数而不是Pythons任意精度整数.