首页 > 解决方案 > 如何使用反向二进制表示重新索引 numpy 数组?

问题描述

如何改进以下代码?

1)-> 传递一个长度为一维的数组2**n

2)->为数组的每个索引获取二进制表示

3)-> 反转二进制表示并将其用作对应值的新整数索引

例子:

[56,209,81,42]

[00,01,10,11](索引的二进制表示)

-> 反向:[00,10,01,11]

-> 变成:[56,81,209,42]

代码:

def order_in_reversed_bits(data: np.ndarray) -> np.ndarray:
    tobinary = lambda t: np.binary_repr(t, width=len(np.binary_repr(data.shape[0]-1)))[::-1]
    func = np.vectorize(tobinary)
    a = func(np.arange(0,data.shape[0]))
    t = np.zeros(data.shape,dtype='float64')

    for i,k in enumerate(a):
        t[int(k,2)] = data[i]

    return t

Numpy 或 Python 的哪些内置功能很方便?

标签: pythonpandasnumpy

解决方案


例如,您可以使用sorted自定义键(感谢@hpaulj 改进了键功能bin()):

lst = [56,209,81,42]

def order_in_reversed_bits_python(lst):
    return [v for _, v in sorted(enumerate(lst), key=lambda k: bin(k[0])[:1:-1])]

print(order_in_reversed_bits_python(lst))

印刷:

[56, 81, 209, 42]

时间:

import timeit
from random import randint

def order_in_reversed_bits_python(lst):
    return [v for _, v in sorted(enumerate(lst), key=lambda k: bin(k[0])[:1:-1])]

def order_in_reversed_bits(data):
    tobinary = lambda t: np.binary_repr(t, width=len(np.binary_repr(data.shape[0]-1)))[::-1]
    func = np.vectorize(tobinary)
    a = func(np.arange(0,data.shape[0]))
    t = np.zeros(data.shape,dtype='float64')

    for i,k in enumerate(a):
        t[int(k,2)] = data[i]

    return t

# create some large array:
lst = np.array([randint(1, 100) for _ in range(2**16)])

t1 = timeit.timeit(lambda: order_in_reversed_bits_python(lst), number=1)
t2 = timeit.timeit(lambda: order_in_reversed_bits(lst), number=1)

print(t1)
print(t2)

印刷:

0.05821935099811526
0.22723246600071434

这是改进〜3.9x


推荐阅读