给出以下熊猫数据框:
| a b
--+-----
0 | 1 A
1 | 2 A
2 | 3 A
3 | 4 A
4 | 1 B
5 | 2 B
6 | 3 B
7 | 1 C
8 | 3 C
9 | 4 C
如果按列b
对其进行分组,我想执行一个操作,该操作仅使它们具有列a
的行保持相同。结果将是以下数据帧:
| a b
--+-----
0 | 1 A
2 | 3 A
4 | 1 B
6 | 3 B
7 | 1 C
8 | 3 C
是否有一些内置方法可以做到这一点?
答案 0 :(得分:6)
您可以在此处尝试将pivot_table
与dropna
一起使用,然后使用sreries.isin
进行过滤:
s = df.pivot_table(index='a',columns='b',aggfunc=len).dropna().index
df[df['a'].isin(s)]
与crosstab
类似:
s = pd.crosstab(df['a'],df['b'])
df[df['a'].isin(s[s.all(axis=1)].index)]
a b
0 1 A
2 3 A
4 1 B
6 3 B
7 1 C
8 3 C
答案 1 :(得分:3)
尝试:
df2=df.groupby("a")["b"].nunique().eq(len(df.groupby("b").groups))
df=df.merge(df2.loc[df2].rename("filter"), on="a").drop("filter", axis=1)
输出:
a b
0 1 A
1 1 B
2 1 C
3 3 A
4 3 B
5 3 C
答案 2 :(得分:3)
一个使用transform
和groupby
并带有布尔过滤和dropna
的衬里
df[df.groupby(['a'])['b'].transform(len).eq(df['b'].nunique())].dropna(how='all')
print(df)
a b
0 1 A
2 3 A
4 1 B
6 3 B
7 1 C
8 3 C
答案 3 :(得分:1)
您可以找到所有组之间的交集并将其用于过滤:
from functools import reduce
intersect = reduce(np.intersect1d, df.groupby('b')['a'].apply(list))
df.loc[df['a'].isin(intersect), :]
输出:
a b
0 1 A
2 3 A
4 1 B
6 3 B
7 1 C
8 3 C
答案 4 :(得分:0)
假设没有与a和b相同的条目,应该这样做
FormResponse.submit()