首页 > 解决方案 > 将多个numpy时间序列数组插入一个数组的最有效和/或最简单的方法?

问题描述

我有三个 numpy 数组,其中一列是时间戳(Unix 时间以毫秒为整数),另一列是传感器的读数(整数)。这三个阵列中的每一个在时间上同时出现(即,时间列的跨度大致相同),但是它们以不同的频率采样(一个是 500 Hz,其他是 125 Hz)。最后的数组应该是(n,4)columns [time, array1,array2,array3]

500.0 Hz Example (only the head, these are multiple minutes long)
array([[1463505325032,           196],
       [1463505325034,           197],
       [1463505325036,           197],
       [1463505325038,           195]])

125.0 Hz Example (only the head, these are multiple minutes long)
array([[1463505287912,         -5796],
       [1463505287920,         -5858],
       [1463505287928,         -5920],
       [1463505287936,         -5968]]) 

目前,我最初的计划如下,但性能并不惊人:

我有数以万计的这些间隔,它们可能长达数天,所以希望有一些相当快且内存效率高的东西。谢谢!

标签: pythonpandasnumpytime-seriessignal-processing

解决方案


您必须对 125 Hz 信号进行插值以获得 500 Hz。这取决于您需要的插值质量。对于线性插值,scipy.signal.interp1d在线性插值模式下有点慢,对于 n 个数据点 O(log n),因为它对每个评估进行二等分搜索。如果您要求它对大型数据集进行平滑插值,则计算时间会激增,因为这涉及求解具有 3n 个未知数的 3n 个方程组。

如果您的采样率具有整数比(在您的示例中为 1:4),则可以像这样更有效地进行线性插值:

# interpolate a125 to a500
n = len(a125)
a500 = np.zeros((n-1)*4+1)
a500[0::4] = a125
a500[1::4] = 0.75*a125[:-1] + 0.25*a125[1:]
a500[2::4] = 0.5*a125[:-1] + 0.5*a125[1:]
a500[3::4] = 0.25*a125[:-1] + 0.75*a125[1:]

如果您需要平滑插值,请使用scipy.signal.resample. 这是一种傅立叶方法,需要仔细处理时间序列的端点;您需要使用从终点逐渐过渡到起点的数据填充它:

from scipy.signal import resample
m = n//8
padding = np.linspace(a125[-1], a125[0], m)
a125_pad = np.concatenate([a125, padding])
a500b = resample(a125_pad, (n+m)*4)[:4*n]

根据数据的性质,在端点处具有连续导数可能会更好。

请注意,用于重采样的 FFT 喜欢具有一个数组大小,该数组大小是小素数(2、3、5、7)的乘积。m明智地选择填充大小 ( )。


推荐阅读