2015-12-07 4 views
5

私は、毎年観測されるレートを表すパンダのデータフレームに一連の番号を持っています。numpy/scipy:一定の時間が経過した後、あるシリーズが別のシリーズに収束するようにする

実験のために、これらのシリーズのレートのいくつかを、最後に観察された年の他のシリーズのレートの1つに収束させたいと思います。

例えば、私がこのデータを持っているとしたら、aの列は、bの列が有意義な目標であることを意味します。例えば、10年の期間を小規模で増減します問題)。

私はもちろんループでこれを行うことができますが、より一般的なnumpyまたはscipyベクター化された方法で、あるシリーズのアプローチを漸進的に漸進的に棚から外すことができますか?

rate    a   b     
year                  
2006    0.393620 0.260998   
2007    0.408620 0.260527 
2008    0.396732 0.257396 
2009    0.418029 0.249123 
2010    0.414246 0.253526 
2011    0.415873 0.256586 
2012    0.414616 0.253865  
2013    0.408332 0.257504  
2014    0.401821 0.259208 
+1

だから必ず私が正しく理解させるために:あなたはすでに持っています'' a''と '' b''両方のデータを扱いますが、 '' b''を漸近的に '' a''に近づけるように変更したいのですか?あるいは、最初から '' b''を生成したいのですか? – pmos

+1

'a'をより正確な数学的表現で' b'に近づける方法を説明できますか?私は、 'a'に適用されたインクリメントが「偶数サイズ」の場合、' a'が 'b' *に漸近的に近づく方法を見ません。あなたが望む操作を行う、遅い 'for'ループを表示できれば、ベクトル化されたアプローチをテストすることができます。 –

+0

@pmos前者:私は 'a'と' b'の両方を持っていて、 'b'を一定の期間にわたって' a'に近づけるように変更したいと思っています。 – ako

答えて

5

一般的に言えば、あなたはいくつかの範囲に渡って「イージング関数」を適用すると思います。例えば

は、下図考慮してください。ここでは

enter image description here

を、我々は2つの元のデータセットを持っています。 2つを減算し、その差に3行目に示すイージング関数を掛けて、結果を最初の曲線に戻します。これにより、灰色領域の左側の元のデータ、灰色領域内の2つのブレンド、および灰色領域の右側の他の曲線のデータである新しい系列が得られます。一例として、

:あなたは上記のプロットについて興味があれば

import numpy as np 
import matplotlib.pyplot as plt 

# Generate some interesting random data 
np.random.seed(1) 
series1 = np.random.normal(0, 1, 1000).cumsum() + 20 
series2 = np.random.normal(0, 1, 1000).cumsum() 
# Our x-coordinates 
index = np.arange(series1.size) 

# Boundaries of the gray "easing region" 
i0, i1 = 300, 700  

# In this case, I've chosen a sinusoidal easing function... 
x = np.pi * (index - i0)/(i1 - i0) 
easing = 0.5 * np.cos(x) + 0.5 

# To the left of the gray region, easing should be 1 (all series2) 
easing[index < i0] = 1 

# To the right, it should be 0 (all series1) 
easing[index >= i1] = 0 

# Now let's calculate the new series that will slowly approach the first 
# We'll operate on the difference and then add series1 back in 
diff = series2 - series1 
series3 = easing * diff + series1 

はまた、ここではそれが生成されています方法は次のとおりです。

fig, axes = plt.subplots(nrows=4, sharex=True) 

axes[0].plot(series1, color='lightblue', lw=2) 
axes[0].plot(series2, color='salmon', lw=1.5) 
axes[0].set(ylabel='Original Series') 

axes[1].plot(diff, color='gray') 
axes[1].set(ylabel='Difference') 

axes[2].plot(easing, color='black', lw=2) 
axes[2].margins(y=0.1) 
axes[2].set(ylabel='Easing') 

axes[3].plot(series1, color='lightblue', lw=2) 
axes[3].plot(series3, color='salmon', ls='--', lw=2, dashes=(12,20)) 
axes[3].set(ylabel='Modified Series') 

for ax in axes: 
    ax.locator_params(axis='y', nbins=4) 
for ax in axes[-2:]: 
    ax.axvspan(i0, i1, color='0.8', alpha=0.5) 

plt.show() 
+0

私は 'cos'よりも別の機能をプラグインしたい場合、魅力的に働き、非常に柔軟です。 – ako

2

すべての権利ので、これはちょうどあなたがaを想定し、コード形式でごcommentで説明した手順とbでは、あなたの2つのnumpyの配列です:

b += (a[-1]-b[-1])/len(b)*numpy.arange(1,len(b)+1) 

(a[-1]-b[-1])/len(b)は、一つの「チャンク」と1以上でありますそれらのうちの1つは、numpy.arange()配列の乗算を介して、各 "反復"(年)に追加されます。私はいくつかのプロットを試しましたが、あなたがそれを微調整しない限り良く見えませんが、それはあなたが求めていたものです。

Example of what this looks like

関連する問題