2016-04-17 6 views
2

概念的には単純なタスクを実行しようとしていますが、コードが高すぎるようです。私は、GroupByオブジェクトのためのパンダの組み込み関数を潜在的に利用して、より速い方法を探しています。Python:pandas GroupByオブジェクトで効率的に使用する

開始点は、各観測値がアイテムに固有の最新の価格更新である、columns = [['item'、 'store'、 'day'、 'price']]を持つpricesというDataFrameです。ストアの組み合わせ。問題は、一部の価格の更新が、同じアイテムストアの組み合わせの最終価格の更新と同じであることです。たとえば、私たちは特定の部分を見てみましょう:

 day item_id store_id price 
35083 34 85376  211 5.95 
56157 41 85376  211 6.00 
63628 50 85376  211 5.95 
64955 51 85376  211 6.00 
66386 56 85376  211 6.00 
69477 69 85376  211 5.95 

この例では(価格はこのグループの最後の観測と同じであるため)、私は日がドロップさ56に等しい観察したいと思います。私のコードは:

def removeSameLast(df): 

    shp = df.shape[0] 
    lead = df['price'][1:shp] 
    lag = df['price'][:shp-1] 
    diff = np.array(lead != lag) 

    boo = np.array(1) 
    boo = np.append(boo,diff) 
    boo = boo.astype(bool) 

    df = df.loc[boo] 

    return df 

gCell = prices.groupby(['item_id', 'store_id']) 
prices = gCell.apply(removeSameLast) 

これは仕事ですが、醜いですし、遅いです。申し訳ありませんが、私はこれがずっと速くできると思います。誰かが解決策を提案できますか?事前に多くの感謝。

答えて

1

パンダのshift機能を使用して簡単な解決方法をお勧めします。これにより、groupbyと関数呼び出しの使用が削除されます。

[5.95, 6, 5.95, 6, 6, 5.95]シリーズがシフトされたものと等しいところを確認し、[nan, 5.95, 6, 5.95, 6, 6]を参照して、この条件が発生する行を削除します(または選択しないでください)。

>>> mask = ~np.isclose(prices['price'], prices['price'].shift()) 
>>> prices[mask] 
     day item_id store_id price 
35083 34 85376  211 5.95 
56157 41 85376  211 6.00 
63628 50 85376  211 5.95 
64955 51 85376  211 6.00 
69477 69 85376  211 5.95 

シンプルなベンチマーク:

%timeit prices = gCell.apply(removeSameLast) 
100 loops, best of 3: 4.46 ms per loop 

%timeit mask = df.price != df.price.shift() 
1000 loops, best of 3: 183 µs per loop 
+0

ではなく、より良いかもしれないnp.isclose使い、==用いた二重/フロートを比較することは悪い考えですか=!。 – PhilChang

+0

私はマスクの作成を 'mask =〜np.isclose(prices ['price']、prices ['price']。shift())' –

関連する問題