Pandas中仅当Vehicle列值为空时删除Name列重复项
解决方法:仅删除对应Vehicle为空的Name重复项
嘿,这个需求我刚好处理过,咱们一步步来搞定它!你的核心诉求是:只删除那些对应Vehicle为空的重复Name行——具体来说就是:
- 所有Vehicle列有值的行,不管Name重不重复都必须保留
- 如果某个Name既有Vehicle有值的行,又有Vehicle为空的行,那空的那些重复项要删掉
- 如果某个Name只有Vehicle为空的行(没有重复),那得把它留下来
先构造示例DataFrame
首先咱们先把你给出的数据转成可操作的DataFrame,顺便把空字符串转成NaN方便后续判断:
import pandas as pd data = { 'Name': ['Dave', 'Mark', 'Steve', 'Dave', 'Steve'], 'Vehicle': ['Car', 'Bike', 'Car', '', ''] } df = pd.DataFrame(data) # 将空字符串转为NaN,统一缺失值格式 df['Vehicle'] = df['Vehicle'].replace('', pd.NA)
方法一:拆分筛选后合并
这个方法逻辑直观,适合新手理解:
- 先把所有Vehicle非空的行单独拎出来(这部分必须全部保留)
- 找出所有已经有非空Vehicle记录的Name集合
- 在Vehicle为空的行里,只保留那些不在上面集合里的行(也就是这个Name没有非空Vehicle记录,必须保留它的空行)
- 把两部分结果合并,恢复原顺序
代码实现:
# 1. 提取Vehicle非空的所有行 non_empty_vehicle_rows = df[df['Vehicle'].notna()] # 2. 获取所有存在非空Vehicle的Name has_valid_vehicle_names = non_empty_vehicle_rows['Name'].unique() # 3. 筛选出Vehicle为空且Name不在有效集合里的行(即该Name没有非空Vehicle记录) empty_vehicle_keep_rows = df[df['Vehicle'].isna() & ~df['Name'].isin(has_valid_vehicle_names)] # 4. 合并结果并恢复原索引顺序 result_df = pd.concat([non_empty_vehicle_rows, empty_vehicle_keep_rows]).sort_index()
方法二:用GroupBy标记筛选(更简洁)
这个方法用groupby.transform给每行标记所属Name是否存在非空Vehicle,然后直接筛选:
# 给每行标记:对应的Name是否有至少一条非空Vehicle记录 df['has_non_empty_vehicle'] = df.groupby('Name')['Vehicle'].transform(lambda x: x.notna().any()) # 筛选条件:要么Vehicle非空,要么Vehicle为空但该Name没有非空Vehicle记录 result_df = df[(df['Vehicle'].notna()) | (~df['has_non_empty_vehicle'])]
最终结果
两种方法得到的结果一致,都是:
Name Vehicle 0 Dave Car 1 Mark Bike 2 Steve Car
完全符合需求:Dave和Steve的空Vehicle行被删除(因为他们有非空记录),Mark的行保留,要是有个单独的Name(比如Lily)只有空Vehicle行,也会被保留下来。
内容的提问来源于stack exchange,提问作者Nithin Nampoothiry
相关产品推荐
相关产品推荐

