2017-04-14 17 views
1

タイムスタンプdatetimeインデックスと各日付に対応する値を持つpandas DataFrameがあります。例えば、df = pd.DataFrame(['0.11', '0.07', '0.04', '-0.11', '-0.04', '0.08', '0.1'], index=['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04', '2017-01-05', '2017-01-06', '2017-01-07'], columns=['values'])パンダの時系列データフレームにおける論理要素単位の操作

上記のデータフレームの現在および過去の値に基づいて、追加の列('new_value'と呼ぶ)を作成したいとします。

ロジックがなければならない:

  1. 値より大きい又は0.1に等しい場合、 'NEW_VALUE' が-1に を設定する必要があり、
  2. 'NEW_VALUE' が-1に設定されると、それは残るべき-1値 登録されている0.05以下になるまで、
  3. の値は、「NEW_VALUE」は +1に設定する必要が-0.1以下である場合、
  4. 「NEW_VALUE回'が+1に設定されている場合、値が+1になるまで+1する必要があります
  5. 、登録されている以上-0.05に等しい そうでない場合は「NEW_VALUEが」0

に等しい私は、複数の解決策を試してみましたが、この問題を解決するように見えることはできません。私は3番目の行を次のように変更した場合'ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().'

'ValueError: can only convert an array of size 1 to a Python scalar'

答えて

2

numpy.searchsorted

if df['value'][date.strftime('%Y-%m-%d').item() > 0.1: 

私はエラーが発生するなど、

new_frame = pd.DataFrame(np.zeros(len(df.index),index=df.index,columns=['new_value']) 
for date in df.index: 
    if df['value'][date.strftime('%Y-%m-%d')] > 0.1: 
     new_frame.set_value(date.strftime("%Y-%m-%d"),'new_value',-1) 

は、しかし、私はエラーが表示されます

s = df['values'].astype(float) 
al = np.array([-.1, -.05]) 
bl = np.array([1, np.nan, 0]) 
ar = np.array([.05, .1]) 
br = np.array([0, np.nan, -1]) 
l = bl[al.searchsorted(s.values)] 
r = br[ar.searchsorted(s.values, side='right')] 

df.assign(new_values=pd.Series(l + r, s.index).ffill()) 

      values new_values 
2017-01-01 0.11  -1.0 
2017-01-02 0.07  -1.0 
2017-01-03 0.04   0.0 
2017-01-04 -0.11   1.0 
2017-01-05 -0.04   0.0 
2017-01-06 0.08   0.0 
2017-01-07 0.1  -1.0 
それは浮動小数点数のちょうどシリーズを取得する必要があり

  • をどのように動作するか

    、名前それal

  • が左サイドを設定し、左側のブレークポイントを設定s
  • bl
  • 設定値をマッピングし右上のブレークポイントar
  • 右側のマップされた値br
  • searchsortedは、値が
  • 前に置かなければならないインデックスが右側値を探している場合、私は再びside='right'
  • マップ値を使用してマップされた値
  • を識別するためにsearchsortedからインデックスを使用するでしょう。
  • 左と右の結果を追加します。 nan +値は、値を前方に伝播するためにnan
  • ffillになります。

セットアップ
データフレームdfこれは素晴らしい答えですOP

df = pd.DataFrame(
    ['0.11', '0.07', '0.04', '-0.11', 
    '-0.04', '0.08', '0.1'], 
    ['2017-01-01', '2017-01-02', 
    '2017-01-03', '2017-01-04', 
    '2017-01-05', '2017-01-06', 
    '2017-01-07'], 
    ['values'] 
) 

      values 
2017-01-01 0.11 
2017-01-02 0.07 
2017-01-03 0.04 
2017-01-04 -0.11 
2017-01-05 -0.04 
2017-01-06 0.08 
2017-01-07 0.1 
+0

によって与えられたと仮定すると、あなたに感謝します。私の理解を構築する上で、私の元のアプローチがうまくいかない理由を誰もが説明できますか? –

+1

@Panda_User参照してください[***この回答は***](http://stackoverflow.com/a/43222675/2336654)それは役に立った:-) – piRSquared

+0

@Panda_User私はあなたがつかまったことがわかります最初の段階で...はい、私があなたに与えたことは、ベクトル化された解決策です。あなたはループを使う道を辿っていた。今はあなたがする必要はありません。多くの人々が、ループを実行するときにシリーズをブール値として評価するという罠に陥ります。 – piRSquared

関連する問題