Skip to content

pandas : Cast DataFrame à un dtype spécifique avec astype()

pandas.Series a un dtype de type de données et pandas.DataFrame a un dtype de type de données différent pour chaque colonne.

Vous pouvez spécifier dtype lors de la création d’un nouvel objet avec un constructeur ou de la lecture à partir d’un fichier CSV, etc., ou le convertir avec la méthode astype().

Cet article décrit le contenu suivant.

  • Liste des types de données de base (dtype) dans les pandas
  • type d’objet et chaîne
    • Type de données spécial, objet
    • Remarque : Méthodes de chaîne
    • Noter:NaN
  • Caster le type de données (dtype) avec astype()
    • Type de données cast de pandas.Series
    • Caster le type de données de toutes les colonnes de pandas.DataFrame
    • Caster le type de données de n’importe quelle colonne de pandas.DataFrame individuellement
  • Spécifiez le type de données (dtype) lors de la lecture de fichiers CSV avec read_csv()
    • Spécifiez le même type de données pour toutes les colonnes
    • Spécifiez le type de données pour chaque colonne
  • Conversions de type implicites
    • Conversion de type implicite par opérations arithmétiques
    • Conversion de type implicite par transposition, etc.
    • Conversion de type implicite par affectation aux éléments

Consultez l’article suivant sur les types de données dtype et astype() dans NumPy.

Consultez l’article suivant sur la façon d’extraire des colonnes par dtype.

La version de pandas dans l’exemple de code suivant est 1.4.1. Notez que le comportement peut différer selon la version.

import pandas as pd
import numpy as np

print(pd.__version__)
# 1.4.1

Liste des types de données de base (dtype) dans les pandas

Voici une liste des types de données de base dtype dans pandas.

dtype code de caractère la description
vous8 i1 Entier signé 8 bits
int16 i2 Entier signé 16 bits
int32 i4 Entier signé 32 bits
int64 i8 Entier signé 64 bits
uint8 en 1 Entier non signé 8 bits
uint16 u2 Entier non signé 16 bits
uint32 u4 Entier non signé 32 bits
uint64 u8 Entier non signé 64 bits
float16 f2 Nombre à virgule flottante 16 bits
float32 f4 nombre à virgule flottante 32 bits
float64 f8 Nombre à virgule flottante 64 bits
float128 F 16 nombre à virgule flottante 128 bits
complexe64 c8 Nombre complexe à virgule flottante 64 bits
complexe128 c16 Nombre complexe à virgule flottante 128 bits
complexe256 c32 Nombre complexe à virgule flottante 256 bits
bourdonner ? Booléen (vrai ou faux)
unicode DANS Chaîne Unicode
objet O Objets Python

Les nombres de dtype sont en bit, et les nombres de code de caractère sont en octet. Notez que les nombres sont différents même pour le même type.

Le code de caractère pour le type bool, ?, ne signifie pas inconnu, mais littéralement ? est assigné.

Lorsque vous spécifiez le type de données dtype, par exemple, pour le type float64, l’un des éléments suivants est acceptable.

  • np.float64
  • ‘float64’
  • ‘f8’
s = pd.Series([0, 1, 2], dtype=np.float64)
print(s.dtype)
# float64

s = pd.Series([0, 1, 2], dtype='float64')
print(s.dtype)
# float64

s = pd.Series([0, 1, 2], dtype='f8')
print(s.dtype)
# float64

Vous pouvez les spécifier avec des types Python tels que int, float ou str sans nombres au bit près.

Dans ce cas, il est converti en dtype équivalent. Les exemples dans Python3, environnement 64 bits sont les suivants. L’uint n’est pas un type Python, mais est répertorié ensemble pour plus de commodité.

Type Python Exemple de dtype équivalent
entier int64
flotteur float64
chaîne objet (Chaque élément est str)
(uint) uint64

Vous pouvez utiliser int ou float ou string ‘int’, ‘float’. Vous ne pouvez pas utiliser uint car ce n’est pas un type Python.

s = pd.Series([0, 1, 2], dtype='float')
print(s.dtype)
# float64

