2016-10-24 70 views
4

私は2つのnumpyのデータ配列を持つpythonで二次微分をとろうとしています。例えばPythonの二次微分 - scipy/numpy/pandas

、問題の配列は次のようになります。

import numpy as np 

x = np.array([ 120. , 121.5, 122. , 122.5, 123. , 123.5, 124. , 124.5, 
     125. , 125.5, 126. , 126.5, 127. , 127.5, 128. , 128.5, 
     129. , 129.5, 130. , 130.5, 131. , 131.5, 132. , 132.5, 
     133. , 133.5, 134. , 134.5, 135. , 135.5, 136. , 136.5, 
     137. , 137.5, 138. , 138.5, 139. , 139.5, 140. , 140.5, 
     141. , 141.5, 142. , 142.5, 143. , 143.5, 144. , 144.5, 
     145. , 145.5, 146. , 146.5, 147. ]) 

y = np.array([ 1.25750000e+01, 1.10750000e+01, 1.05750000e+01, 
     1.00750000e+01, 9.57500000e+00, 9.07500000e+00, 
     8.57500000e+00, 8.07500000e+00, 7.57500000e+00, 
     7.07500000e+00, 6.57500000e+00, 6.07500000e+00, 
     5.57500000e+00, 5.07500000e+00, 4.57500000e+00, 
     4.07500000e+00, 3.57500000e+00, 3.07500000e+00, 
     2.60500000e+00, 2.14500000e+00, 1.71000000e+00, 
     1.30500000e+00, 9.55000000e-01, 6.65000000e-01, 
     4.35000000e-01, 2.70000000e-01, 1.55000000e-01, 
     9.00000000e-02, 5.00000000e-02, 2.50000000e-02, 
     1.50000000e-02, 1.00000000e-02, 1.00000000e-02, 
     1.00000000e-02, 1.00000000e-02, 1.00000000e-02, 
     1.00000000e-02, 1.00000000e-02, 5.00000000e-03, 
     5.00000000e-03, 5.00000000e-03, 5.00000000e-03, 
     5.00000000e-03, 5.00000000e-03, 5.00000000e-03, 
     5.00000000e-03, 5.00000000e-03, 5.00000000e-03, 
     5.00000000e-03, 5.00000000e-03, 5.00000000e-03, 
     5.00000000e-03, 5.00000000e-03]) 

私は現在、その後f(x) = yを持っている、と私はd^2 y/dx^2をしたいです。

数値的に言えば、私は関数を補間して解析的に微分するか、を使用することができます。

私はnp.interp()scipy.interpolateを見てきましたが、これは私に適合した(線形または立方体の)ものを返すので、どちらかを使用するのに十分なデータがあると思います。 )スプラインを使用していますが、その時点でどのように微係数を得るか分かりません。

ご指摘いただきありがとうございます。

+0

あなたは[np.diff](https://docs.scipy.org/doc/numpy/reference/generated/numpy.diff.html)を見ていましたか? – mkhanoyan

+0

私の懸念事項は、データポイントが均等に配置されていないことです。 – Jared

答えて

9

scipyの1-D Splines関数を使用してデータを補間できます。計算されたスプラインは、導関数を計算するための便利な方法を持っています。 UnivariateSplineを使用してあなたの例のデータについては

は、次のようにフィット

import matplotlib.pyplot as plt 
from scipy.interpolate import UnivariateSpline 

y_spl = UnivariateSpline(x,y,s=0,k=4) 

plt.semilogy(x,y,'ro',label = 'data') 
x_range = np.linspace(x[0],x[-1],1000) 
plt.semilogy(x_range,y_spl(x_range)) 

enter image description here

フィットは、少なくとも視覚的、合理的に良いようです提供します。 UnivariateSplineが使用するパラメータを試してみるとよいでしょう。

スプラインフィットの第二導関数は、単純に(場合、データは、いくつかの物理的プロセスに相当)結果は幾分不自然な表示

y_spl_2d = y_spl.derivative(n=2) 

plt.plot(x_range,y_spl_2d(x_range)) 

enter image description here

として得ることができます。スプラインフィットのパラメータを変更したり、データを改善したり(サンプル数を増やしたり、ノイズの少ない測定を行うなど)、データをモデリングしてカーブフィットを実行する解析関数を決定することができます(例えば、sicpyのcurve_fitを使用)

有限差分、それぞれに対するYの1次導関数により
+0

このデータは確率密度関数を表すものとします。この曲線を正規化し、いくつかのルール(負の値など)を適用する最も良い方法は何ですか? – Jared

+1

一般的な補間方法を使用するアプローチでは、制約を課す際にオプションが限られているため、標準的な答えはないと思います。原則として、制約のある最適化問題をゼロから策定して解決する必要があります。 'y_spl.integral(x [0]、x [-1])'は約80であるので、データを正規化することから始めたいと思うかもしれません。もちろん、これはpdfにとって有効な値ではありません。 – Stelios

2

はあなたのアレイ上のxの平均値で与えられる。

dy=np.diff(y,1) 
dx=np.diff(x,1) 
yfirst=dy/dx 

およびXの対応する値は、次のとおりについて

xfirst=0.5*(x[:-1]+x[1:]) 

二次再び電子同じプロセス:

dyfirst=np.diff(yfirst,1) 
dxfirst=np.diff(xfirst,1) 
ysecond=dyfirst/dxfirst 

xsecond=0.5*(xfirst[:-1]+xfirst[1:])