Como determinar se uma coluna / variável é numérica ou não no Pandas / NumPy?

88

Existe uma maneira melhor de determinar se uma variável está Pandase / ou NumPyé numericou não?

Eu tenho um self definido dictionarycom dtypesas chaves e numeric/ notas valores.

user2808117
fonte
15
Você poderia verificar dtype.kind in 'biufc'.
Jaime
1
O comentário acima deste postado por Jaime, era mais simples que os abaixo e parece ter funcionado perfeitamente ...... obrigado
hfrog713

Respostas:

97

Em pandas 0.20.2você pode fazer:

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
dente de leão
fonte
Eu diria que esta é uma solução mais elegante. Obrigado
como - se
84

Você pode usar np.issubdtypepara verificar se o dtipo é um subtipo de np.number. Exemplos:

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

Isso funciona para dtypes de numpy, mas falha para tipos específicos de pandas como pd.Categorical, como observou Thomas . Se você estiver usando a is_numeric_dtypefunção categoricals de pandas, é uma alternativa melhor do 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: 
   A    B   C  D
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 várias colunas, você pode 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)

E para seleção, o pandas agora tem select_dtypes:

df.select_dtypes(include=[np.number])
Out: 
   A    B   C
0  1  1.0  1j
1  2  2.0  2j
2  3  3.0  3j
Ayhan
fonte
1
Isso não parece funcionar de forma confiável com DataFrames do pandas, uma vez que eles podem retornar categorias desconhecidas para numpy como "categoria". Numpy, em seguida, lança "TypeError: tipo de dados não compreendido"
Thomas
23

Com base na resposta de @jaime nos comentários, você precisa verificar .dtype.kinda coluna de interesse. Por exemplo;

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

NB O significado de biufc: bbool, iint (assinado), uunsigned int, ffloat, ccomplex. Consulte https://docs.scipy.org/doc/numpy/reference/generated/numpy.dtype.kind.html#numpy.dtype.kind

danodonovan
fonte
3
Aqui está a lista de todos os tipos de dtype [1]. As minúsculas usão para inteiros sem sinal; maiúsculas Ué para Unicode. [1]: docs.scipy.org/doc/numpy/reference/generated/…
cbarrick
7

Pandas tem select_dtypefunção. Você pode filtrar facilmente suas colunas em int64 e float64 assim:

df.select_dtypes(include=['int64','float64'])
Farshad Madani
fonte
4

Este é um método pseudo-interno para retornar apenas os dados do 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]: 
   A         B    C                   D
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]: 
   A         B
0  0 -0.667672
1  1  0.811300
2  2  2.020402
Jeff
fonte
Sim, eu estava tentando descobrir como eles fazem isso. Seria de se esperar que uma função IsNumeric interna fosse executada por coluna ... mas ainda não a encontrei no código
user2808117
Você pode aplicar isso por coluna, mas é muito mais fácil apenas verificar o tipo de d. em qualquer caso, as operações do pandas excluem as não numéricas quando necessário. O que você está tentando fazer?
Jeff
4

Que tal apenas verificar o tipo de um dos valores na coluna? Sempre tivemos algo assim:

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

Quando tento verificar os tipos de dados para as colunas no dataframe abaixo, eu os obtenho como 'objeto' e não como um tipo numérico que estou 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

Quando faço o seguinte, parece que me dá um resultado preciso:

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

retorna

True
Punit S
fonte
1

Apenas para adicionar a todas as outras respostas, também se pode usar df.info()para obter quais são os tipos de dados de cada coluna.

Beta
fonte
1

Você pode verificar se uma determinada coluna contém valores numéricos ou não usando dtypes

numerical_features = [feature for feature in train_df.columns if train_df[feature].dtypes != 'O']

Nota: "O" deve ser maiúsculo

Gokulakrishnan
fonte
0

Você também pode tentar:

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

Ele retorna uma lista de booleanos: Truese numérico, Falsese não.

Paulwasit
fonte