Come determinare se una colonna / variabile è numerica o meno in Pandas / NumPy?


91

C'è un modo migliore per determinare se una variabile è in Pandase / o NumPyè numerico no?

Ho un auto definito dictionarycon dtypescome chiavi e numeric/ notcome valori.


16
Potresti controllare dtype.kind in 'biufc'.
Jaime

1
Il commento sopra questo postato da Jaime, è stato più semplice di quelli sotto e sembra aver funzionato perfettamente ...... grazie
hfrog713

Risposte:


102

In pandas 0.20.2puoi fare:

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

Direi che questa è una soluzione più elegante. Grazie
come - se il

85

È possibile utilizzare np.issubdtypeper verificare se il dtype è un sub dtype di np.number. Esempi:

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

Questo funziona per i dtypes di numpy ma fallisce per i tipi specifici di panda come pd.Categorical come ha notato Thomas . Se stai usando la is_numeric_dtypefunzione categorici di Panda è un'alternativa migliore di 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

Per più colonne puoi usare 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 per la selezione, i panda ora hanno 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

1
Questo non sembra funzionare in modo affidabile con i DataFrame di panda, poiché potrebbero restituire categorie sconosciute a numpy come "categoria". Numpy lancia quindi "TypeError: tipo di dati non compreso"
Thomas

23

Sulla base della risposta di @ jaime nei commenti, è necessario verificare .dtype.kindla colonna di interesse. Per esempio;

>>> 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 Il significato di biufc: bbool, iint (signed), uunsigned int, ffloat, ccomplex. Vedi https://docs.scipy.org/doc/numpy/reference/generated/numpy.dtype.kind.html#numpy.dtype.kind


3
Ecco l'elenco di tutti i tipi di dtype [1]. Le lettere minuscole uindicano un numero intero senza segno; maiuscolo Uè per unicode. [1]: docs.scipy.org/doc/numpy/reference/generated/…
cbarrick

7

I panda hanno una select_dtypefunzione. Puoi facilmente filtrare le tue colonne su int64 e float64 in questo modo:

df.select_dtypes(include=['int64','float64'])

4

Questo è un metodo pseudo-interno per restituire solo i dati di tipo numerico

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

Sì, stavo cercando di capire come lo fanno. Ci si aspetterebbe che una funzione IsNumeric interna fosse eseguita per colonna ... ma ancora non l'ha trovata nel codice
user2808117

Puoi applicarlo per colonna, ma è molto più semplice controllare il dtype. in ogni caso le operazioni panda escludono le operazioni non numeriche quando necessario. Cosa stai cercando di fare?
Jeff

4

Che ne dici di controllare il tipo per uno dei valori nella colonna? Abbiamo sempre avuto qualcosa di simile:

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

Quando provo a controllare i tipi di dati per le colonne nel dataframe sottostante, li ottengo come 'oggetto' e non come un tipo numerico che mi aspetto:

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 eseguo le seguenti operazioni, sembra che mi fornisca un risultato accurato:

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

ritorna

True

1

Puoi anche provare:

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

Restituisce un elenco di Truevalori booleani: se numerico, in Falsecaso contrario.


1

Solo per aggiungere a tutte le altre risposte, si può anche usare df.info()per ottenere qual è il tipo di dati di ciascuna colonna.


1

È possibile verificare se una determinata colonna contiene valori numerici o meno utilizzando dtypes

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

Nota: "O" dovrebbe essere maiuscolo

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.