2016-11-30 4 views
0

ループ内の複数の列でデータフレーム条件をマスクしたいとします。私はこのような何かをしようとしています:複数の列条件でのDataFrameのマスキング - ループ内

dfs = [] 
val_dict = {0: 'a', 1: 'b', 2: 'c', 3: 'd'} 
for i in range(4): 
    items = [val_dict[i] for i in range(i+1)] 
    df_ = df[(df['0'] == items[0]) & (df['1'] == items[1]) & ... ] 
    dfs.append(df_) 

は何の項目[1]の要素はないだろうので、私は上記に書いた第2の条件は、ループの最初の反復のために存在しませんのでご注意ください。ここで

は、あなたがテストすることが歓迎されているサンプルデータフレームです:

df = pd.DataFrame({'0': ['a']*3 + ['b']*3 + ['c']*3, 
        '1': ['a']*3 + ['b']*6, 
        '2': ['b']*4 + ['c']*5, 
        '3': ['c']*5 + ['d']*4}) 

私は避けるために非常に多くのことを伝えたい用途evalが出ている唯一のソリューション。

答えて

0

あなたはだけが比較に使用する列(あなたはあなたの例で行ったように)とあなたのval_dictのキーを含めるようにデータフレームのサブセット場合は、その後、比較したい列と同じですあなたのためにパンダにこれをさせることができます。それは対処していても

私は私の最初の溶液を残しています 次

dfs = [] 
val_dict = {0: 'a', 1: 'b', 2: 'c', 3: 'd'} 
val_series = pd.Series(val_dict) 

for i in range(4): 
    mask = (df == val_series).all(axis=1) 
    dfs.append(df[mask]) 

EDITで何をしたいあなたは今達成することができ、あなたのdf

df = pd.DataFrame({0: ['a']*3 + ['b']*3 + ['c']*3, 
        1: ['a']*3 + ['d']*6, 
        2: ['b']*4 + ['c']*5, 
        3: ['c']*5 + ['a']*4}) 

に若干の修正を作ります解決しようとするOPとは異なる問題。意図した問題は、次のことによって解決することができます。

mask = True 
for key in range(4): 
    mask &= df[key] == val_dict[key] 
    dfs.append(df[mask]) 

を繰り返しますが、これは私のオリジナルの答えに、以前使用される変性dfを使用しています。

+0

おかげで、これは私が達成しようとしています何をしません。私は 'DFをマスクアイデア最初のループではdf [(df ['0'] == items [0])&(df ['1'] == items)[[df ['0'] == items [0] [df ['0'] == items [0])&(df ['1'] == items [1])&(df ['2']) == items [2])] '第3回など...あなたのループは内部に依存関係がないので、毎回同じことをします! – AlexG

+0

申し訳ありませんが、私はあなたが行っていたことをかなり理解していませんでした。 – JaminSore

+0

Brilliant!ここで重要なのは、マスクがSeriesオブジェクトであることを覚えておき、それを保持する変数を定義することです – AlexG

0

私はevalソリューションを提供します。

for i in range(4): 
    items = [val_dict[i] for i in range(i+1)] 
    df_ = eval('df[(' + ') & ('.join(['df["'+str(j)+'"] == items['+str(j)+']' for j in range(i+1)]) + ')]') 
    dfs.append(df_) 

それは動作します...しかし、私の問題に行く@JaminSoreを与えるので、醜い:(