2017-02-05 4 views
5

私は、現在のコードがかなり遅いので、ベクトル化された方法で以下のコードを書いてみたいと思います(Pythonのベストプラクティスを学びたいと思います)。基本的に、コードは、今日の値が昨日の値の10%以内であれば、今日の値(新しい列内の値)は昨日の値と同じであると言っています。そうでなければ、今日の値は変更されません:ループを使用する代わりに、ベクトル化された方法でコードを書く方法は?

def test(df): 
    df['OldCol']=(100,115,101,100,99,70,72,75,78,80,110) 
    df['NewCol']=df['OldCol'] 
    for i in range(1,len(df)-1): 
     if df['OldCol'][i]/df['OldCol'][i-1]>0.9 and df['OldCol'][i]/df['OldCol'][i-1]<1.1: 
      df['NewCol'][i]=df['NewCol'][i-1] 
     else: 
      df['NewCol'][i]=df['OldCol'][i] 
    return df['NewCol'] 

出力は次のようする必要があります。

OldCol NewCol 
0  100  100 
1  115  115 
2  101  101 
3  100  101 
4  99  101 
5  70  70 
6  72  70 
7  75  70 
8  78  70 
9  80  70 
10  110  110 

あなたは助けてくださいことはできますか?

私はこのようなものを使用したいと思いますが、私は私の問題を解決するために管理していませんでした:

def test(df): 
    df['NewCol']=df['OldCol'] 
    cond=np.where((df['OldCol'].shift(1)/df['OldCol']>0.9) & (df['OldCol'].shift(1)/df['OldCol']<1.1)) 
    df['NewCol'][cond[0]]=df['NewCol'][cond[0]-1]  
    return df  
+1

'df'は、データフレームは、右、次のとおりです。1行で

? 'df ['OldCol']'や 'NewCol 'の' dtype'とは何ですか?私はこれがPythonicよりも良いパンダコーディングの問題だと思う。 – hpaulj

+0

'' 'OldCol =(100,115,101,100,99,70,72,75,78,80,81,82,110)' ''の望ましい結果は何ですか? – wwii

答えて

0

あなたの元データフレームをマスクブール必要があります。NewColがどこにある

df[(0.9 <= df['NewCol']/df['OldCol']) & (df['NewCol']/df['OldCol'] <= 1.1)]はあなたにすべての行を与えますOldCol

の10%以内したがって、これらの行にNewColフィールドを設定します

within_10 = df[(0.9 <= df['NewCol']/df['OldCol']) & (df['NewCol']/df['OldCol'] <= 1.1)] 
within_10['NewCol'] = within_10['OldCol'] 
0

"ジャンプ"の日を見つけるには良い方法だと思われるので、私はちょっとしたトリックを表示します。したがって、oldの長さがNで、ブール値のnumpy配列jumpが同じサイズの配列があるとします。慣例として、jumpの0番目の要素はTrueに設定されています。そして、あなたは最初のジャンプの間の繰り返しの数を計算することができます:あなたはこれらを持って

jump_indices = np.where(jumps)[0] 
repeats = np.diff(np.r_[jump_indices, [N]]) 

たら、np.repeatを使用することができます。

new = np.repeat(old[jump_indices], repeats) 
2

3つの段階で解決策:

df['variation']=(df.OldCol/df.OldCol.shift()) 
df['gap']=~df.variation.between(0.9,1.1) 
df['NewCol']=df.OldCol.where(df.gap).fillna(method='ffill') 

の場合:

OldCol variation gap NewCol 
0  100  nan True  100 
1  115  1.15 True  115 
2  101  0.88 True  101 
3  100  0.99 False  101 
4  99  0.99 False  101 
5  70  0.71 True  70 
6  72  1.03 False  70 
7  75  1.04 False  70 
8  78  1.04 False  70 
9  80  1.03 False  70 
10  110  1.38 True  110 

この例ではループよりも30倍高速です。

x=df.OldCol;df['NewCol']=x.where(~(x/x.shift()).between(0.9,1.1)).fillna(method='ffill') 
+0

これは私が必要とするものです - ありがとう – crazyfrog

関連する問題