首页 > 解决方案 > 是否有一种有效的方法来检查列是否具有混合 dtypes?

问题描述

考虑

np.random.seed(0)
s1 = pd.Series([1, 2, 'a', 'b', [1, 2, 3]])
s2 = np.random.randn(len(s1))
s3 = np.random.choice(list('abcd'), len(s1))


df = pd.DataFrame({'A': s1, 'B': s2, 'C': s3})
df
           A         B  C
0          1  1.764052  a
1          2  0.400157  d
2          a  0.978738  c
3          b  2.240893  a
4  [1, 2, 3]  1.867558  a

列“A”具有混合数据类型。我想提出一种非常快速的方法来确定这一点。它不会像检查是否一样简单type == object,因为这会将“C”识别为误报。

我可以考虑这样做

df.applymap(type).nunique() > 1

A     True
B    False
C    False
dtype: bool

type但是在上面调用applymap很慢。特别是对于较大的框架。

%timeit df.applymap(type).nunique() > 1
3.95 ms ± 88 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

我们能做得更好吗(也许使用 NumPy)?如果你的论点足够有说服力,我可以接受“不”。:-)

标签: pythonpandasnumpydataframetypechecking

解决方案


在 pandas 中,infer_dtype()这里可能会有所帮助。

用 Cython 编写(代码链接),它返回一个字符串,总结了传递对象中的值。它在 pandas 的内部结构中被大量使用,因此我们可以合理地期望它的设计考虑到了效率。

>>> from pandas.api.types import infer_dtype

现在,A 列是整数和其他一些类型的混合:

>>> infer_dtype(df.A)
'mixed-integer'

B列的值都是浮动类型:

>>> infer_dtype(df.B)
'floating'

C 列包含字符串:

>>> infer_dtype(df.B)
'string'

混合值的一般“catchall”类型就是“mixed”:

>>> infer_dtype(['a string', pd.Timedelta(10)])
'mixed'

浮点数和整数的混合是 ''mixed-integer-float'':

>>> infer_dtype([3.141, 99])
'mixed-integer-float'

为了使您在问题中描述的功能,一种方法可能是创建一个捕获相关混合案例的功能:

def is_mixed(col):
    return infer_dtype(col) in ['mixed', 'mixed-integer']

然后你有:

>>> df.apply(is_mixed)
A     True
B    False
C    False
dtype: bool

推荐阅读