有没有一种更快的方法来读取、诉诸和转换二进制文件?

问题描述 投票:1回答:1

我有一个二进制文件,其中包含一定数量的样本,每个样本包含四个字节。数据是通过14位ADC采集的,我的位分配如下:b31-b29=未使用,b28=数字输入,b27-b14=chB(签名),b13-b0=chA(签名)。最后我想对chA和chB进行FFT。为了达到目的,我使用了下面的Python代码。

1. 在这里,二进制数据文件作为一个位串被打开,样本,即516x1024x32x32位被读取并追加到一个位数组。具体做法是每次读取一个样本(4个字节或32位),颠倒字节顺序,然后把这个位串放到一个位数组中。所有样本都要重复这样做。

swap = BitArray()

f = ConstBitStream(filename='data.kbin')
f.pos = 0
samples = 516*1024*32
sample_rate = 30517.578125

for i in range(samples):
    data = BitArray()
    g = f.read('bits:32')
    data.append(g)
    data.byteswap(4)
    swap.append(data)

2. 新排序的数组再次以位串的形式打开。

data2 = ConstBitStream(swap)

3. 现在读取比特串的方式,以便应用正确的位分配(如上图所示),并将每个比特串转换为有符号的整数。同时将每个引用chA和chB的整数放入相应的列表中。

chA = []
chB = []

data2.pos = 0
for i in range(samples):
    a = data2.read('int:3')
    b = data2.read('int:1')
    c = data2.read('int:14')
    d = data2.read('int:14')
    chA.append(d)
    chB.append(c)

4. 计算FFT。

dt = 1 / sample_rate

yf_A = fftpack.rfft(chA)
yf_B = fftpack.rfft(chB)
xf = fftpack.rfftfreq(samples, dt)

这段代码是可行的,我得到了我想要的结果,但它需要很长时间。第一步花了将近10分钟,第三步花了大约3分钟。我对Python相当陌生,所以我的知识相当少。我怎样才能加快进度呢?

python-3.x performance sorting binary fft
1个回答
1
投票

我找到了一个更快的方法。

# input the path t the data file
file_kbin = input("Path to data file: ")

# initialize two lists where the converted data for chA and chB will be stored

CHA = []
CHB = []

# get the number of samples in the data file

size = 516 * 1024 * 32

# here the binary file is opened and converted following the byte assignment given above
with open(file_kbin, 'rb') as data:

    data.seek(0)                                          # make sure to start at the beginning of the file

    for i in range(size):                                 # loop over the complete file

        sample = data.read(4)                             # read one sample (byte0 byte1 byte2 byte3) 
        tmp = int.from_bytes(sample, byteorder='little')  # store the data as integer following the byteorder little (byte3 byte2 byte1 byte0)          

        chA = tmp & 0x00003FFF                            # set chA to byte1 byte0 with b15 and b14 = 0
        if (chA & 0x2000):                                # check if chA negative
            chA = chA - 0x4000                            # get the correct negative value

        chB = (tmp & 0x0FFFc000) >> 14                    # set all bits to 0 except for b27-b14 and shift right by 14 bits
        if (chB & 0x2000):                                # check if chB negative
            chB = chB - 0x4000                            # get the correct negative value

        CHA.append(chA)                                   # store the values in the corresponding list
        CHB.append(chB)

(用C++的相应代码也会快很多)

© www.soinside.com 2019 - 2024. All rights reserved.