使用Pandas从Dataframe的两列中过滤非数字数据

我正在加载一个有很多数据types(从Excel加载)的Pandas数据框。 两个特定的列应该是浮动的,但偶尔一个研究人员随机发表评论,如“未测量”。 我需要删除任何两列之一的值不是数字的行,并在其他列中保留非数字数据。 一个简单的用例看起来像这样(真正的表有几千行…)

import pandas as pd df = pd.DataFrame(dict(A = pd.Series([1,2,3,4,5]), B = pd.Series([96,33,45,'',8]), C = pd.Series([12,'Not measured',15,66,42]), D = pd.Series(['apples', 'oranges', 'peaches', 'plums', 'pears']))) 

结果在这个数据表中:

  ABCD 0 1 96 12 apples 1 2 33 Not measured oranges 2 3 45 15 peaches 3 4 66 plums 4 5 8 42 pears 

我不清楚如何到达这个表格:

  ABCD 0 1 96 12 apples 2 3 45 15 peaches 4 5 8 42 pears 

我尝试了dropna,但types是“对象”,因为有非数字条目。 我不能将这些值转换为浮点数,而不是转换整个表,或者一次执行一个系列,而这个系列与这个行中的其他数据失去了关系。 也许有一些简单的我不理解?

您可以先创build列BC子集并apply to_numeric ,检查all值是否为notnull 。 然后使用布尔索引 :

 print df[['B','C']].apply(pd.to_numeric, errors='coerce').notnull().all(axis=1) 0 True 1 False 2 True 3 False 4 True dtype: bool print df[df[['B','C']].apply(pd.to_numeric, errors='coerce').notnull().all(axis=1)] ABCD 0 1 96 12 apples 2 3 45 15 peaches 4 5 8 42 pears 

下一个解决scheme使用str.isdigitisnull和异或( ^ ):

 print df['B'].str.isdigit().isnull() ^ df['C'].str.isdigit().notnull() 0 True 1 False 2 True 3 False 4 True dtype: bool print df[df['B'].str.isdigit().isnull() ^ df['C'].str.isdigit().notnull()] ABCD 0 1 96 12 apples 2 3 45 15 peaches 4 5 8 42 pears 

但与isnullnotnull解决scheme是最快的:

 print df[pd.to_numeric(df['B'], errors='coerce').notnull() ^ pd.to_numeric(df['C'], errors='coerce').isnull()] ABCD 0 1 96 12 apples 2 3 45 15 peaches 4 5 8 42 pears 

时间

 #len(df) = 5k df = pd.concat([df]*1000).reset_index(drop=True) In [611]: %timeit df[pd.to_numeric(df['B'], errors='coerce').notnull() ^ pd.to_numeric(df['C'], errors='coerce').isnull()] 1000 loops, best of 3: 1.88 ms per loop In [612]: %timeit df[df['B'].str.isdigit().isnull() ^ df['C'].str.isdigit().notnull()] 100 loops, best of 3: 16.1 ms per loop In [613]: %timeit df[df[['B','C']].apply(pd.to_numeric, errors='coerce').notnull().all(axis=1)] The slowest run took 4.28 times longer than the fastest. This could mean that an intermediate result is being cached 100 loops, best of 3: 3.49 ms per loop