我正在尝试编写一个函数,它可以将一些数据归零,直到其长度等于2的最接近的更高功率。我也希望能够做一定数量的迭代。现在这是我的职责:
def pad_to_next_2n(array, iterations = 1):
n = 1
while n <= iterations:
l = len(array)
padding = l +1 #incase array is already length equal to 2^n
while np.log2(padding) % 1 != 0:
padding += 1
if l % 2 == 0:
total_padding = padding - l
array = np.pad(array, (total_padding/2,), 'constant')
n += 1
else:
total_padding = padding - l
left_padding = (total_padding - 1)/2
right_padding = total_padding - left_padding
print total_padding
print left_padding
print right_padding
array = np.pad(array, (left_padding, right_padding), 'constant')
n += 1
return array
这确实有效,但对于高于5的迭代来说,速度确实很慢。我想知道是否有人可以帮助提高速度,或看到更好的方法来做这件事。我认为最大的问题来自
while np.log2(padding) % 1 != 0:
padding += 1
但我不知道怎样才能更有效率。
最佳答案
你不需要做很多你正在做的事情-你只需要找出下一个2的幂,你需要扩展你的数组的长度,然后你可以调用数组上的pad
,一次将它填充到你需要的长度。
这使用了另一个关于Python中获得2的下一个幂的最快方法的问题中的shift_bit_length
。
import numpy as np
def shift_bit_length(x):
return 1<<(x-1).bit_length()
def padpad(data, iterations = 1):
narray = data
for i in xrange(iterations):
length = len(narray)
diff = shift_bit_length(length + 1) - length
if length % 2 == 0:
pad_width = diff / 2
else:
# need an uneven padding for odd-number lengths
left_pad = diff / 2
right_pad = diff - left_pad
pad_width = (left_pad, right_pad)
narray = np.pad(narray, pad_width, 'constant')
return narray
一些测试:
>> arr = np.array([1, 2])
>> padpad(arr, 1)
Out[2]: array([0, 1, 2, 0])
>> len(padpad(arr, 1)
Out[3]: 4
>> padpad(arr, 5)
Out[4]: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
>> len(padpad(arr, 5))
Out[5]: 32
>> padpad(arr, 8)
Out[6]: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0])