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

l5tcr1uw  于 2023-03-28  发布在  其他
关注(0)|答案(8)|浏览(179)

有一个类似下面的 Dataframe ,它有一个不干净的列'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
scyqe7ek

scyqe7ek1#

使用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
f5emj3cl

f5emj3cl2#

你可以使用字符串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的case没有使用apply方法,但它比对str列应用np.isnumeric慢了近两倍。我还添加了使用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)
ojsjcaue

ojsjcaue3#

假设df是您的 Dataframe ,

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[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])]
unhi4e5o

unhi4e5o4#

x的类型为float时,x.isnumeric()不会测试返回值True
有一种方法可以过滤掉可以转换为float的值:
df[df['id'].apply(lambda x: is_float(x))]

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

zxlwwiss5#

这个怎么样?.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()]
  • 补充(2021-06-22)*

如果id包含某种令人头痛的数据类型(例如floatNonenan),您可以使用astype('str')将它们强制转换为str数据类型。

import numpy as np
import pandas as pd

df = pd.DataFrame(
    {
        'id':   {0: '1', 1: '2', 2: '3', 3: 3.14, 4: '4', 5: '5', 6: None, 7: np.nan},
        'name': {0: 'A', 1: 'B', 2: 'C', 3: 'D',  4: 'E', 5: 'F', 6: 'G',  7: 'H'}
    }
)

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

原始的,但它的工作无论如何。

lmyy7pcs

lmyy7pcs6#

这是一种动态的方法,它只适用于int64和float 64,如果你的dataframe中有其他数值数据类型,请确保将它们添加到if语句中。

# make dataframe of column data types
col_types = df.dtypes.to_frame()
col_types.columns = ['dtype']

#make list of zeros
drop_it = [0]*col_types.shape[0]
k = 0

#make it a one if the data isn't numeric
#if you have other numeric types you need to add them to if statement
for t in col_types.dtype:
    if t != 'int64' and t != 'float64':
        drop_it[k] = 1
    k = k + 1

#delete types from drop list that aren't numeric
col_types['drop_it'] = drop_it
col_types = col_types.loc[col_types["drop_it"] == 1]

#finally drop columns that are in drop list
for col_to_drop in col_types.index.values.tolist():
    df = df.drop([col_to_drop], axis = 1)
mctunoxg

mctunoxg7#

另一种方法是使用query方法:

In [5]: df.query('id.str.isnumeric()')
Out[5]: 
  id  name
0  1     A
1  2     B
2  3     C
4  4     E
5  5     F
lyr7nygr

lyr7nygr8#

系统对象处理异常:'无法访问已释放的对象。对象名称:'IServiceProvider'.'
尝试删除bin文件夹并重新构建它。这对我很有效。

相关问题