python - 将多个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]])
目前,我最初的计划如下,但性能并不惊人:
- 找到最早的开始时间(不同频率和系统问题的 b/c,它们并不完全以相同的毫秒开始)
- 创建一个新数组,其时间列从最早的时间开始,并且与三个数组中最长的时间一样长。
np.linspace
使用/将时间列填充到所需的公共频率np.arange
- 循环三个数组,使用
np.interp
或类似方法转换为公共频率,然后将输出堆叠到上面创建的公共 numpy 数组上
我有数以万计的这些间隔,它们可能长达数天,所以希望有一些相当快且内存效率高的东西。谢谢!
解决方案
您必须对 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
明智地选择填充大小 ( )。
推荐阅读
- java - 动态更新查询mybatis mapper
- android - Flutter 冻结系统(ubuntu)
- java - 了解 DataBinding 的生命周期
- mysql - 无法在我的 buffalo 应用程序中写入 mySQL db 或从中读取
- unit-testing - 是否可以将用户输入保存在变量中以使用intellij(pycharm)连续测试
- ada - Ada 阐述根本没有发生
- java - 切换字符串的第一个和最后一个字母
- excel - Excel基于相邻列的动态数据校验
- python - 如何使用 send_mail 制作 Django 与我联系表格?
- php - Wordpress 插件无法识别所需文件