[python] 요소 개수가 1이 아닌 그룹에서 DataFrame 필터링

다음 구조의 DataFrame으로 작업하고 있습니다.

import pandas as pd

df = pd.DataFrame({'group':[1,1,1,2,2,2,2,3,3,3],
                   'brand':['A','B','X','C','D','X','X','E','F','X']})

print(df)

   group brand
0      1     A
1      1     B
2      1     X
3      2     C
4      2     D
5      2     X
6      2     X
7      3     E
8      3     F
9      3     X

내 목표는 정확히 하나의 브랜드가 X연결된 그룹 만 보는 것입니다. 그룹 번호 2에는 brand X와 동일한 두 개의 관측치 가 있으므로 결과 DataFrame에서 필터링해야합니다.

출력은 다음과 같아야합니다.

   group brand
0      1     A
1      1     B
2      1     X
3      3     E
4      3     F
5      3     X

groupby그룹 열에서 작업을 수행 한 다음 X1이 아닌 다른 그룹을 필터링 해야한다는 것을 알고 있습니다 . 필터링 부분은 내가 어려움을 겪는 곳입니다. 도움을 주시면 감사하겠습니다.



답변

이 같은지 series.eq확인한 다음 count가 1 인 그룹 별 및 필터 그룹 을 확인하는 데 사용 합니다 .brandXtransform sumX

df[df['brand'].eq('X').groupby(df['group']).transform('sum').eq(1)]

   group brand
0      1     A
1      1     B
2      1     X
7      3     E
8      3     F
9      3     X


답변

이것은 잘 작동합니다

df[df.groupby(['group'])['brand'].transform('sum').str.count('X').eq(1)]

산출

 group  brand
0   1   A
1   1   B
2   1   X
7   3   E
8   3   F
9   3   X


답변

'X'별로 그룹화하고 1과 동일한 그룹 의 문자 수에 대한 간단한 필터를 적용하십시오.

df.groupby('group').filter(lambda x: x['brand'].str.count('X').sum() == 1)

산출

   group brand
0      1     A
1      1     B
2      1     X
7      3     E
8      3     F
9      3     X


답변

솔루션 pd.crosstab

df[df['group'].map(pd.crosstab(df['group'],df['brand'])['X'].eq(1))]

#   group brand
#0      1     A
#1      1     B
#2      1     X
#7      3     E
#8      3     F
#9      3     X

우리는 또한 DataFrame.merge함께 사용할 수 있습니다Series.drop_duplicates

df.merge(df.loc[df.brand.eq('X'),'group'].drop_duplicates(keep = False),on='group')
#   group brand
#0      1     A
#1      1     B
#2      1     X
#3      3     E
#4      3     F
#5      3     X


답변