我想使用Python重新采样存储在int32二进制文件中的时间序列。 我写下了一个能达到目的的函数;这是我的函数的简化版本:
import numpy as np
import scipy.signal as signal
def resampleData(fileName_in,fileName_out,new_number_of_samples)
fIn = open(fileName_in, 'rb')
data_in = np.fromfile(fIn, dtype="int32", count=-1, sep="")
fIn.close()
data_out=signal.resample(data_in,new_number_of_samples).astype('int32')
fOut = open(fileName_out, 'wb')
data_out.tofile(fOut,sep="")
fOut.close()
return
在处理大文件时,我的代码需要很长时间才能运行,这使我想知道是否有更好的解决方案。例如,是否有内置方法可以直接对存储在二进制文件中的时间序列进行重新采样,而不必将其写入ndarray?
非常感谢您的帮助!
答案 0 :(得分:1)
我不认为IO是这里的问题,因为即使对于这么大的阵列:
np.empty(1000000000, 'i').tofile('abc.bin')
np.fromfile('abc.bin', 'i')
只需要
1.18 s ± 26.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
阅读。如果您坚持要使用memmap
:
np.memmap('abc.bin', 'i')
“加载”所花费的时间可以忽略不计,但以后仍然需要执行IO:
5.6 µs ± 433 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
另一方面,如果通过重新采样表示降采样,则可以使用上面的memmap
方法,并直接保存原始数组的切片,如
memmap_result[::2].tofile('xxx')
采样减少一半。
如果您需要非整数逐步降采样或向上采样,更重要的是,您可以使用最近邻居方法,可以使用像这样的花哨索引:
memmap_result[np.linspace(0, len(memmap_result), num_samples).astype('i')]
应该也很快。
对于其他情况,您可能需要寻找其他重新采样算法。我看到scipy.signal.resample
使用了傅立叶变换,该变换应该非常快速且稳定。您可以使用更快的算法,例如线性插值等。但是重采样的质量可能会受到影响。