s = pd.Series([0, 1, 2], dtype=float)
print(s.dtype)
# float64

s = pd.Series([0, 1, 2], dtype='uint')
print(s.dtype)
# uint64

Vous pouvez vérifier la plage de valeurs possibles (valeurs minimales et maximales) pour les types de nombres entiers et à virgule flottante avec np.iinfo() et np.finfo(). Pour plus de détails, consultez l’article suivant.

Les types de données introduits ici sont essentiellement basés sur NumPy, mais pandas a étendu certains de ses propres types de données.

type d’objet et chaîne

Cette section décrit le type d’objet et la chaîne str.

Notez que StringDtype a été introduit dans pandas version 1.0.0 en tant que type de données pour les chaînes. Ce type pourrait devenir courant à l’avenir, mais il n’est pas mentionné ici. Voir la documentation officielle pour plus de détails.

Type de données spécial, objet

Le type d’objet est un type de données spécial qui stocke des pointeurs vers des objets Python. Chaque élément peut avoir un type différent.

Dans pandas, le type de données des colonnes Series et DataFrame contenant des chaînes est un objet, mais chaque élément a son propre type et tous les éléments ne sont pas des chaînes.

Exemples:

Le np.nan représente la valeur manquante.

La fonction intégrée type() est appliquée avec la méthode map() pour vérifier le type de chaque élément.

s_object = pd.Series([0, 'abcde', np.nan])
print(s_object)
# 0        0
# 1    abcde
# 2      NaN
# dtype: object

print(s_object.map(type))
# 0      <class 'int'>
# 1      <class 'str'>
# 2    <class 'float'>
# dtype: object

Si str est spécifié dans astype() (voir ci-dessous pour plus de détails), tous les éléments, y compris NaN, sont convertis en str. dtype reste objet.

s_str_astype = s_object.astype(str)
print(s_str_astype)
# 0        0
# 1    abcde
# 2      nan
# dtype: object

print(s_str_astype.map(type))
# 0    <class 'str'>
# 1    <class 'str'>
# 2    <class 'str'>
# dtype: object

Si str est spécifié dans le paramètre dtype du constructeur, NaN reste flottant. Notez que NaN a également été converti en str dans la version 0.22.0.

s_str_constructor = pd.Series([0, 'abcde', np.nan], dtype=str)
print(s_str_constructor)
# 0        0
# 1    abcde
# 2      NaN
# dtype: object

print(s_str_constructor.map(type))
# 0      <class 'str'>
# 1      <class 'str'>
# 2    <class 'float'>
# dtype: object

Remarque : Méthodes de chaîne

Notez que même si le dtype est le même type d’objet, le résultat de la méthode string avec l’accesseur str est différent selon le type d’élément.

Par exemple, en appliquant str.len(), qui renvoie le nombre de caractères, un élément de type numérique renvoie NaN.

print(s_str_astype.str.len())
# 0    1
# 1    5
# 2    3
# dtype: int64

print(s_object.str.len())
# 0    NaN
# 1    5.0
# 2    NaN
# dtype: float64

Si le résultat de la méthode string contient NaN, chaque élément peut ne pas être str même si le type de données de la colonne est object. Vous pouvez appliquer astype(str) avant la méthode de chaîne.

print(s_object.astype(str).str.len())
# 0    1
# 1    5
# 2    3
# dtype: int64

Noter:NaN

Vous pouvez déterminer la valeur manquante NaN avec isnull() ou la supprimer avec dropna().

print(s_object)
# 0        0
# 1    abcde
# 2      NaN
# dtype: object

print(s_object.map(type))
# 0      <class 'int'>
# 1      <class 'str'>
# 2    <class 'float'>
# dtype: object

print(s_object.isnull())
# 0    False
# 1    False
# 2     True
# dtype: bool

print(s_object.dropna())
# 0        0
# 1    abcde
# dtype: object

Notez que s’il est converti en chaîne str, NaN devient la chaîne ‘nan’ et n’est pas traité comme une valeur manquante.

print(s_str_astype)
# 0        0
# 1    abcde
# 2      nan
# dtype: object

