2016-11-30 24 views
0

我想在循環內的多列上屏蔽我的數據框。我試圖做這樣的事情:在多個列條件下屏蔽數據幀 - 在循環內

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]的元素。

這裏是一個樣本數據幀歡迎您來測試:

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只有你想用比較(如你在你的例子已經完成)列和鍵是一樣的,你要比較的列,那麼你可以讓熊貓爲你做這個。

製作一個輕微修改您的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}) 

現在可以完成你想要的由以下

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]) 

編輯 我離開我原來的解決方案,即使它解決了與OP意圖解決的問題不同。再次

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

,這是用我原來的答覆之前使用的改性df:預期的問題,可以通過以下來解決。

+0

謝謝你給我的問題去@JaminSore,但這並不做什麼,我試圖完成。我掩飾的想法'DF [(df ['0'] == items [0])]'for the first loop,'df [(df ['0'] == items [0])&(df ['1'] == items (df ['0'] == items [0])&(df ['1'] == items [1])&(df ['2']) ==項目[2])]'爲第三,等等...你的循環沒有我依賴裏面所以它每次都做同樣的事情 – AlexG

+0

對不起,我不完全明白你要去。編輯 – JaminSore

+0

精彩!這裏的關鍵洞察是記住面具是一個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_) 

它的工作原理......但這麼醜:(