Python(或Excel)中的数据同步

0 投票
1 回答
1773 浏览
提问于 2025-04-18 15:47

我经常使用Python(偶尔也用Excel)来处理和比较多个实验的测试数据。有时候,数据可能不同步,这让直接比较变得困难。例如,一个典型的测试规范可能是:

1) Stabilize test temperature to a value of 20 +/- 2 degrees C
2) Hold test temperature at stabilized value for 15-25 seconds
3) Increase temperature by 20 degrees C at a rate of 0.5 degree C/second

将数据标准化,使它们在时间=0秒时都从20摄氏度开始是很简单的,但我真正想要的是让数据同步,这样温度上升的开始时间是一样的。

我尝试过一些简单的算法来检查数据的斜率,以找出温度开始上升的时刻,但由于仪器的原因,测量数据会有局部波动,这导致斜率并不能真实反映温度的整体变化率。

请问在Numpy、Scipy、Pandas等库中,有没有可以过滤这些局部波动并识别温度实际开始上升时刻的函数?

我偶尔也会用Excel,所以如果在电子表格中有更方便的方法来处理这些数据,我也可以用Excel来完成。

任何建议都非常感谢。

1 个回答

2

有很多方法可以解决这个问题。首先想到的是对数据进行数值微分,看看斜率从0跳到0.5的地方。但是(正如你观察到的)噪声数据可能会让这个方法效果不好。如果你在网上搜索“噪声数据的数值微分”,你会发现很多相关的研究,但我不知道在Python中有没有现成的库可以用。你可以尝试使用Savitzky-Golay滤波器:scipy.signal.savgol_filter

不过,这种方法可能有点复杂,因为你的信号有一个非常简单和特定的预期结构:先是一个恒定的区间,然后是一个上升段,最后又是一个恒定的区间。你可能会发现scipy.optimize.curve_fit对这个问题效果很好。这里有一个例子:

from __future__ import division

import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt


def ramp(t, temp_init, temp_final, t0, t1):
    slope = (temp_final - temp_init) / (t1 - t0)
    y = temp_init + np.minimum(slope * np.maximum(t - t0, 0.0), temp_final - temp_init)
    return y

np.random.seed(123)

dt = 0.5
t = np.arange(0, 100, dt)

# Generate a sample to work with.
temp_init = 20.0 + np.random.randn()
temp_final = 40.0 + np.random.randn()
t0 = 25.0
t1 = t0 + 40
y = ramp(t, temp_init, temp_final, t0, t1)
y += 0.25*np.random.randn(*t.shape)  # Add noise.

# Create an initial guess for the four parameters and use curve_fit
# to fit the ramp function to the sample.
T = t[-1] - t[0]
p0 = (20, 40, t[0] + 0.333*T, t[0] + 0.667*T)
popt, pcov = curve_fit(ramp, t, y, p0=p0)
fit_temp_init, fit_temp_final, fit_t0, fit_t1 = popt


print "             Input    Fit"
print "temp_init   %6.2f  %6.2f" % (temp_init, fit_temp_init)
print "temp_final  %6.2f  %6.2f" % (temp_final, fit_temp_final)
print "t0          %6.2f  %6.2f" % (t0, fit_t0)
print "t1          %6.2f  %6.2f" % (t1, fit_t1)

plt.plot(t, y, 'ro', alpha=0.15)
plt.plot(t, ramp(t, popt[0], popt[1], popt[2], popt[3]), 'k-', linewidth=1.5)
plt.grid(True)
plt.xlabel('t', fontsize=12)
plt.show()

这会生成以下输出:

             Input    Fit
temp_init    18.91   18.91
temp_final   41.00   40.99
t0           25.00   24.85
t1           65.00   65.09

以及这个图:

fit ramp

撰写回答