Comment déterminer si une colonne / variable est numérique ou non dans Pandas / NumPy?

88

Existe-t-il une meilleure façon de déterminer si une variable est dans Pandaset / ou NumPyest numericou non?

J'ai un moi défini dictionaryavec dtypescomme clés et numeric/ notcomme valeurs.

user2808117
la source
15
Vous pourriez vérifier dtype.kind in 'biufc'.
Jaime
1
Le commentaire au-dessus de celui-ci posté par Jaime, était plus simple que ceux ci-dessous et semble avoir parfaitement fonctionné ...... merci
hfrog713

Réponses:

97

En pandas 0.20.2vous pouvez faire:

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
danthelion
la source
Je dirais que c'est une solution plus élégante. Merci
comme - si le
84

Vous pouvez utiliser np.issubdtypepour vérifier si le dtype est un sous-type de np.number. Exemples:

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

Cela fonctionne pour les dtypes de numpy mais échoue pour les types spécifiques aux pandas comme pd.Catégorique comme l'a noté Thomas . Si vous utilisez la is_numeric_dtypefonction catégorielle de pandas, c'est une meilleure alternative 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

Pour plusieurs colonnes, vous pouvez utiliser 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)

Et pour la sélection, les pandas ont maintenant 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
la source
1
Cela ne semble pas fonctionner de manière fiable avec les pandas DataFrames, car ceux-ci peuvent renvoyer des catégories inconnues à numpy comme "category". Numpy lance alors "TypeError: type de données non compris"
Thomas
23

Sur la base de la réponse de @ jaime dans les commentaires, vous devez vérifier .dtype.kindla colonne qui vous intéresse. Par exemple;

>>> 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 La signification de biufc: bbool, iint (signé), uunsigned int, ffloat, ccomplex. Voir https://docs.scipy.org/doc/numpy/reference/generated/numpy.dtype.kind.html#numpy.dtype.kind

danodonovan
la source
3
Voici la liste de tous les types de dtype [1]. Les minuscules ucorrespondent aux nombres entiers non signés; les majuscules Usont pour unicode. [1]: docs.scipy.org/doc/numpy/reference/generated/…
cbarrick
7

Pandas a une select_dtypefonction. Vous pouvez facilement filtrer vos colonnes sur int64 et float64 comme ceci:

df.select_dtypes(include=['int64','float64'])
farshad madani
la source
4

Il s'agit d'une méthode pseudo-interne pour renvoyer uniquement les données de type numérique

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
la source
Oui, j'essayais de comprendre comment font-ils cela. On s'attendrait à ce qu'une fonction IsNumeric interne s'exécute par colonne ... mais ne l'a toujours pas trouvée dans le code
user2808117
Vous pouvez l'appliquer par colonne, mais il est beaucoup plus simple de vérifier simplement le dtype. dans tous les cas, les opérations pandas excluent les opérations non numériques si nécessaire. Qu'essayez-vous de faire?
Jeff
4

Que diriez-vous de vérifier simplement le type de l'une des valeurs de la colonne? Nous avons toujours eu quelque chose comme ça:

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

Lorsque j'essaie de vérifier les types de données pour les colonnes dans le cadre de données ci-dessous, je les reçois en tant qu'objet et non en tant que type numérique que j'attends:

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

Lorsque je fais ce qui suit, cela semble me donner un résultat précis:

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

Retour

True
Punit S
la source
1

Juste pour ajouter à toutes les autres réponses, on peut également utiliser df.info()pour obtenir quel est le type de données de chaque colonne.

Bêta
la source
1

Vous pouvez vérifier si une colonne donnée contient des valeurs numériques ou non en utilisant des dtypes

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

Remarque: "O" doit être une majuscule

Gokulakrishnan
la source
0

Vous pouvez également essayer:

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

Il renvoie une liste de booléens: Truesi numérique, Falsesinon.

paulwasit
la source