通过bytearray从ndarray中选择行

时间:2018-03-28 22:54:17

标签: numpy redis-py

我有一个从redis中提取的bytearray。

r.set('a', '')
r.setbit('a', 0, 1)
r.setbit('a', 1, 1)
r.setbit('a', 12, 1)

a_raw = db.get('a')
# b'\xc0\x08'
a_bin = bin(int.from_bytes(a, byteorder="big")) 
# 0b1100000000001000

我想使用该bytearray从ndarray中选择行。

arr = np.arange(12)
arr[a_raw]
# array([0, 1, 12])

编辑两种解决方案都有效,但我发现@ paul-panzer更快

import timeit

setup = '''import numpy as np; a = b'\\xc0\\x08'; '''

t1 = timeit.timeit('idx = np.unpackbits(np.frombuffer(a, np.uint8)); np.where(idx)', 
              setup = setup, number=10000)

t2 = timeit.timeit('idx = np.array(list(bin(int.from_bytes(a, byteorder="big"))[2:])) == "1"; np.where(idx)',
              setup = setup, number=10000)

print(t1, t2)
#0.019560601096600294 0.054518797900527716

编辑2 实际上,from_bytes方法并没有返回我正在寻找的内容:

redis_db.delete('timeit_test')
redis_db.setbit('timeit_test', 12666, 1)
redis_db.setbit('timeit_test', 14379, 1)
by = redis_db.get('timeit_test')

idx = np.unpackbits(np.frombuffer(by, np.uint8))
indices = np.where(idx)

idx = np.array(list(bin(int.from_bytes(by, byteorder="big"))[2:])) == "1"
indices_2 = np.where(idx)

print(indices, indices_2)
#(array([12666, 14379]),) (array([   1, 1714]),)

2 个答案:

答案 0 :(得分:1)

以下是使用>>> a = b'\xc0\x08' >>> b = np.arange(32).reshape(16, 2) >>> c = np.arange(40).reshape(20, 2) >>> >>> idx = np.unpackbits(np.frombuffer(a, np.uint8)) >>> # if the sizes match boolen indexing can be used >>> b[idx.view(bool)] array([[ 0, 1], [ 2, 3], [24, 25]]) >>> # non matching sizes can be worked around using where >>> c[np.where(idx)] array([[ 0, 1], [ 2, 3], [24, 25]]) >>> 的方法:

onScrollDown()

答案 1 :(得分:0)

以这种方式:

In [57]: b = 0b1100000000001000

In [58]: mask = np.array(list(bin(b)[2:])) == '1'

In [59]: arr = np.arange(13)

In [60]: arr[mask[:len(arr)]]
Out[60]: array([ 0,  1, 12])

此外,它只是一个简单的检查,以证明__getitem__的{​​{1}}实现不支持直接在ndarray对象上建立索引:

bytes

因此,除非您继承In [61]: by = b'\xc0\x08' In [62]: arr[by] --------------------------------------------------------------------------- IndexError Traceback (most recent call last) <ipython-input-111-6cd68003b176> in <module>() ----> 1 arr[by] IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices 或创建具有自定义ndarray行为的扩展模块,否则无法直接从__getitem__执行此操作,您必须将字节转换为基于按位条件的布尔掩码。

以下是比较直接使用原始bytes对象的几种不同方法的时间的示例:

bytes