bugfix> python > 投稿

次のような消費者トランザクションのこの巨大なデータセット(1億行)があります。

df = pd.DataFrame({'id':[1, 1, 2, 2, 3],'brand':['a','b','a','a','c'], 'date': ['01-01-2020', '01-02-2020', '01-05-2019', '01-06-2019', '01-12-2018']})

各行(各トランザクション)について、同じ人(同じ「id」)が何かを購入したかどうかを確認したいと思います過去にはのために異なるブランド。結果のデータセットは次のようになります。

   id  brand  date        check
0   1   a      01-01-2020  0  
1   1   b      01-02-2020  1
2   2   a      01-05-2019  0
3   2   a      01-06-2019  0
4   3   c      01-12-2018  0

さて、私の解決策は次のとおりです。

def past_transaction(row):
    x = df[(df['id'] == row['id']) & (df['brand'] != row['brand']) & (df['date'] < row['date'])]
    if x.shape[0]>0:
        return 1
    else:
        return 0
df['check'] = df.appy(past_transaction, axis=1)

これはうまく機能しますが、パフォーマンスはひどいです。これを行うためのより効率的な方法はありますか(パンダの有無にかかわらず)?ありがとう!

回答 2 件
  • 私は個人的に2つのブール値を使用します。

    まず、 id 重複しています。 2番目はあるものをチェックすることですない重複したIDとブランド

    import numpy as np 
    s = df.duplicated(subset=['id'],keep='first')
    s1 = ~df.duplicated(subset=['id','brand'],keep=False)
    df['check'] = np.where(s & s1,1,0)
    
       id brand        date  check
    0   1     a  01-01-2020      0
    1   1     b  01-02-2020      1
    2   2     a  01-05-2019      0
    3   2     a  01-06-2019      0
    4   3     c  01-12-2018      0
    
    

  • A)パンダの組み込み関数を使用する

    最初のステップは、独自の機能を作成する代わりにパンダを利用することです。

    df['check'] = np.logical_and(df.id.duplicated(), ~df['id','brand'].duplicated())
    
    

    それはあなたのコードをすでに速くするでしょう!

    B)ハードウェアを活用する

    RAMで許可されている場合は、マシンにあるすべてのコアを利用するようにオプトインします。 modin.pandasまたはその代わりの方法を使用できます。変更が最小限で、マシンの構成に応じて指数関数的に高速化されるため、これをお勧めします

    C)ビッグデータフレームワーク

    ビッグデータの問題である場合、パンダはそのような大量のデータを処理することを意図していないため、ビッグデータを処理することを意図したdaskまたはsparkデータフレームをすでに利用しているはずです。

    同様の問題に対処しているときに私が効果的だと思ったいくつかのこと。

あなたの答え