¿Cómo determinar si una columna / variable es numérica o no en Pandas / NumPy?

¿Hay una mejor manera de determinar si una variable en Pandas y / o NumPy es numeric o no?

Tengo un dictionary autodefinido con dtypes como claves y numeric / not como valores.

Puede usar np.issubdtype para verificar si el dtype es un subtipo de np.number . Ejemplos:

 np.issubdtype(arr.dtype, np.number) # where arr is a numpy array np.issubdtype(df['X'].dtype, np.number) # where df['X'] is a pandas Series 

Esto funciona para los dtypes de Numpy pero falla para los tipos específicos de pandas como pd.Categorical, como anotó Thomas. Si está utilizando las funciones categóricas is_numeric_dtype de pandas es una alternativa mejor que np.issubdtype.

 df = pd.DataFrame({'A': [1, 2, 3], 'B': [1.0, 2.0, 3.0], 'C': [1j, 2j, 3j], 'D': ['a', 'b', 'c']}) df Out: ABCD 0 1 1.0 1j a 1 2 2.0 2j b 2 3 3.0 3j c df.dtypes Out: A int64 B float64 C complex128 D object dtype: object 

 np.issubdtype(df['A'].dtype, np.number) Out: True np.issubdtype(df['B'].dtype, np.number) Out: True np.issubdtype(df['C'].dtype, np.number) Out: True np.issubdtype(df['D'].dtype, np.number) Out: False 

Para columnas múltiples puede usar np.vectorize:

 is_number = np.vectorize(lambda x: np.issubdtype(x, np.number)) is_number(df.dtypes) Out: array([ True, True, True, False], dtype=bool) 

Y para la selección, pandas ahora tiene select_dtypes :

 df.select_dtypes(include=[np.number]) Out: ABC 0 1 1.0 1j 1 2 2.0 2j 2 3 3.0 3j 

En pandas 0.20.2 puedes hacer:

 import pandas as pd from pandas.api.types import is_string_dtype from pandas.api.types import is_numeric_dtype df = pd.DataFrame({'A': ['a', 'b', 'c'], 'B': [1.0, 2.0, 3.0]}) is_string_dtype(df['A']) >>>> True is_numeric_dtype(df['B']) >>>> True 

Basado en la respuesta de @ jaime en los comentarios, debe revisar .dtype.kind para la columna de interés. Por ejemplo;

 >>> import pandas as pd >>> df = pd.DataFrame({'numeric': [1, 2, 3], 'not_numeric': ['A', 'B', 'C']}) >>> df['numeric'].dtype.kind in 'bifc' >>> True >>> df['not_numeric'].dtype.kind in 'bifc' >>> False 

NB bifc es b bool, i int, f float, c complex – No estoy seguro de lo que podría ser.

¿Qué tal si solo verificamos el tipo de uno de los valores en la columna? Siempre hemos tenido algo como esto:

 isinstance(x, (int, long, float, complex)) 

Cuando trato de verificar los tipos de datos para las columnas en el siguiente dataframe, los obtengo como ‘objeto’ y no como un tipo numérico que estoy esperando:

 df = pd.DataFrame(columns=('time', 'test1', 'test2')) for i in range(20): df.loc[i] = [datetime.now() - timedelta(hours=i*1000),i*10,i*100] df.dtypes time datetime64[ns] test1 object test2 object dtype: object 

Cuando hago lo siguiente, parece darme un resultado preciso:

 isinstance(df['test1'][len(df['test1'])-1], (int, long, float, complex)) 

devoluciones

 True 

Este es un método pseudointerno para devolver solo los datos de tipo numérico

 In [27]: df = DataFrame(dict(A = np.arange(3), B = np.random.randn(3), C = ['foo','bar','bah'], D = Timestamp('20130101'))) In [28]: df Out[28]: ABCD 0 0 -0.667672 foo 2013-01-01 00:00:00 1 1 0.811300 bar 2013-01-01 00:00:00 2 2 2.020402 bah 2013-01-01 00:00:00 In [29]: df.dtypes Out[29]: A int64 B float64 C object D datetime64[ns] dtype: object In [30]: df._get_numeric_data() Out[30]: AB 0 0 -0.667672 1 1 0.811300 2 2 2.020402 

Solo para agregar a todas las demás respuestas, también se puede usar df.info() para obtener el tipo de datos de cada columna.

También puedes probar:

 df_dtypes = np.array(df.dtypes) df_numericDtypes= [x.kind in 'bifc' for x in df_dtypes] 

Devuelve una lista de valores booleanos: True si es numérico, False si no.