我有一个这样的数据框(刚好大得多,x的步长更小):
x val1 val2 val3
0 0.0 10.0 NaN NaN
1 0.5 10.5 NaN NaN
2 1.0 11.0 NaN NaN
3 1.5 11.5 NaN 11.60
4 2.0 12.0 NaN 12.08
5 2.5 12.5 12.2 12.56
6 3.0 13.0 19.8 13.04
7 3.5 13.5 13.3 13.52
8 4.0 14.0 19.8 14.00
9 4.5 14.5 14.4 14.48
10 5.0 NaN 19.8 14.96
11 5.5 15.5 15.5 15.44
12 6.0 16.0 19.8 15.92
13 6.5 16.5 16.6 16.40
14 7.0 17.0 19.8 18.00
15 7.5 17.5 17.7 NaN
16 8.0 18.0 19.8 NaN
17 8.5 18.5 18.8 NaN
18 9.0 19.0 19.8 NaN
19 9.5 19.5 19.9 NaN
20 10.0 20.0 19.8 NaN
我最初的问题是计算每个列的导数,并且在以下问题中得到了解决:如何在Pandas DataFrame中获取值的索引?Alexander发布的解决方案与我以前的代码相同,如下所示:
import pandas as pd
import numpy as np
df = pd.read_csv('H:/DocumentsRedir/pokus/dataframe.csv', delimiter=',')
vals = list(df.columns.values)[1:]
dVal = df.iloc[:, 1:].diff() # `x` is in column 0.
dX = df['x'].diff()
dVal.apply(lambda series: series / dX)
但是,我需要进行一些平滑处理(比方说,从x的原始0.5 m间距到此处2 m),因为导数的值只是在精细范围内变得疯狂。我尝试了scipy函数filtfilt和butter(我想使用Butterworth过滤器,这是我学科中的常见做法),但是可能我没有正确使用它们。更新:还尝试了savgol_filter。
如何在此代码中实现这些功能?
(这是我修改代码的方式:
step = 0.5
relevant_scale = 2
order_butterworth = 4
b, a = butter(order_butterworth, step/relevant_scale, btype='low', analog=False)
smoothed=filtfilt(b,a,data.iloc[:, 1:]) # the first column is x
dVal = smoothed.diff()
dz = data['Depth'].diff()
derivative = (dVal.apply(lambda series: series / dz))*1000
但是我得到的结果是一系列NaN并得到了错误AttributeError: 'numpy.ndarray' object has no attribute 'diff'
)
答案-https: //stackoverflow.com/a/38691551/5553319解决了这个问题,该代码确实适用于连续数据。但是,我在源数据中进行的几乎不明显的更改会发生什么?(中间的NaN值。)
那么,即使我们错过了本来连续的数据数组中的数据点,又如何使该解决方案稳定呢?好的,在评论中也回答了。此类丢失的数据点需要进行插值。
您看到的错误是因为您试图.diff()
在的结果上调用该方法,该结果filtfilt
是一个没有该方法的numpy数组。如果您确实想使用一阶差分,则可以使用np.gradient(smoothed)
现在看来,您的真正目标似乎是获得对噪声信号导数的无滞后估计。我建议您宁可使用诸如Savitzky Golay滤波器之类的东西,它可以让您在该滤波器的一个应用程序中获得导数估计。您可以在此处看到有关噪声信号的导数估计的示例
您还需要容纳NaN
数据中的。这是我将如何处理您的数据的方法:
import scipy.signal
import matplotlib.pyplot as plt
# Intelligent use of the index allows us to keep track of the x for the data.
df = df.set_index('x')
dx = df.index[1]
for col in df:
# Get rid of nans
# NOTE: If you have nans in between your data points, this does the wrong thing,
# but for the data you show for contiguous data this is fine.
nonans = df[col].dropna()
smoothed = scipy.signal.savgol_filter(nonans, 5, 2, deriv=1, delta=dx)
plt.plot(nonans.index, smoothed, label=col)
plt.legend()
结果如下图:
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句