【发布时间】:2011-05-12 19:05:57
【问题描述】:
我有一个包含多个数据通道的文件。文件以基本速率采样,每个通道都以该基本速率除以某个数字进行采样——它似乎总是 2 的幂,尽管我认为这并不重要。
所以,如果我有频道 a、b 和 c,在 1、2 和 4 的分隔符处采样,我的流看起来像:
a0 b0 c0 a1 a2 b1 a3 a4 b2 c1 a5 ...
为了增加乐趣,通道可以独立地是浮点数或整数(尽管我知道每个通道),并且数据流不一定以 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 倍。
【问题讨论】:
-
为什么有人要这样对你?
-
如果 ch.samples_for 是问题所在,那么我们需要查看该函数才能知道如何为您提供帮助。顺便问一下,你有多少个频道?
-
您现在是否实际上每次通过循环只读取一个频道?起初我以为不是这样,但现在我不清楚了。
-
啊,这些文件来自一个嵌入式系统,该系统读取生理数据(心率、呼吸等)以及一些数字信号——我们在记录生理信号的同时进行功能性核磁共振和心理测试。这正是我们得到的。
-
现在,我正在阅读,分组,
(a0 b0 c0) (a1) (a2 b1) (a3) (a4 b2 c1) (a5)
标签: python optimization numpy binary-data