gpt4 book ai didi

python - 将十进制范围转换为 Numpy 数组,每一位都是一个数组元素

转载 作者:太空宇宙 更新时间:2023-11-03 14:25:08 24 4
gpt4 key购买 nike

我创建了一个小函数,它将一个整数 length 作为输入,并返回所有二进制表示的 numpy array 2**length [0:2**length-1] 范围内的整数。

import numpy as np

def get_bitstrings(length):
# We need to binary-fy 2^length numbers.
iterations = 2**length
# Pre-allocate memory.
the_array = np.zeros((iterations, length))
# Go through all decimals in the range [0:iterations-1]
for num in range(iterations):
# Get binary representation in string format with 'length' zeroes padded
t_string = '{f_num:0{f_width}b}'.format(f_num=num, f_width=length)
# Convert to a Python list
t_list = list(t_string)
# Convert to Numpy array and store.
the_array[num,:] = np.array(t_list)

return the_array

if __name__ == '__main__':
var1 = get_bitstrings(2)
var2 = get_bitstrings(3)
print('var1:\n{}\n'.format(var1))
print('var2:\n{}\n'.format(var2))

产生:

var1:
[[ 0. 0.]
[ 0. 1.]
[ 1. 0.]
[ 1. 1.]]

var2:
[[ 0. 0. 0.]
[ 0. 0. 1.]
[ 0. 1. 0.]
[ 0. 1. 1.]
[ 1. 0. 0.]
[ 1. 0. 1.]
[ 1. 1. 0.]
[ 1. 1. 1.]]

该过程包括将每个整数的二进制表示形式作为字符串(在其前面填充 0,以便长度恒定为 length),将字符串转换为 Python 列表,然后将列表转换为 numpy array

我发现这是满足每个位都是数组中的一个条目这一要求的唯一方法——即位串 1010 是一个 1x4 numpy array 而不仅仅是 1x1 数组中的整数。但我确信有更好的选择,因此才有了这个问题。

正如您所想象的那样,问题在于这是低效的。我想知道我是否可以通过使用 Python/Numpy 技巧来改进这一点。

编辑:我曾经在 MATLAB 中使用以下代码片段执行此操作:

t_length = 5; dc = [0:2^t_length-1]'; bc = rem(floor(dc*pow2(-(t_length-1):0)),2);

但说到 Python/Numpy,我完全是个菜鸟!也许它会激励某人。 :-)

最佳答案

您可以使用 NumPy 的广播和矢量化操作相当有效地完成此操作:

>>> from numpy import arange, newaxis
>>> powers_of_two = 2**arange(4)[::-1]
>>> (arange(2**4)[:, newaxis] & powers_of_two) / powers_of_two
array([[0, 0, 0, 0],
[0, 0, 0, 1],
[0, 0, 1, 0],
[0, 0, 1, 1],
[0, 1, 0, 0],
[0, 1, 0, 1],
[0, 1, 1, 0],
[0, 1, 1, 1],
[1, 0, 0, 0],
[1, 0, 0, 1],
[1, 0, 1, 0],
[1, 0, 1, 1],
[1, 1, 0, 0],
[1, 1, 0, 1],
[1, 1, 1, 0],
[1, 1, 1, 1]])

简要说明:我们取 0 到 15 之间的所有整数 (arange(2**4)),然后将其 reshape 为给定形状的数组 (16, 1 )(即 [:, newaxis] 切片部分)。然后我们从最高到最低采用 bitwise-and 和 2 的幂 (2**arange(4)[::-1])。 reshape 确保按位与运算作为一种“外部”运算执行:我们将原始 arange 的每个元素与 powers_of_two 的每个元素进行按位与运算> 阵列。这是 NumPy 的 broadcastingslicing在上类。由于没有明确的 Python 级 for 循环,这应该比基于 for 循环或列表理解的解决方案快得多。

这里有一个更时尚的,事实证明,速度更快,沿着相同的路线替代:

>>> from numpy import arange, newaxis
>>> arange(2**4)[:,newaxis] >> arange(4)[::-1] & 1
array([[0, 0, 0, 0],
[0, 0, 0, 1],
[0, 0, 1, 0],
[0, 0, 1, 1],
[0, 1, 0, 0],
[0, 1, 0, 1],
[0, 1, 1, 0],
[0, 1, 1, 1],
[1, 0, 0, 0],
[1, 0, 0, 1],
[1, 0, 1, 0],
[1, 0, 1, 1],
[1, 1, 0, 0],
[1, 1, 0, 1],
[1, 1, 1, 0],
[1, 1, 1, 1]])

与往常一样,如果效率是一个问题,那么您应该充分利用 Python 以 timeit 形式提供的工具。和 profile模块。我的机器上 length=16 的计时似乎表明第二个变体比第一个变体快得多:

taniyama:~ mdickinson$ python -m timeit -s "from numpy import arange, newaxis" "arange(1<<16)[:, newaxis] >> arange(16)[::-1] & 1"
100 loops, best of 3: 4.08 msec per loop
taniyama:~ mdickinson$ python -m timeit -s "from numpy import arange, newaxis" "(arange(1<<16)[:, newaxis] & 2**arange(16)[::-1]) / 2**arange(16)[::-1]"
10 loops, best of 3: 21.6 msec per loop

关于python - 将十进制范围转换为 Numpy 数组,每一位都是一个数组元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21918267/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com