如何仅在列具有所有指定值时提取id和行



我有以下数据帧

id  date     other variables..  
A   2019Q4      
A   2020Q4        
A   2021Q4 
B   2018Q4
B   2019Q4
B   2020Q4
B   2021Q4
C   2020Q4
C   2021Q4
D   2021Q4
E   2018Q4
E   2019Q4
E   2020Q4
E   2021Q4
.       .      

我想按id分组并保留这些id,如果它包含所有指定的值(即2019Q4, 2020Q4, 2021Q4),然后提取与这些值对应的行。isin()不会起作用,因为它不会降低C和d。

所需输出

A   2019Q4      
A   2020Q4        
A   2021Q4 
B   2019Q4
B   2020Q4
B   2021Q4
E   2019Q4
E   2020Q4
E   2021Q4
.       .      

您可以使用set操作来过滤日期的id和isin:

target = {'2019Q4', '2020Q4', '2021Q4'}
id_ok = df.groupby('id')['date'].agg(lambda x: target.issubset(x))
df2 = df[df['date'].isin(target) & df['id'].map(id_ok)]

或,使用transform:

target = {'2019Q4', '2020Q4', '2021Q4'}
mask = df.groupby('id')['date'].transform(lambda x: target.issubset(x))
df2 = df[df['date'].isin(target) & mask]

输出:

id    date  other
0   A  2019Q4    NaN
1   A  2020Q4    NaN
2   A  2021Q4    NaN
4   B  2019Q4    NaN
5   B  2020Q4    NaN
6   B  2021Q4    NaN
11  E  2019Q4    NaN
12  E  2020Q4    NaN
13  E  2021Q4    NaN

id_ok:

id
A     True
B     True
C    False
D    False
E     True
Name: date, dtype: bool

汇总每个ID的日期。然后只保留包含所有日期的id

ids = df.groupby("id")["date"].agg(set).apply(lambda x: x.issuperset({"2019Q4", "2020Q4", "2021Q4"}))
>>> df[df["id"].isin(ids.index.where(ids).dropna())&df["date"].isin(["2019Q4", "2020Q4", "2021Q4"])]
id    date
0   A  2019Q4
1   A  2020Q4
2   A  2021Q4
4   B  2019Q4
5   B  2020Q4
6   B  2021Q4
11  E  2019Q4
12  E  2020Q4
13  E  2021Q4

最新更新