使用pandas删除一列中的非数字行

时间:2015-11-27 15:59:36

标签: python pandas

有一个类似以下的数据框,它有一个不干净的列'id',它应该是数字列

id, name
1,  A
2,  B
3,  C
tt, D
4,  E
5,  F
de, G

是否有一种简洁的方法来删除行,因为tt和de不是数值

tt,D
de,G

使数据帧干净吗?

id, name
1,  A
2,  B
3,  C
4,  E
5,  F

5 个答案:

答案 0 :(得分:44)

使用pd.to_numeric

In [1079]: df[pd.to_numeric(df['id'], errors='coerce').notnull()]
Out[1079]:
  id  name
0  1     A
1  2     B
2  3     C
4  4     E
5  5     F

答案 1 :(得分:19)

您可以使用字符串isnumeric的标准方法,并将其应用于id列中的每个值:

import pandas as pd
from io import StringIO

data = """
id,name
1,A
2,B
3,C
tt,D
4,E
5,F
de,G
"""

df = pd.read_csv(StringIO(data))

In [55]: df
Out[55]: 
   id name
0   1    A
1   2    B
2   3    C
3  tt    D
4   4    E
5   5    F
6  de    G

In [56]: df[df.id.apply(lambda x: x.isnumeric())]
Out[56]: 
  id name
0  1    A
1  2    B
2  3    C
4  4    E
5  5    F

或者如果您想使用id作为索引,您可以这样做:

In [61]: df[df.id.apply(lambda x: x.isnumeric())].set_index('id')
Out[61]: 
   name
id     
1     A
2     B
3     C
4     E
5     F

编辑。添加时间

虽然pd.to_numeric未使用apply方法,但它比np.isnumeric列适用str慢几乎两倍。此外,我添加了使用pandas str.isnumeric的选项,这样可以减少输入,但仍然比使用pd.to_numeric更快。但是pd.to_numeric更通用,因为它可以适用于任何数据类型(不仅仅是字符串)。

df_big = pd.concat([df]*10000)

In [3]: df_big = pd.concat([df]*10000)

In [4]: df_big.shape
Out[4]: (70000, 2)

In [5]: %timeit df_big[df_big.id.apply(lambda x: x.isnumeric())]
15.3 ms ± 2.02 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [6]: %timeit df_big[df_big.id.str.isnumeric()]
20.3 ms ± 171 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [7]: %timeit df_big[pd.to_numeric(df_big['id'], errors='coerce').notnull()]
29.9 ms ± 682 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

答案 2 :(得分:5)

鉴于df是您的数据框,

import numpy as np
df[df['id'].apply(lambda x: isinstance(x, (int, np.int64)))]

它的作用是将id列中的每个值传递给isinstance函数,并检查它是否为int。然后它返回一个布尔数组,最后只返回有True的行。

如果您还需要考虑float值,则另一个选项是:

import numpy as np
df[df['id'].apply(lambda x: type(x) in [int, np.int64, float, np.float64])]

请注意,无论哪种方式都不在位,因此您需要将其重新分配给原始df,或者创建一个新方法:

df = df[df['id'].apply(lambda x: type(x) in [int, np.int64, float, np.float64])]
# or
new_df = df[df['id'].apply(lambda x: type(x) in [int, np.int64, float, np.float64])]

答案 3 :(得分:1)

x.isnumeric()的类型为True时,

x不会测试返回float

一种过滤掉可以转换为float的值的方法:

df[df['id'].apply(lambda x: is_float(x))]

def is_float(x):
    try:
        float(x)
    except ValueError:
        return False
    return True

答案 4 :(得分:0)

这个怎么样? .str访问器是我的最爱之一:)

import pandas as pd


df = pd.DataFrame(
    {
        'id':   {0: '1', 1: '2', 2: '3', 3: 'tt', 4: '4', 5: '5', 6: 'de'},
        'name': {0: 'A', 1: 'B', 2: 'C', 3: 'D',  4: 'E', 5: 'F', 6: 'G'}
    }
)

df_clean = df[df.id.str.isnumeric()]