gpt4 book ai didi

python - 读取交错数据的快速方法?

转载 作者:太空狗 更新时间:2023-10-29 20:20:46 26 4
gpt4 key购买 nike

我有一个包含多个数据通道的文件。文件以基本速率采样,每个 channel 以该基本速率除以某个数字采样——它似乎总是 2 的幂,但我认为这不重要。

所以,如果我有 channel abc,在 1、2 和 4 的分度处采样,我的流看起来像:

a0 b0 c0 a1 a2 b1 a3 a4 b2 c1 a5 ...

为了增加乐趣, channel 可以独立地是 float 或整数(虽然我知道每一个),并且数据流不一定以 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() 上花费了大量时间——这是有道理的;那里有一些条件逻辑。

我的大脑感觉好像有一种方法可以一举完成,而不是嵌套循环——也许使用索引技巧将我想要的字节读取到每个数组中?构建一个巨大的、疯狂的格式字符串的想法似乎也是一条值得商榷的道路。

更新

感谢那些回应的人。值得一提的是,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/

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