有一个类似以下的数据框,它有一个不干净的列'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
答案 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()]