如何使用 pandas 查找特定列具有小数的行?
how find rows where a particular column has decimal numbers using pandas?
我正在使用 pandas 编写数据质量脚本,其中脚本将检查每一列的特定条件
目前我需要找出特定列中没有小数或实际数字的行。如果它是一个整数,我能够找到这些数字,但是我到目前为止看到的方法,即 isdigit() , isnumeric(), isdecimal()
等无法正确识别数字何时是十进制数。例如:2.5、0.1245 等
以下是一些示例代码和数据:
>>> df = pd.DataFrame([
[np.nan, 'foo', 0],
[1, '', 1],
[-1.387326, np.nan, 2],
[0.814772, ' baz', ' '],
["a", ' ', 4],
[" ", 'foo qux ', ' '],
], columns='A B C'.split(),dtype=str)
>>> df
A B C
0 NaN foo 0
1 1 1
2 -1.387326 NaN 2
3 0.814772 baz
4 a 4
5 foo qux
>>> df['A']
0 NaN
1 1
2 -1.387326
3 0.814772
4 a
5
Name: A, dtype: object
以下方法均无法识别十进制数
df['A'].fillna('').str.isdigit()
df['A'].fillna('').str.isnumeric()
df['A'].fillna('').str.isdecimal()
0 False
1 True
2 False
3 False
4 False
5 False
Name: A, dtype: bool
所以当我尝试以下操作时,我只得到 1 行
>>> df[df['A'].fillna('').str.isdecimal()]
A B C
1 1 1
注意:我正在使用 dtype=str
来获取没有 pandas interpreting/changing dtypes 值的数据。实际数据可能在 A 列中有空格,我将 trim 使用 replace() 来解决这个问题,我在这里保持代码简单,以免混淆。
使用to_numeric
with errors='coerce'
for non numeric to NaN
s and then test by Series.notna
:
print (pd.to_numeric(df['A'], errors='coerce').notna())
0 False
1 True
2 True
3 True
4 False
5 False
Name: A, dtype: bool
如果需要 return True
缺失值:
print (pd.to_numeric(df['A'], errors='coerce').notna() | df['A'].isna())
0 True
1 True
2 True
3 True
4 False
5 False
Name: A, dtype: bool
另一种具有自定义功能的解决方案:
def test_numeric(x):
try:
float(x)
return True
except Exception:
return False
print (df['A'].apply(test_numeric))
0 True
1 True
2 True
3 True
4 False
5 False
Name: A, dtype: bool
print (df['A'].fillna('').apply(test_numeric))
0 False
1 True
2 True
3 True
4 False
5 False
Name: A, dtype: bool
或者,如果你想保留字符串结构,你可以使用:
df['A'].str.contains('.')
0 False
1 True
2 False
3 False
4 False
5 False
在这种情况下,唯一的风险可能是您也用 .
来识别单词..这不是您的意愿
我正在使用 pandas 编写数据质量脚本,其中脚本将检查每一列的特定条件
目前我需要找出特定列中没有小数或实际数字的行。如果它是一个整数,我能够找到这些数字,但是我到目前为止看到的方法,即 isdigit() , isnumeric(), isdecimal()
等无法正确识别数字何时是十进制数。例如:2.5、0.1245 等
以下是一些示例代码和数据:
>>> df = pd.DataFrame([
[np.nan, 'foo', 0],
[1, '', 1],
[-1.387326, np.nan, 2],
[0.814772, ' baz', ' '],
["a", ' ', 4],
[" ", 'foo qux ', ' '],
], columns='A B C'.split(),dtype=str)
>>> df
A B C
0 NaN foo 0
1 1 1
2 -1.387326 NaN 2
3 0.814772 baz
4 a 4
5 foo qux
>>> df['A']
0 NaN
1 1
2 -1.387326
3 0.814772
4 a
5
Name: A, dtype: object
以下方法均无法识别十进制数
df['A'].fillna('').str.isdigit()
df['A'].fillna('').str.isnumeric()
df['A'].fillna('').str.isdecimal()
0 False
1 True
2 False
3 False
4 False
5 False
Name: A, dtype: bool
所以当我尝试以下操作时,我只得到 1 行
>>> df[df['A'].fillna('').str.isdecimal()]
A B C
1 1 1
注意:我正在使用 dtype=str
来获取没有 pandas interpreting/changing dtypes 值的数据。实际数据可能在 A 列中有空格,我将 trim 使用 replace() 来解决这个问题,我在这里保持代码简单,以免混淆。
使用to_numeric
with errors='coerce'
for non numeric to NaN
s and then test by Series.notna
:
print (pd.to_numeric(df['A'], errors='coerce').notna())
0 False
1 True
2 True
3 True
4 False
5 False
Name: A, dtype: bool
如果需要 return True
缺失值:
print (pd.to_numeric(df['A'], errors='coerce').notna() | df['A'].isna())
0 True
1 True
2 True
3 True
4 False
5 False
Name: A, dtype: bool
另一种具有自定义功能的解决方案:
def test_numeric(x):
try:
float(x)
return True
except Exception:
return False
print (df['A'].apply(test_numeric))
0 True
1 True
2 True
3 True
4 False
5 False
Name: A, dtype: bool
print (df['A'].fillna('').apply(test_numeric))
0 False
1 True
2 True
3 True
4 False
5 False
Name: A, dtype: bool
或者,如果你想保留字符串结构,你可以使用:
df['A'].str.contains('.')
0 False
1 True
2 False
3 False
4 False
5 False
在这种情况下,唯一的风险可能是您也用 .
来识别单词..这不是您的意愿