为何df.dtypes.isin传入字符串列表无法得到预期结果?
校验DataFrame数据类型是否属于指定子集的问题与解决方法
问题场景
要校验DataFrame所有列的数据类型是否属于指定的类型子集(比如仅允许int64和float64),最初尝试用字符串类型名传入isin方法,但结果完全不稳定,每次运行输出都不一样。
错误代码与异常现象
使用以下代码测试:
import pandas as pd df = pd.DataFrame({'A': [1., 2., 3.], 'B': [100, 101, 102], 'C': ['a', 'b', 'c']}) assert df.dtypes.A == 'float64' assert df.dtypes.B == 'int64' assert df.dtypes.C == 'object' print(df.dtypes.isin(['int64', 'float64']))
多次运行脚本的输出结果完全不一致:
(base) Mac-mini-2:stackoverflow username$ python pandas_dtypes_isin.py A False B False C False dtype: bool (base) Mac-mini-2:stackoverflow username$ python pandas_dtypes_isin.py A True B False C False dtype: bool (base) Mac-mini-2:stackoverflow username$ python pandas_dtypes_isin.py A True B True C False dtype: bool
原因分析
df.dtypes返回的是一个元素为numpy.dtype对象的Series,直接传入字符串类型名(如'int64')到isin方法中,本质是在做对象类型的匹配比较。字符串和dtype对象属于不同类型,这种跨类型匹配在pandas的某些版本中会出现不稳定的隐式转换,导致结果随机变化。
正确解法
需要传入numpy.dtype类型的对象到isin中,才能稳定匹配:
import pandas as pd import numpy as np df = pd.DataFrame({'A': [1., 2., 3.], 'B': [100, 101, 102], 'C': ['a', 'b', 'c']}) print(df.dtypes.isin([np.dtype('float64'), np.dtype('int64')]))
运行后会得到稳定的正确结果:
A True B True C False dtype: bool
注:已知
select_dtypes或is_numeric_dtype等方法可实现类似筛选,但本次需求仅针对isin方法的正确使用场景。
内容的提问来源于stack exchange,提问作者Bill
相关产品推荐
相关产品推荐