print(s_str_astype.map(type))
# 0    <class 'str'>
# 1    <class 'str'>
# 2    <class 'str'>
# dtype: object

print(s_str_astype.isnull())
# 0    False
# 1    False
# 2    False
# dtype: bool

print(s_str_astype.dropna())
# 0        0
# 1    abcde
# 2      nan
# dtype: object

Vous pouvez la traiter comme une valeur manquante avant le transtypage, ou remplacer la chaîne ‘nan’ par NaN en utilisant replace().

s_str_astype_nan = s_str_astype.replace('nan', np.nan)
print(s_str_astype_nan)
# 0        0
# 1    abcde
# 2      NaN
# dtype: object

print(s_str_astype_nan.map(type))
# 0      <class 'str'>
# 1      <class 'str'>
# 2    <class 'float'>
# dtype: object

print(s_str_astype_nan.isnull())
# 0    False
# 1    False
# 2     True
# dtype: bool

Caster le type de données (dtype) avec astype()

Vous pouvez convertir le type de données dtype avec la méthode astype() de pandas.DataFrame, pandas.Series.

astype() renvoie un nouveau pandas.Series ou pandas.DataFrame avec un nouveau dtype. L’objet d’origine n’est pas modifié.

Utilisez les données suivantes comme exemple.

df = pd.read_csv('data/src/sample_header.csv')
print(df)
#     a   b   c   d
# 0  11  12  13  14
# 1  21  22  23  24
# 2  31  32  33  34

s = df['c']
print(s)
# 0    13
# 1    23
# 2    33
# Name: c, dtype: int64

Type de données cast de pandas.Series

Si vous spécifiez le type de données dtype dans la méthode astype() de pandas.Series, un nouveau pandas.Series est renvoyé. Le pandas.Series d’origine reste inchangé.

s_f = s.astype('float64')
print(s_f)
# 0    13.0
# 1    23.0
# 2    33.0
# Name: c, dtype: float64

print(s)
# 0    13
# 1    23
# 2    33
# Name: c, dtype: int64

Comme mentionné ci-dessus, vous pouvez spécifier dtype sous différentes formes.

s_f = s.astype('float')
print(s_f.dtype)
# float64

s_f = s.astype(float)
print(s_f.dtype)
# float64

s_f = s.astype('f8')
print(s_f.dtype)
# float64

Caster le type de données de toutes les colonnes de pandas.DataFrame

pandas.DataFrame a le type de données dtype pour chaque colonne.

Vous pouvez vérifier chaque dtype avec l’attribut dtypes.

print(df)
#     a   b   c   d
# 0  11  12  13  14
# 1  21  22  23  24
# 2  31  32  33  34

print(df.dtypes)
# a    int64
# b    int64
# c    int64
# d    int64
# dtype: object

Si vous spécifiez le type de données dtype dans la méthode astype() de pandas.DataFrame, les types de données de toutes les colonnes sont modifiés.

df_f = df.astype('float64')
print(df_f)
#       a     b     c     d
# 0  11.0  12.0  13.0  14.0
# 1  21.0  22.0  23.0  24.0
# 2  31.0  32.0  33.0  34.0

print(df_f.dtypes)
# a    float64
# b    float64
# c    float64
# d    float64
# dtype: object

Caster le type de données de n’importe quelle colonne de pandas.DataFrame individuellement

Vous pouvez modifier le type de données dtype de n’importe quelle colonne individuellement en spécifiant un dictionnaire de {nom de colonne : type de données} à astype().

df_fcol = df.astype({'a': float})
print(df_fcol)
#       a   b   c   d
# 0  11.0  12  13  14
# 1  21.0  22  23  24
# 2  31.0  32  33  34

print(df_fcol.dtypes)
# a    float64
# b      int64
# c      int64
# d      int64
# dtype: object

df_fcol2 = df.astype({'a': 'float32', 'c': 'int8'})
print(df_fcol2)
#       a   b   c   d
# 0  11.0  12  13  14
# 1  21.0  22  23  24
# 2  31.0  32  33  34

print(df_fcol2.dtypes)
# a    float32
# b      int64
# c       int8
# d      int64
# dtype: object

