3

ある時系列の値を別の時系列で上書きしたいと思います。入力系列はすべての点で値を持ちます。上書き時系列は同じインデックス (つまり日付) を持ちますが、いくつかの日付でのみ値を上書きしたいと思います。NaNこれを指定する方法は、その値にオーバーライドしたい場所とオーバーライドを適用したくない場所の値を持つ時系列を持つことです。

おそらく、簡単な例で最もよく説明されています。

            ints  orts  outts
index
2013-04-01     1   NaN      1
2013-05-01     2    11      2
2013-06-01     3   NaN      3
2013-07-01     4     9      4
2013-08-01     2    97      5

# should become

            ints  orts  outts
index
2013-04-01     1   NaN      1
2013-05-01     2    11     11
2013-06-01     3   NaN      3
2013-07-01     4     9      9
2013-08-01     2    97     97

例からわかるように、置換の値はインデックスの場所に依存し、入力値に依存しないため、 replaceorメソッドは機能しないと思います。whereこれを複数回実行したいので、関数に入れました。以下に示すように機能するソリューションがあります。

def overridets(ts, orts):
    tmp = pd.concat([ts, orts], join='outer', axis=1)
    out = tmp.apply(lambda x: x[0] if pd.isnull(x[1]) else x[1], axis=1)
    return out

問題は、これが比較的遅く実行されることです。私の環境では、500 ポイント シリーズで 20 ~ 30 ミリ秒です。2 つの 500 ポイント シリーズを乗算するには ~200 us かかるため、約 100 倍遅くなります。ペースを上げる方法について何か提案はありますか?

編集

問題に対する私の最終的な解決策の下にある @Andy と @bmu からのヘルプは次のとおりです。

def overridets(ts, orts):

     ts.name = 'outts'
     orts.name = 'orts'
     tmp = pd.concat([ts, orts], join='outer', axis=1)

     out = tmp['outts'].where(pd.isnull(tmp['orts']), tmp['orts'])
     return out

inplace=Trueこれは常に単一の時系列を返す関数にラップされていたため、必要ありませんでした。ほぼ 50 倍高速なので、みんなありがとう!

4

2 に答える 2

0

convert_first 関数は Pandas に組み込まれており、この問題を処理します。

In [62]:  df

Out [62]:
                ints  orts  outts
    2013-04-01     1   NaN      1
    2013-05-01     2    11     11
    2013-06-01     3   NaN      3
    2013-07-01     4     9      9
    2013-08-01     2    97     97

In [63]:
    df['outts'] =  df.orts.combine_first(df.ints)
    df

Out [63]:
                ints  orts  outts
    2013-04-01     1   NaN      1
    2013-05-01     2    11     11
    2013-06-01     3   NaN      3
    2013-07-01     4     9      9
    2013-08-01     2    97     97

これは、以前のソリューションと同じくらい高速である必要があります...

In [64]:
    df500 = pd.DataFrame(np.random.randn(500, 2), columns=['orts', 'outts'])
    %timeit df500.orts.combine_first(df500.outts)

Out [64]:
    1000 loops, best of 3: 210 µs per loop
于 2013-09-15T19:10:55.513 に答える