Groupby和drop NaN行,同时在Pandas中保留一行

2024-06-12 06:07:13 发布

您现在位置:Python中文网/ 问答频道 /正文

给定一个测试数据集,如下所示:

   id city   name
0   1   bj    NaN
1   2   bj   jack
2   3   bj    NaN
3   4   bj    jim
4   5   sh    NaN
5   6   sh    NaN
6   7   sh  steve
7   8   sh  fiona
8   9   sh    NaN

如何按city分组并删除nameNaN行,同时仅为每个group保留一行?非常感谢

预期结果如下:

   id city   name
0   1   bj    NaN
1   2   bj   jack
2   4   bj    jim
3   5   sh    NaN
4   7   sh  steve
5   8   sh  fiona

df = pd.read_clipboard(na_filter = False)从excel文件读取的新数据集,请注意N/A不应被视为NaN

      newcode build_name  floor  rent_id      rent_name
0  1210010403         C栋     25  1765228   (株)有延商店上海事务所
1  1210010403         C栋     25  1765229            N/A
2  1210010403         C栋     25  1765229            N/A
3  1210010403         C栋     25  1765229            N/A
4  1210010403         C栋     25  1765230  上海皇瑾文化传媒有限公司 
5  1210010403         C栋     25  1765229            N/A
6  1210010403         C栋     25  1765231     上海农邦实业有限公司
7  1210010403         C栋     25  1765232            N/A
8  1210010403         C栋     25  1765231   上海农NA邦实业有限公司

代码:df[df['rent_name'].ne('N/A') | ~df.duplicated(subset=['newcode', 'build_name', 'floor'])],与df[~(df['rent_name'].eq('N/A') & df.duplicated(subset = ['newcode', 'build_name', 'floor'], keep = 'first'))]的结果相同

输出:

      newcode build_name  floor  rent_id      rent_name
0  1210010403         C栋     25  1765228   (株)有延商店上海事务所
4  1210010403         C栋     25  1765230  上海皇瑾文化传媒有限公司 
6  1210010403         C栋     25  1765231     上海农邦实业有限公司
8  1210010403         C栋     25  1765231   上海农NA邦实业有限公司

您可以看到结果中缺少一行,我不知道为什么

期望输出:

      newcode build_name  floor  rent_id      rent_name
0  1210010403         C栋     25  1765228   (株)有延商店上海事务所
1  1210010403         C栋     25  1765229            N/A
4  1210010403         C栋     25  1765230  上海皇瑾文化传媒有限公司 
6  1210010403         C栋     25  1765231     上海农邦实业有限公司
8  1210010403         C栋     25  1765231   上海农NA邦实业有限公司

Tags: namebuildidcitydfshnan商店
2条回答

每个city测试的链条件不缺少值或第一个重复值,名称:

df = df[df['name'].notna() | ~df.duplicated(subset=['city', 'name'])]
print(df)
   id city   name
0   1   bj    NaN
1   2   bj   jack
3   4   bj    jim
4   5   sh    NaN
6   7   sh  steve
7   8   sh  fiona

编辑:对于测试字符串N/A,请使用^{}

df = df[df['name'].ne('N/A') | ~df.duplicated(subset=['city', 'name'])]
print(df)
   id city   name
0   1   bj    N/A
1   2   bj   jack
3   4   bj    jim
4   5   sh    N/A
6   7   sh  steve
7   8   sh  fiona

如果要测试多个值,请使用带反转掩码的^{}

df = df[~df['name'].isin(['N/N','N/A']) | ~df.duplicated(subset=['city', 'name'])]
print(df)

   id city   name
0   1   bj    N/A
1   2   bj   jack
3   4   bj    jim
4   5   sh    N/A
6   7   sh  steve
7   8   sh  fiona

编辑:

df = df[df['name'].notna() | ~df.duplicated(subset=['city', 'name'])]
print(df)
   id city   name
0   1   bj    NaN
1   2   bj   jack
3   4   bj    jim
4   5   sh    NaN
6   7   sh  steve
7   8   sh  fiona
9  10   gz    NaN

EDIT1:对于重复测试,需要添加带有NaN的列,此处rent_name

df =  df[df['rent_name'].ne('N/A') | 
         ~df.duplicated(subset=['newcode', 'build_name', 'floor', 'rent_name'])]
print (df)
    
      newcode build_name  floor  rent_id     rent_name
0  1210010403         C栋     25  1765228  (株)有延商店上海事务所
1  1210010403         C栋     25  1765229           N/A
4  1210010403         C栋     25  1765230  上海皇瑾文化传媒有限公司
6  1210010403         C栋     25  1765231    上海农邦实业有限公司
8  1210010403         C栋     25  1765231  上海农NA邦实业有限公司

布尔选择NaNs,删除namecity中的最后一个重复项

df[~(df.name.isna() & df.duplicated(subset = ['city', 'name'], keep = 'first'))]

    id city   name
0   1   bj    NaN
1   2   bj   jack
3   4   bj    jim
4   5   sh    NaN
6   7   sh  steve
7   8   sh  fiona

相关问题 更多 >