Spécifiez le type de données (dtype) lors de la lecture de fichiers CSV avec read_csv()

Dans les pandas, vous pouvez lire les fichiers CSV avec pd.read_csv(). Vous pouvez spécifier n’importe quel type de données avec le paramètre dtype.

Utilisez le fichier CSV suivant comme exemple.

,a,b,c,d
ONE,1,"001",100,x
TWO,2,"020",,y
THREE,3,"300",300,z

Si l’argument dtype est omis, le type de données est automatiquement choisi pour chaque colonne.

df = pd.read_csv('data/src/sample_header_index_dtype.csv', index_col=0)
print(df)
#        a    b      c  d
# ONE    1    1  100.0  x
# TWO    2   20    NaN  y
# THREE  3  300  300.0  z

print(df.dtypes)
# a      int64
# b      int64
# c    float64
# d     object
# dtype: object

print(df.applymap(type))
#                    a              b                c              d
# ONE    <class 'int'>  <class 'int'>  <class 'float'>  <class 'str'>
# TWO    <class 'int'>  <class 'int'>  <class 'float'>  <class 'str'>
# THREE  <class 'int'>  <class 'int'>  <class 'float'>  <class 'str'>

Spécifiez le même type de données pour toutes les colonnes

Si vous spécifiez un type de données pour le paramètre dtype, toutes les colonnes sont converties dans ce type.

S’il existe des colonnes qui ne peuvent pas être converties dans le type de données spécifié, une erreur est générée.

# pd.read_csv('data/src/sample_header_index_dtype.csv',
#             index_col=0, dtype=float)
# ValueError: could not convert string to float: 'ONE'

Si dtype=str, la valeur manquante NaN n’est pas convertie en str.

df_str = pd.read_csv('data/src/sample_header_index_dtype.csv',
                     index_col=0, dtype=str)
print(df_str)
#        a    b    c  d
# ONE    1  001  100  x
# TWO    2  020  NaN  y
# THREE  3  300  300  z

print(df_str.dtypes)
# a    object
# b    object
# c    object
# d    object
# dtype: object

print(df_str.applymap(type))
#                    a              b                c              d
# ONE    <class 'str'>  <class 'str'>    <class 'str'>  <class 'str'>
# TWO    <class 'str'>  <class 'str'>  <class 'float'>  <class 'str'>
# THREE  <class 'str'>  <class 'str'>    <class 'str'>  <class 'str'>

Si vous souhaitez convertir une valeur manquante en chaîne ‘nan’, lisez-la sans spécifier dtype, puis convertissez-la en str avec astype().

print(df.astype(str).applymap(type))
#                    a              b              c              d
# ONE    <class 'str'>  <class 'str'>  <class 'str'>  <class 'str'>
# TWO    <class 'str'>  <class 'str'>  <class 'str'>  <class 'str'>
# THREE  <class 'str'>  <class 'str'>  <class 'str'>  <class 'str'>

Spécifiez le type de données pour chaque colonne

Comme avec astype(), vous pouvez utiliser un dictionnaire pour spécifier le type de données pour chaque colonne dans read_csv().

df_col = pd.read_csv('data/src/sample_header_index_dtype.csv',
                     index_col=0, dtype={'a': str, 'b': float})
print(df_col)
#        a      b      c  d
# ONE    1    1.0  100.0  x
# TWO    2   20.0    NaN  y
# THREE  3  300.0  300.0  z

print(df_col.dtypes)
# a     object
# b    float64
# c    float64
# d     object
# dtype: object

Vous pouvez spécifier par numéro de colonne au lieu du nom de colonne. Notez que si une colonne d’index est spécifiée, vous devez spécifier le numéro de colonne, y compris la colonne d’index.

df_col = pd.read_csv('data/src/sample_header_index_dtype.csv',
                     index_col=0, dtype={1: str, 2: float})
print(df_col)
#        a      b      c  d
# ONE    1    1.0  100.0  x
# TWO    2   20.0    NaN  y
# THREE  3  300.0  300.0  z

print(df_col.dtypes)
# a     object
# b    float64
# c    float64
# d     object
# dtype: object

