2016-11-30 26 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_) 

它的工作原理......但这么丑:(