我制作了一个代码,在一个文件中读取256x256矩阵,将它们转换为二进制数,读取它们的一部分,制作另外两个256x256矩阵的文件。我认为它正在做我想要的,但处理一个文件需要几分钟。有关更高效代码的任何建议吗?
这是我的代码。
#Read in file
f = open(path, 'r')
l = [list(map(int, line.split(' '))) for line in f]
a = np.array(l)
A = a.ravel()
#Convert to binary
bnry = ()
for data in A:
bnry = np.append(bnry, bin(data))
#Extract two data from each number and store them to 'THL' and 'THH'
thl = ()
thh = ()
THL = ()
THH = ()
for ths in bnry:
thl = int(ths[2:14], 2)
THL = np.append(THL, thl)
thh = int(ths[-12:], 2)
THH = np.append(THH, thh)
#Save 'THL' and 'THH' to text files
np.savetxt('THL.txt', np.reshape(THL, (256,256)), fmt='%.4g', delimiter=' ')
np.savetxt('THH.txt', np.reshape(THH, (256,256)), fmt='%.4g', delimiter=' ')
解 非常感谢Oliver W.,我能够比我的几分钟长的代码更快地获得更快的代码。他们基本上是
thl = np.bitwise_and(a, 2**12 - 1)
thh = np.bitwise_and(a, (2**12-1) << (12+4)) >> (12+4)
我仍然需要学习更多并熟悉它们的工作原理,但它们工作得很好!
答案 0 :(得分:0)
你试图提取一系列整数的前12位以及最后12位。这是2个不同的问题。后者是最简单的。
首先,让我们首先使用numpy
的便捷方法来读取文本文件中的数据,而不是编写我们自己的(更可能不太理想的)函数:
a = np.fromfile(file, dtype=np.uint32, sep=' ') # alternative: np.genfromtxt
接下来,让我们解决一个简单的问题:从a:
中提取最低的12位THH = np.bitwise_and(a, 2**12 - 1)
这是一个矢量化操作,所以它非常高效且速度极快。
获得前12位是另一个问题,因为它取决于数字本身。我的猜测是,这实际上并不是你想要做的,而是有人要求你从一些整数中提取12个“最高”位,当它们被解释为具有固定数量的位时。 “3位最高位”的解释将更清楚:
如果你需要一个数字的3个最高位,比如20,你可以将20解释为像0b10100
一样写,在这种情况下,3个最高位是101
,这是小数但是,如果您将20解释为0b0010100
,那么使用2个前导零,则3个最高位将是001
,即十进制数1.实际上不需要很多操作你考虑(最小的)二进制表示的长度,我想这也是你说“我认为它正在做我想要的”的原因。
因此,更有可能的是,您的数字将以固定长度的二进制格式进行解释。看看你提到的最大值,268374015,这个长度大概是28位数(甚至看起来不太可能,32位更常见)。但是,假设它是28位,而你只想提取前12位,你可以使用与以前相同的技巧:
np.logical_and(a, (2**12 - 1)<<16) >> 16
请注意,>>
和<<
为bitshift operations。
我对你的数据做了几个假设(你只处理整数是明确的,因为你用int()
转换所有内容)当然,你的真实问题
但是,如果确实希望这些数字的前12位,从最高位开始,则以下代码显示:
method_old()
)method_new()
)他们在我的机器上的执行时间。
import numpy as np
a = np.random.random_integers(0, 268374016, (512,512))
def method_new(nbr_select_bits=12):
high_bits = np.empty_like(a)
for bit in range(32, nbr_select_bits -1, -1):
mask = a < 2**bit
shift = bit - nbr_select_bits
bitmask = (2**nbr_select_bits - 1) << shift
high_bits[mask] = np.bitwise_and(a[mask], bitmask) >> shift
low_bits = np.bitwise_and(a, 2**nbr_select_bits - 1)
return high_bits, low_bits
def method_old(nbr_select_bits=12):
thl = np.empty(a.size, dtype=np.uint32)
thh = np.empty(a.size, dtype=np.uint32)
for enu, data in enumerate(a.ravel()):
thl[enu] = int(bin(data)[2:2+nbr_select_bits], 2)
try:
thh[enu] = int(bin(data)[-nbr_select_bits:], 2)
except ValueError: # because 'int("b11", 2)' fails
thh[enu] = int(bin(data)[-(nbr_select_bits+1):], 2)
return thl.reshape(a.shape), thh.reshape(a.shape)
from timeit import timeit
new_t = timeit('method_new()', setup='from __main__ import method_new', number=1)
old_t = timeit('method_old()', setup='from __main__ import method_old', number=1)
print('Old method ran in {:.2f}ms,\nNew method ran in {:.2f}ms.\n'
'Speedup: {:.1f}x'.format(old_t*1000, new_t*1000, old_t/new_t))))
# Output:
# Old method ran in 473.97ms,
# New method ran in 60.18ms.
# Speedup: 7.9x