2017-08-10 15 views
1

この場合、複数のポイントから選択/スライスを選択するには、すべての列に対してmax()から開始します。各株はそれ自身の最大値を有するので、その特定の地点から選択を開始する。 パンダの異なるポイントから行を選択する方法

df 
>>>          TSLA    MSFT 
2017-05-15 00:00:00+00:00    314    68 
2017-05-16 00:00:00+00:00    319    69 
2017-05-17 00:00:00+00:00    320    61 
2017-05-18 00:00:00+00:00    313    66 
2017-05-19 00:00:00+00:00    316    70 
2017-05-22 00:00:00+00:00    314    65 
2017-05-23 00:00:00+00:00    310    63 


max_idx = df.idxmax() # returns index of max value 
>>> TSLA 2017-05-17 00:00:00+00:00 
>>> MSFT 2017-05-19 00:00:00+00:00 

max_value = df.max() # returns max value 
>>> TSLA = 320 
>>> MSFT = 70 

は使用してのような彼らのいずれかの方法で、私は後でMAX_VALUEを見つけることができるようにして、もう一度、この新しい出力から始まるmax_idxに出力したい df2 = df.loc[max_idx:]

TSLA 2017-05-17 00:00:00+00:00 
MSFT 2017-05-19 00:00:00+00:00 

EDITです:次の出力を期待しています:

df2 
>>> TSLA         MSFT 
    2017-05-17 00:00:00+00:00  320  2017-05-19 00:00:00+00:00 70 
    2017-05-18 00:00:00+00:00  313  2017-05-22 00:00:00+00:00 65  
    2017-05-19 00:00:00+00:00  316  2017-05-23 00:00:00+00:00 63  
    2017-05-22 00:00:00+00:00  314    
    2017-05-23 00:00:00+00:00  310 

@UnutbuがMultindexingを使用するのと同様に、可能であれば新しいデータフレームをマルチインデックス化することができます。

たとえば、私は2列しか投稿しませんでしたが、その列の数は100であり、 なので、このような大きなデータに注意してください。ありがとう! (あなたは、どちらか一方を選択することができ、両方の最大値よりも大きいタイムスタンプを持つあなたに行を与える

df[(df.index > max_idx.TSLA) & (df.index > max_idx.TSLA)] 

、私は:

+0

を? – MaxU

+0

@MaxU pd.read_clipboard()はあなたの友人です。 – Stael

+0

私はどんな形式の出力も受け入れることができます。ちょうど 'TSLA 2017-05-17 00:00:00 + 00:00から始まる最大値を見つけることができます。 MSFT 2017-05-19 00:00:00 +00:00' @MaxUあなたはどんな形式でも自由に使うことができます。 – ArJuN

答えて

2

あなたはapplyメソッドを使用できます。

In [204]: df.apply(lambda s: s.loc[s.idxmax():]) 
Out[204]: 
      MSFT TSLA 
2017-05-17 NaN 320 
2017-05-18 NaN 313 
2017-05-19 70.0 316 
2017-05-22 65.0 314 
2017-05-23 63.0 310 

または、MaxU's answerに構築、

In [205]: pd.concat({c:df.loc[max_idx[c]:, c] for c in df.columns}).unstack(level=0) 
Out[205]: 
      MSFT TSLA 
2017-05-17 NaN 320.0 
2017-05-18 NaN 313.0 
2017-05-19 70.0 316.0 
2017-05-22 65.0 314.0 
2017-05-23 63.0 310.0 

これらのソリューションの両方が列をループします。 (df.applyのループは のフードで行われますが、それはパフォーマンス上の点ではPythonスピードのループになります。) はベクトル化されたソリューションを探していますが、この場合は表示されません。 ループ。


あなたはNaNを避けたい場合は、アンスタック答えを残すことができる:

In [208]: pd.concat({c:df.loc[max_idx[c]:, c] for c in df.columns}) 
Out[208]: 
MSFT 2017-05-19  70 
     2017-05-22  65 
     2017-05-23  63 
TSLA 2017-05-17 320 
     2017-05-18 313 
     2017-05-19 316 
     2017-05-22 314 
     2017-05-23 310 
dtype: int64 

か、あなたはdf.applyを使用している場合、のレベルに列のラベルを移動するstackを呼び出します行インデックス:

In [213]: df.apply(lambda s: s.loc[s.idxmax():]).T.stack() 
Out[213]: 
MSFT 2017-05-19  70.0 
     2017-05-22  65.0 
     2017-05-23  63.0 
TSLA 2017-05-17 320.0 
     2017-05-18 313.0 
     2017-05-19 316.0 
     2017-05-22 314.0 
     2017-05-23 310.0 
dtype: float64 

それでは、パフォーマンスを見てみましょう。この設定で(大きなDATAFRAMEにテストする):

shape = (1000,2000) 
bigdf = pd.DataFrame(np.random.randint(100, size=shape), 
        index=pd.date_range('2000-1-1', periods=N)) 

def using_apply(df): 
    return df.apply(lambda s: s.loc[s.idxmax():]) 

def using_loop(df): 
    max_idx = df.idxmax() 
    return pd.concat({c:df.loc[max_idx[c]:, c] for c in df.columns}).unstack(level=0) 

MaxUのusing_loopusing_applyよりも若干速いです。しかし、

In [202]: %timeit using_apply(bigdf) 
1 loop, best of 3: 1.45 s per loop 

In [203]: %timeit using_loop(bigdf) 
1 loop, best of 3: 1.22 s per loop 

注意、それはと自分のマシン上でベンチマークをテストするために最善であること結果 は異なる場合があります。

+0

すごくおかげさまでした。しかし、今はどのようにして '2017 -05-19 MSFT 70 2017-05-17 TSLA 320'、私が使用する機能は、パンダには新しく、助けてください。 – ArJuN

+0

申し訳ありませんが、私は何をしたいと思っているのか具体的に質問しませんでした。私は質問を編集しましたが、出力がどのようになるかを明確に述べました。 – ArJuN

+0

ありがとう、@unutbu、uは私の一日を作った。神のお恵みがありますように! – ArJuN

1

あなたが最大のインデックスに基づいてスライスしたい場合は、あなたが使用することができますあなたが望んでいたのかわからなかった)

+0

'df.loc [max_idx.max():]'を実行できますが、私はできません確かにOPはこのようなものを望んでいます... – MaxU

+0

@ Maxiはただ1つの株のデータセットを産出することができますが、私は両方のカラムが必要でした。 – ArJuN

+0

@ArJuN、私は知っている - それは私が望むデータセットをあなたに尋ねた理由です... – MaxU

2

私たちは、このような何か行うことができます:あなたが希望するデータセットを投稿することができます

In [120]: {c:df.loc[max_idx[c]:, c].max() for c in df.columns} 
Out[120]: {'MSFT': 70, 'TSLA': 320} 
+1

これはすばらしい男ですが、ここで問題になるのは、ループのための100の列/株を扱うことになるので、パフォーマンスが低下するかもしれませんが、あなたの答えが本当に好きです。あなたとunutbuによって提供される両方のソリューションを試し、 1つは、私が正式にあなたの答えをupvoteするつもりです。 – ArJuN

+0

私は質問を編集し、出力がどのように最終的に見えるかを指定しました。申し訳ありませんが、私の出力がどのように見えるかを伝えることができなかったのは間違いでした。 – ArJuN

関連する問題