在pandas的数据框中查找非数字行?
我在pandas有一个很大的数据框,除了作为索引使用的列应该只有数值:
df = pd.DataFrame({'a': [1, 2, 3, 'bad', 5], 'b': [0.1, 0.2, 0.3, 0.4, 0.5], 'item': ['a', 'b', 'c', 'd', 'e']}) df = df.set_index('item')
我怎样才能find数据框df
中有一个非数字值的行?
在这个例子中,它是数据框中的第四行,在a
列中有string'bad'
。 如何可以通过编程find这一行?
您可以使用np.isreal
来检查每个元素的types( applymap将函数应用于DataFrame中的每个元素):
In [11]: df.applymap(np.isreal) Out[11]: ab item a True True b True True c True True d False True e True True
如果所有行都是True,那么它们都是数字:
In [12]: df.applymap(np.isreal).all(1) Out[12]: item a True b True c True d False e True dtype: bool
所以要得到rouges的子数据框,(注意:上面的否定,〜find至less有一个非法数字的那个):
In [13]: df[~df.applymap(np.isreal).all(1)] Out[13]: ab item d bad 0.4
你也可以find你可以使用argmin的第一个罪犯的位置:
In [14]: np.argmin(df.applymap(np.isreal).all(1)) Out[14]: 'd'
正如@CTZhu所指出的那样, 检查它是int还是float 的一个实例可能会稍微快一点 (在np.isreal中有一些额外的开销):
df.applymap(lambda x: isinstance(x, (int, float)))
对于混淆抱歉,这应该是正确的做法。 你只想捕捉'bad'
,而不是'good'
; 或者只是任何非数值?
In[15]: np.where(np.any(np.isnan(df.convert_objects(convert_numeric=True)), axis=1)) Out[15]: (array([3]),)
这个问题已经有一些很好的答案,但是这里有一个很好的代码片断,我经常用它来删除行,如果它们在某些列上有非数值的话:
# Eliminate invalid data from dataframe (see Example below for more context) numdf = (df.drop(data_columns, axis=1) .join(df[data_columns].apply(pd.to_numeric, errors='coerce'))) numdf = numdf[num_df[data_columns].notnull().all(axis=1)]
这样做的方式是我们首先从df
drop
所有的data_columns
,然后使用一个join
将它们传递给pd.to_numeric
(带有选项'coerce'
,使得所有非数字条目都被转换为NaN
)。 结果保存为numdf
。
在第二行,我们使用一个只保留所有值不为空的行的filter。
请注意, pd.to_numeric
强制转换为NaN
无法转换为数值的所有内容,因此表示数值的string将不会被删除。 例如'1.25'
将被识别为数值1.25
。
免责声明: pd.to_numeric
在pandas版本0.17.0
引入
例:
In [1]: import pandas as pd In [2]: df = pd.DataFrame({"item": ["a", "b", "c", "d", "e"], ...: "a": [1,2,3,"bad",5], ...: "b":[0.1,0.2,0.3,0.4,0.5]}) In [3]: df Out[3]: ab item 0 1 0.1 a 1 2 0.2 b 2 3 0.3 c 3 bad 0.4 d 4 5 0.5 e In [4]: data_columns = ['a', 'b'] In [5]: num_df = (df ...: .drop(data_columns, axis=1) ...: .join(df[data_columns].apply(pd.to_numeric, errors='coerce'))) In [6]: num_df Out[6]: item ab 0 a 1 0.1 1 b 2 0.2 2 c 3 0.3 3 d NaN 0.4 4 e 5 0.5 In [7]: num_df[num_df[data_columns].notnull().all(axis=1)] Out[7]: item ab 0 a 1 0.1 1 b 2 0.2 2 c 3 0.3 4 e 5 0.5
如果你正在使用string值的列,你可以使用非常有用的函数series.str.isnumeric(),如:
a = pd.Series(['hi','hola','2.31','288','312','1312', '0,21', '0.23'])
我所做的就是将该列复制到新列,然后执行str.replace('。','')和str.replace(',',''),然后select数字值。 和:
a = a.str.replace('.','') a = a.str.replace(',','') a.str.isnumeric()
Out [15]:0 False 1 False 2 True 3 True 4 True 5 True 6 True 7 True dtype:bool
祝你好运!