2016-09-12 11 views
1

形状が〜(100000, 50)のpandasデータフレームを使用していますが、目的のデータフォーマットと操作を実現できますが、コードの実行に時間がかかります(3〜10分)含む、特定のタスクに応じて:値は、別のリストまたはnumpyの配列内に含まれるかどうかの確認データフレーム系列 パンダのデータを操作するためのForループの高速化

  • 内の各インスタンスに関数を適用する異なる列
    1. 組み合わせるストリング

    私は将来大きなデータフレームを持ち、非常に長い処理時間を避けるために適切なコーディング方法を使用したいと考えています。私は私のforループが最も長くかかることがわかります。リスト内包表記とシリーズ演算子(たとえばdf.loc[:,'C'] = df.A + df.B)を持つforループを回避しようとしますが、場合によってはネストされたforループでより複雑で複雑な操作を実行する必要があります。例えば、各list内の各アイテムを以下のデータフレームのシリーズhistory(一連のリスト)を反復処理し、続いて反復する:

    for row in DF.iterrows(): 
    
        removelist = [] 
    
        for i in xrange(0, len(row[1]['history'])-1): 
         if ((row[1]['history'][i]['title'] == row[1]['history'][i+1]['title']) & 
          (row[1]['history'][i]['dept'] == row[1]['history'][i+1]['dept']) & 
          (row[1]['history'][i]['office'] == row[1]['history'][i+1]['office']) & 
          (row[1]['history'][i]['employment'] == row[1]['history'][i+1]['employment'])): 
           removelist.append(i) 
    
        newlist = [v for i, v in enumerate(row[1]['history']) if i not in removelist] 
    

    私はそのリストの内包は、ネストされたforループを収容することができます知っているが、上記のように思われますリストの理解の中では本当に面倒です。

    私の質問:処理時間が短いforループと同じ機能を実現するために他にどのようなテクニックを使用できますか?リストを含むシリーズを反復処理するとき、ネストされたforループ以外の別のテクニックを使用する必要がありますか?

  • 答えて

    1

    ここでは、各行の履歴エントリに辞書のリストが含まれているデータフレームがありますか?同様に:

    import pandas as pd 
    john_history = [{'title': 'a', 'dept': 'cs'}, {'title': 'cj', 'dept': 'sales'}] 
    john_history 
    jill_history = [{'title': 'boss', 'dept': 'cs'}, {'title': 'boss', 'dept': 'cs'}, {'title': 'junior', 'dept': 'cs'}] 
    jill_history 
    df = pd.DataFrame({'history': [john_history, jill_history], 
        'firstname': ['john', 'jill']}) 
    

    あなたの構造の底部レベルでパンダの構造を使用するように、私は、例えば、あなたのデータを再構築でしょう各データフレームは、歴史あるデータフレームのdictの(私はパネルデータフレームの長さが異なることがあり、ここで働くとは思わない):

    people.groupby('name').apply(pd.DataFrame.drop_duplicates) 
    

    john_history = pd.DataFrame({'title': ['a', 'cj'], 'dept': ['cs', 'sales']}) 
    john_history['name'] = 'john' 
    jill_history = pd.DataFrame({'title': ['boss', 'boss', 'junior'], 'dept': ['cs', 'cs', 'cs']}) 
    jill_history['name'] = 'jill' 
    people = pd.concat([john_history, jill_history]) 
    

    あなたは、それらが同じようGROUPBY使用して処理することができます

    一般に、pandas/numpy内で必要な機能を見つけることができない場合は、pandasプリミティブを使用してデータフレームを反復するのではなく、作成する方が高速になることがわかります。

    df2 = df.shift() 
    

    今、あなたはデータフレームの内容を比較し、唯一異なると、使用されているものを維持することにより、選択範囲を作成することができます。たとえば最初の最初のものがシフトされ、新たなデータフレームを作成し、上記のロジックを再作成するには

    selection_array = (df.history == df2.history) & (df.title == df2.title) 
    unduplicated_consecutive = df[~selection_array] 
    print(unduplicated_consecutive) 
        history id title 
    0  a 1  x 
    1  b 2  y 
    # or in one line: 
    df[~((df.history == df2.history) & (df.title == df2.title))] 
    # or: 
    df[(df.history != df2.history) | (df.title != df2.title)] 
    

    だからGROUPBYにこれを置く: - いくつかのロジックごと取り外し、はい、しかし

    def drop_consecutive_duplicates(df): 
        df2 = df.shift() 
        return df.drop(df[(df.dept == df2.dept) & (df.title == df2.title)].index) 
    
    people.groupby('name').apply(drop_consecutive_duplicates) 
    
    +0

    は必ずしも重複を除去しないデータフレームをフィルタリングするためにその。リスト項目を含むデータフレームシリーズを素早く反復するためのコメントはありますか?以前のコメントありがとう。 – NickBraunagel

    +0

    行のフレームが必要で、各行に各列のリストが含まれていますか?私は代わりにパンダのデータ構造でこれを行う方法を示すために私の答えを修正しました。 – danio

    +0

    これはすばらしいです、答えのおかげで – NickBraunagel

    関連する問題