过滤df,以便各组的值相等-熊猫

时间:2020-06-26 03:09:33

标签: python pandas

我有一个熊猫df,其中包含各个时间点的值。我对这些时间点和值进行分组。我希望过滤器输出,以便两个组在每个时间点都包含值。如果任何一个组在那个时间点都不包含值,我想删除该行。

使用下面的df,在各个时间点都有Group AGroup B的值。但是,时间点3,4,6仅包含Group AGroup B中的一项。如果每个组中至少没有两个项目,则我希望将这些行全部删除。

订购很重要,而不是总数。因此,如果在特定时间点Group缺少任何一项,我想删除这些行。

注意:在每个时间点,df每组最多只能包含一个值。但是我的实际数据可能包含很多。主要的问题是删除至少没有一组的行。

df1 = pd.DataFrame({   
        'Time' : [1,1,1,2,2,3,4,5,5,6],   
        'Group' : ['A','B','B','A','B','A','B','A','B','B'],                    
        'Val_A' : [6,7,4,5,4,4,9,6,7,8],  
        'Val_B' : [1,2,2,3,2,1,2,1,4,9],         
        'Val_C' : [1,2,2,3,4,5,7,8,9,7],                      
    }) 


Group_A = df1.loc[df1['Group'] == 'A']
Group_B = df1.loc[df1['Group'] == 'B']

Group_A = list(Group_A.groupby(['Time'])['Val_A'].apply(list))
Group_B = list(Group_B.groupby(['Time'])['Val_B'].apply(list))

print(df1)
print(Group_A)
print(Group_B) 

   Time Group  Val_A  Val_B  Val_C
0     1     A      6      1      1
1     1     B      7      2      2
2     1     B      4      2      2
3     2     A      5      3      3
4     2     B      4      2      4
5     3     A      4      1      5
6     4     B      9      2      7
7     5     A      6      1      8
8     5     B      7      4      9
9     6     B      8      9      7
[[6], [5], [4], [6]]
[[2, 2], [2], [2], [4], [9]]

我不能使用dropnadrop_duplicates。此外,数据可能包含Group B而非Group A的项目。因此,我希望找到一个可以处理两个实例的函数。

预期输出:

  Time Group  Val_A  Val_B  Val_C
0     1     A      6      1      1
1     1     B      7      2      2
2     1     B      4      2      2
3     2     A      5      3      3
4     2     B      4      2      4
7     5     A      6      1      8
8     5     B      7      4      9
[[6], [5], [6]]
[[2, 2], [2], [4]]

2 个答案:

答案 0 :(得分:2)

如果您不关心要删除的行,则可以选择每个组中的前n行,其中n是任何组中行数最少的行:

df1.groupby('Group').head(df1.groupby('Group')['Val_A'].count().min())

或者,如果您只希望每个组中具有“时间”值的行,则可以执行以下操作:

df1.groupby('Time').filter(lambda x: len(x['Val_A']) > 1)

或者,如果您要检查每个时间点是否都有每个组(例如A和B),并且它们在该时间点仅出现一次

df1.groupby('Time').filter(lambda x: {'A','B'} == set(x['Group']) and len(x) == 2) 

答案 1 :(得分:1)

将“时间”作为每个分组和“ set()”进行分组以进行单个比较。有条件地提取比较结果。这符合您的意图吗?

mask = list(set(Group_A['Time'])^set(Group_B['Time']))
df1[~(df1['Time'].isin(mask))]
    Time    Group   Val_A   Val_B   Val_C
0   1   A   6   1   1
1   1   B   7   2   2
2   1   B   4   2   2
3   2   A   5   3   3
4   2   B   4   2   4
7   5   A   6   1   8
8   5   B   7   4   9
相关问题