在Pandas中基于字符串列表过滤行

50

我有一个大的时间序列数据框(称为df),前5条记录如下:

df

         stn     years_of_data  total_minutes avg_daily TOA_daily   K_daily
date                        
1900-01-14  AlberniElementary      4    5745    34.100  114.600 0.298
1900-01-14  AlberniWeather         6    7129    29.500  114.600 0.257
1900-01-14  Arbutus                8    11174   30.500  114.600 0.266
1900-01-14  Arrowview              7    10080   27.600  114.600 0.241
1900-01-14  Bayside                7    9745    33.800  114.600 0.295

目标:

我试图删除在'stn'列中存在以下列表中任何一个字符串的行。因此,我基本上是尝试过滤该数据集,以不包括包含以下任何字符串的行。

尝试:

remove_list = ['Arbutus','Bayside']

cleaned = df[df['stn'].str.contains('remove_list')]

返回值:

Out[78]:

stn years_of_data   total_minutes   avg_daily   TOA_daily   K_daily
date    

没有任何东西!

我尝试了几种引号、括号,甚至使用了一个 lambda 函数;虽然我还很新,很可能没有正确使用语法。

3个回答

85

使用isin函数:

cleaned = df[~df['stn'].isin(remove_list)]

In [7]:

remove_list = ['Arbutus','Bayside']
df[~df['stn'].isin(remove_list)]
Out[7]:
                          stn  years_of_data  total_minutes  avg_daily  \
date                                                                     
1900-01-14  AlberniElementary              4           5745       34.1   
1900-01-14     AlberniWeather              6           7129       29.5   
1900-01-14          Arrowview              7          10080       27.6   

            TOA_daily  K_daily  
date                            
1900-01-14      114.6    0.298  
1900-01-14      114.6    0.257  
1900-01-14      114.6    0.241  

还有其他的方法吗?使用lambda x: ...设置一些函数怎么样?我尝试的方法怎么样?我接近或者达到了我的目标吗?教我如何钓鱼,而不是只给我一条鲷鱼! :) - geokrowding

21

我有一个类似的问题,找到了这个旧帖子,我认为有其他方法可以获得相同的结果。对于我的特定应用程序,我对@EdChum的解决方案的问题是我没有一个完全匹配的列表。如果你有同样的问题,.isin并不适用于这种情况。

相反,你也可以尝试一些选项,包括numpy.where:

  removelist = ['ayside','rrowview']
  df['flagCol'] = numpy.where(df.stn.str.contains('|'.join(remove_list)),1,0)

请注意,此解决方案实际上并未删除匹配行,而只是将其标记。您可以根据需要进行复制/切片/删除。

如果您不知道车站名称是否大写,并且不想事先对文本进行标准化,则此解决方案将非常有用。numpy.where通常也很快,与.isin可能没有太大区别。


感谢 - 这还有一个额外的优点,就是可以处理子字符串。 - Realhermit

4

我只是想在这个非常重要的用例中补充我的2分钱(过滤由字符串值索引的项目列表)。 .isin() 方法的参数不需要是列表!它可以是一个 pd.Series!然后你可以做这样的事情:

df[~df['stn'].isin(another_df['stn_to_remove_column_there'])]

你明白我的意思吗?你可以使用这个结构而不需要使用.to_list()方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接