2017-05-18 17 views
1

私はパンダの専門家ではありません。私は普通のdevの男です。最も効率的な管理値の計算方法

私は管理値を計算したいと思います。 私はdfを1日当たりの市場価格(インデックスを日付として)とdfTrendを同じインデックスの0と1としています。

これらのデータフレームを関数に送り、管理された値を取得すると、トレンドがゼロの場合、管理された値がフラットなままになり、トレンドが1の場合は値を増やし続けます市場価格。例えば

enter image description here

は私のコードは正常に動作しますが、それは非常に遅いです:

def getManagedValue(df, dfTrend): 
    dfReturn = df.pct_change(1) 
    dfManaged = df 

    for col in df: 
     for i in range(1, len(df[col])): 
      dfManaged[col][0] = df[col][0] 
      if dfTrend[col][i] == 1: 
       dfManaged[col][i] = dfManaged[col][i-1] * (1 + dfReturn[col][i]) 
      else: 
       dfManaged[col][i] = dfManaged[col][i-1] 
    return dfManaged 

それはより速く実行されるように、私はこれを最適化することができますどのように誰もが知っていますか?すべての列のすべてのセルの反復は、ここでは間違いなく問題です。

誰でも提案を持っている...私はcythonでこれを実行していると思っていますが、私はcython、のみnumpyのの配列でパンダを使用することはできませんよと信じていますか? ジュリアン

答えて

1

パンダスピードとパワー

乾杯は、全体のアレイ上で動作ではなく、個々の行とセルを反復処理から来ています。私が正しくあなたの元の例では、論理に従うならば、あなたはこれより速く行うにnp.whereを使用することができます。

dfManaged = np.where(dfTrend == 1, df.shift(1) * (1 + df.pct_change(1)), df.shift(1)) 
  • np.where あなたは (この場合、dfTrend == 1に)いくつかの条件を指定し、1から値を割り当てることができますその条件が真である場合は (df.shift(1) * (1 + df.pct_change(1)))、それ以外の場合は 条件が偽(df.shift(1))のデータフレーム。
  • df.shift(1) dfManaged[col][i-1] のように、すべての値をdfに移動しますが、反復する必要はありません。
  • これは、一度に1つの行と列ではなく、データフレーム全体の操作を一度に実行することに注意してください。それはそれをスピードアップするはずです。
+0

ありがとう、それは私が探しているものです。 unfortunetaly、df.shift(1)トレンド== 0なら、私はそれが高原にしたいときにはまだ増加しています。なぜ私は理解できません。 (私はそれをnp.nanとこの仕事に置き換えようとしました) – JulienCoo

+0

申し訳ありませんが、あなたの質問/私の答え、またはdfTrend自体のコードに問題がありますか? – ASGM

+0

df.shift(1)は、dfTrend = 0の間、管理された値を同じ値に保持しません。 – JulienCoo

0

私が集めたものから、派生物(df.pct_change(1))を使用してカーブを再構成します。トレンドが1の場合、この導関数を使用したい場合は、0の微係数を0にする必要があります。

これを効率的に実行するのはちょっと難しいことです。 1つの試みは、(i)dfTrendを使用して誘導体を修飾し、そして(ii)managedをその派生物の累積合計として再計算することであろう。ここで浮動小数点エラーが発生する可能性があります - わかりません。

# step 1 
deriv = 1 + df.pct_change(1) 
deriv[dfTrend == 0] = 0 
# step 2 
managed = np.cumsum(deriv) 
# optional -- remove potential floating point errors where possible 
managed[dfTrend == 1] = df[dfTrend == 1] 
+0

ありがとう、私はかなり効果的なソリューション(下記参照)を見つけましたが、とにかくそれを試みます。 – JulienCoo

0

ご回答ありがとうございます。私は最後に解決策を見つけました。

[2696行×305列]のデータフレームの場合、 (問題のコードを使用して)pandasデータフレームで処理するのに約5分かかります。

numpy配列を使用して2.30分になりました。

最後に、私はすべてを暗号化して2.5秒になりました。これは間違いなく十分です。

乾杯、 Julien

関連する問題