我有一个包含几个数据 channel 的文件。该文件以基本速率进行采样,每个 channel 均以该基本速率除以某个数字进行采样-似乎总是2的幂,尽管我认为这并不重要。
因此,如果我有 channel a,b和c,分别在1、2和4的分频器上采样,则流将如下所示:

a0 b0 c0 a1 a2 b1 a3 a4 b2 c1 a5 ...
为了增加乐趣, channel 可以独立地是浮点数或整数(尽管我对每个 channel 都知道),并且数据流不一定以2的幂结尾,示例流在没有进一步扩展的情况下将是有效的。这些值有时很大,有时是低端的,尽管我知道我要处理的是什么。
我有正确解压缩这些代码并用正确的值填充numpy数组的代码,但是它很慢:看起来像(希望我并不过分;只是对算法有所了解):
for sample_num in range(total_samples):
    channels_to_sample = [ch for ch in all_channels if ch.samples_for(sample_num)]
    format_str = ... # build format string from channels_to_sample
    data = struct.unpack( my_file.read( ... ) ) # read and unpack the data
    # iterate over data tuple and put values in channels_to_sample
    for val, ch in zip(data, channels_to_sample):
        ch.data[sample_num / ch.divider] = val
而且速度很慢-几秒钟即可在笔记本电脑上读取20MB的文件。 Profiler告诉我,我在Channel#samples_for()中花了很多时间-这很有意义;那里有一些条件逻辑。
我的大脑感觉好像有一种方法可以一次完成,而不是嵌套循环-也许使用索引技巧将我想要的字节读取到每个数组中?构建一个巨大的,疯狂的格式字符串的想法似乎也是一条值得商down的道路。
更新
感谢那些回应。值得的是,numpy索引技巧将读取我的测试数据所需的时间从大约10秒减少到大约0.2秒,从而使速度提高了50倍。

最佳答案

真正提高性能的最好方法是摆脱所有示例的Python循环,然后让NumPy在编译的C代码中执行此循环。要做到这一点有些棘手,但有可能。

首先,您需要一些准备。正如贾斯汀·皮尔(Justin Peel)所指出的那样,在一些步骤之后,重复排列了样本。如果d_1,...,d_k是k个数据流的除数,而b_1,...,b_k是流的样本大小(以字节为单位),而lcm是这些除数的最小公倍数,则

N = lcm*sum(b_1/d_1+...+b_k/d_k)

将是流模式之后将重复的字节数。如果您已找出前N个字节中的每个字节属于哪个流,则只需重复此模式即可。

现在,您可以通过类似于以下内容来构建前N个字节的流索引数组
stream_index = []
for sample_num in range(lcm):
    stream_index += [i for i, ch in enumerate(all_channels)
                     if ch.samples_for(sample_num)]
repeat_count = [b[i] for i in stream_index]
stream_index = numpy.array(stream_index).repeat(repeat_count)

在此,d是序列d_1,...,d_k,b是序列b_1,...,b_k。

现在你可以做
data = numpy.fromfile(my_file, dtype=numpy.uint8).reshape(-1, N)
streams = [data[:,stream_index == i].ravel() for i in range(k)]

您可能需要在数据末尾填充一点以使reshape()工作。

现在,您拥有属于每个流的所有字节,位于单独的NumPy数组中。您可以通过简单地分配给每个流的dtype属性来重新解释数据。如果要将第一个流解释为大端整数,只需编写
streams[0].dtype = ">i"

这不会以任何方式更改数组中的数据,而只会更改其解释方式。

这可能看起来有点神秘,但在性能方面应该更好。

关于python - 快速读取交错数据的方法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4227990/

10-12 14:19
查看更多