如何删除Pandas DataFrame中指定列不含'PC'的行?
问题
我有如下Pandas DataFrame数据集:
<class 'pandas.core.frame.DataFrame'> RangeIndex: 513250 entries, 0 to 513249 Data columns (total 26 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Game Title 513196 non-null object 1 Game Poster 513196 non-null object 2 Game Release Date 513196 non-null object 3 Game Developer 512977 non-null object 4 Genre 513196 non-null object 5 Platforms 513250 non-null object 6 Product Rating 425527 non-null object 7 Overall Metascore 513181 non-null float64 8 Overall User Rating 513128 non-null object 9 Reviewer Name 512347 non-null object 10 Reviewer Type 513250 non-null object 11 Rating Given By The Reviewer 510449 non-null float64 12 Review Date 405044 non-null object 13 Review Text 512804 non-null object 14 0 513250 non-null object 15 1 513250 non-null object 16 2 513250 non-null object 17 3 513250 non-null object 18 4 513250 non-null object 19 5 513250 non-null object 20 6 513250 non-null object 21 7 513250 non-null object 22 8 513250 non-null object 23 9 513250 non-null object 24 10 513250 non-null bool 25 11 513250 non-null object dtypes: bool(1), float64(2), object(23) memory usage: 98.4+ MB
其中名为0到11的列(即DataFrame中索引14到25对应的列)里,部分行包含'PC'值,不含该值的列显示为"False"。我需要删除那些在这些指定列中**完全不含'PC'**的行,但尝试多种方法都没成功,包括:
方法1:
for index, row in df.iterrows(): if 'PC' not in row.values: df.drop(index, inplace=True)
方法2:
df = df[df['column'] == 'PC'] # Resetando os índices após a filtragem df.reset_index(drop=True, inplace=True)
方法3:
column_pc = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] df = df[df[colum_pc].apply(lambda row: 'PC' in row.values, axis=1)] df.reset_index(drop=True, inplace=True)
请问该如何正确实现需求?
解决方案
先说说你之前方法为啥不行:
- 方法1用
iterrows()遍历几十万行效率极低,而且row.values包含所有列的值,不是你要检查的0-11列,逻辑压根不对。 - 方法2里的
'column'是占位符,没指定实际列,而且只筛单列为'PC'的行,不符合“任意指定列含PC就保留”的需求。 - 方法3里变量名拼错了(
colum_pc少了个n),而且你要的是列名为0到11的列(不是DataFrame的第1到11列),另外列10是bool类型,直接判断会出错。
给你两个可行的写法,第二个更高效:
写法一(lambda遍历)
# 指定要检查的列名:0到11 pc_columns = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11'] # 遍历每行,检查是否有列的值等于'PC'(把bool转成字符串避免类型错误) df_filtered = df[df[pc_columns].apply(lambda row: any(str(val) == 'PC' for val in row), axis=1)] # 重置索引 df_filtered.reset_index(drop=True, inplace=True)
写法二(矢量化操作,推荐)
矢量化操作比lambda遍历快得多,适合几十万行的大数据集:
pc_columns = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11'] # 把所有列转成字符串,生成布尔矩阵(每个元素表示是否等于'PC'),再按行判断是否有True mask = df[pc_columns].astype(str).eq('PC').any(axis=1) # 过滤并重置索引 df_filtered = df[mask].reset_index(drop=True)
原理很简单:
astype(str)把所有列统一转成字符串,解决列10是bool类型的问题eq('PC')生成一个和原列同形状的布尔矩阵,True表示对应位置是'PC'any(axis=1)按行判断,只要该行有一个True就保留- 最后用这个布尔掩码过滤原DataFrame就行
内容的提问来源于stack exchange,提问作者Andre de Paula Galhardo
相关产品推荐
相关产品推荐