Conversions de type implicites

En plus de la conversion de type explicite par astype(), les types de données peuvent être convertis implicitement par diverses opérations.

Utilisez pandas.DataFrame avec des colonnes d’entier int et des colonnes de virgule flottante float comme exemple.

df_mix = pd.DataFrame({'col_int': [0, 1, 2], 'col_float': [0.0, 0.1, 0.2]}, index=['A', 'B', 'C'])
print(df_mix)
#    col_int  col_float
# A        0        0.0
# B        1        0.1
# C        2        0.2

print(df_mix.dtypes)
# col_int        int64
# col_float    float64
# dtype: object

Conversion de type implicite par opérations arithmétiques

Par exemple, le résultat de l’ajout par l’opérateur + d’une colonne int à une colonne float est un float.

print(df_mix['col_int'] + df_mix['col_float'])
# A    0.0
# B    1.1
# C    2.2
# dtype: float64

De même, les opérations avec des valeurs scalaires convertissent implicitement le type de données. Le résultat de la division par l’opérateur / est flottant.

print(df_mix / 1)
#    col_int  col_float
# A      0.0        0.0
# B      1.0        0.1
# C      2.0        0.2

print((df_mix / 1).dtypes)
# col_int      float64
# col_float    float64
# dtype: object

Pour +, -, *, // et **, les opérations entre entiers renvoient int et les opérations impliquant des nombres à virgule flottante renvoient float. Cela équivaut à la conversion de type implicite du tableau NumPy ndarray.

print(df_mix * 1)
#    col_int  col_float
# A        0        0.0
# B        1        0.1
# C        2        0.2

print((df_mix * 1).dtypes)
# col_int        int64
# col_float    float64
# dtype: object

print(df_mix * 1.0)
#    col_int  col_float
# A      0.0        0.0
# B      1.0        0.1
# C      2.0        0.2

print((df_mix * 1.0).dtypes)
# col_int      float64
# col_float    float64
# dtype: object

Conversion de type implicite par transposition, etc.

Le type peut également être converti lorsqu’une ligne est sélectionnée en tant que pandas.Series avec loc ou iloc, ou lorsque pandas.DataFrame est transposé avec T ou transpose(). Par exemple, un élément entier est converti en un nombre à virgule flottante.

print(df_mix.loc['A'])
# col_int      0.0
# col_float    0.0
# Name: A, dtype: float64

print(df_mix.T)
#              A    B    C
# col_int    0.0  1.0  2.0
# col_float  0.0  0.1  0.2

print(df_mix.T.dtypes)
# A    float64
# B    float64
# C    float64
# dtype: object

Conversion de type implicite par affectation aux éléments

Le type de données peut également être implicitement converti lors de l’attribution d’une valeur à un élément.

Par exemple, l’affectation d’un élément de float à une colonne de int convertit cette colonne en float. De plus, l’affectation d’un élément de int à une colonne de float convertit cet élément en float.

df_mix.at['A', 'col_int'] = 10.1
df_mix.at['A', 'col_float'] = 10
print(df_mix)
#    col_int  col_float
# A     10.1       10.0
# B      1.0        0.1
# C      2.0        0.2

print(df_mix.dtypes)
# col_int      float64
# col_float    float64
# dtype: object

Lorsqu’un élément de chaîne est affecté à une colonne numérique, le type de données de la colonne est converti en objet.

df_mix.at['A', 'col_float'] = 'abc'
print(df_mix)
#    col_int col_float
# A     10.1       abc
# B      1.0       0.1
# C      2.0       0.2

print(df_mix.dtypes)
# col_int      float64
# col_float     object
# dtype: object

print(df_mix.applymap(type))
#            col_int        col_float
# A  <class 'float'>    <class 'str'>
# B  <class 'float'>  <class 'float'>
# C  <class 'float'>  <class 'float'>

Notez que l’exemple de code ci-dessus est le résultat de la version 1.4.1. Dans la version 0.22.0, le type de colonne restait le même même après l’affectation d’un élément d’un type différent, mais le type de l’élément affecté changeait. Notez que le comportement diffère selon la version.