我有一个熊猫df
,其中包含各个时间点的值。我对这些时间点和值进行分组。我希望过滤器输出,以便两个组在每个时间点都包含值。如果任何一个组在那个时间点都不包含值,我想删除该行。
使用下面的df
,在各个时间点都有Group A
和Group B
的值。但是,时间点3,4,6
仅包含Group A
或Group 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]]
我不能使用dropna
或drop_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]]
答案 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