python - Pandas:当组中的值包含相似值时从数据中删除组

标签 python pandas dataframe

df = pd.DataFrame({"name":["A", "A", "B" ,"B", "C", "C"],
                   "nickname":["X","Y","X","Z","Y", "Y"]})

如何按“名称”对 df 进行分组并删除那些仅包含“Y”的组? 就我而言,“C”应该被删除。

我正在使用下面的代码,但它不起作用:

df_new = df.groupby('name').filter(lambda x: all(x['nickname'] != 'Y'))

如果 Y 出现在具有其他昵称的任何其他“名称”中,则应保留该名称。请帮忙。

最佳答案

这里groupby不是必需的。您可以使用boolean indexing :

df = df[df['name'].isin(df.loc[df['nickname'].ne('Y'), 'name'].unique())]
print (df)
  name nickname
0    A        X
1    A        Y
2    B        X
3    B        Z

说明:

首先比较ne对于不相等的值:

print (df['nickname'].ne('Y'))
0     True
1    False
2     True
3     True
4    False
5    False
Name: nickname, dtype: bool

然后选择列name bu boolean mask:

print (df.loc[df['nickname'].ne('Y'), 'name'])
0    A
2    B
3    B
Name: name, dtype: object

为了获得更好的性能,请获取独特的值:

print(df.loc[df['nickname'].ne('Y'), 'name'].unique())
['A' 'B']

并按 isin 进行过滤最终面具:

print (df['name'].isin(df.loc[df['nickname'].ne('Y'), 'name'].unique()))
0     True
1     True
2     True
3     True
4    False
5    False
Name: name, dtype: bool

性能:

取决于行数、唯一组的数量和匹配值的数量 - 真实数据中的最佳测试:

np.random.seed(123)
N = 100000

df = pd.DataFrame({'name': np.random.randint(1000,size=N).astype(str),
                   'nickname':np.random.randint(200,size=N).astype(str)})
#print (df)

In [152]: %timeit df[df.nickname.ne('Y').groupby(df.name).transform('sum').astype(bool)]
27.6 ms ± 292 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [153]: %timeit df[~df.nickname.eq('Y').groupby(df.name).transform('all')]
27.3 ms ± 162 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [154]: %timeit df[df['name'].isin(df.loc[df['nickname'].ne('Y'), 'name'].unique())]
28.9 ms ± 189 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [155]: %timeit df[~df.assign(mask=df.nickname.eq('Y')).groupby('name').mask.transform('all')]
30.3 ms ± 469 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [156]: %timeit df[df.groupby('name')['nickname'].transform('unique').astype(str) !="['Y']"]
15.6 s ± 233 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [157]: %timeit df.groupby('name').filter(lambda x: any(x['nickname'] != 'Y'))
408 ms ± 29.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

关于python - Pandas:当组中的值包含相似值时从数据中删除组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53629720/

相关文章:

python - 如何不计算用户输入的重复项?

python - 命令错误 : You appear not to have the 'psql' program installed or on your path

Python Markdown : Markdown Inside HTML Blocks

python - Pandas:根据行中的多个条件向 DF 添加带有随机数的新列

python - 将包含字典的 Pandas 数据框行拆分为多行

scala - 如何将 DataFrame 模式写入 Scala 中的文件

python - 属性错误: module 'tensorflow' has no attribute 'init_scope' during train. py

python - 如何在 pandas loc API 中使用 *and*

python - 如何在 pandas 交叉表上运行 join

python - 清理 1677 年之前日期的不同日期格式时的 Pandas OutOfBoundsDatetime