Types de données Pandas (dtype et conversion de type)

Pandas offre un riche système de types de données. Bien comprendre et utiliser les types de données est la base d'une analyse de données efficace. Cette section détaille le système de types de données de Pandas, l'inférence de types et les méthodes de conversion de types.


Aperçu des types de données de Pandas

dtype Description Type Python Exemple
int64 Entier 64 bits int 1, 2, 100
float64 Flottant 64 bits float 1.5, 3.14
object Type chaîne ou mixte str "hello"
bool Boolean bool True, False
datetime64[ns] Datetime datetime 2024-01-01
timedelta64[ns] Timedelta timedelta 1 days
category Type catégoriel - Ensemble fini

Exemple

import pandas as pd
import numpy as np

# Créer un DataFrame avec différents types de données
df = pd.DataFrame({
    "Entier": [1, 2, 3],
    "Flottant": [1.5, 2.5, 3.5],
    "Chaîne": ["a", "b", "c"],
    "Booléen": [True, False, True],
    "Date": pd.date_range("2024-01-01", periods=3)
})

print("Types de données des colonnes :")
print(df.dtypes)

Inférence et spécification des types

Inférence automatique des types

Exemple

import pandas as pd

# Inférence de type lors de la lecture d'un CSV
# pandas tente d'inférer le type le plus adapté pour chaque colonne
df = pd.read_csv("data.csv")

# Ou utilisez le paramètre dtype pour spécifier explicitement les types
df = pd.read_csv("data.csv", dtype={
    "Age": "int32",     # Spécifier comme entier 32 bits pour économiser de la mémoire
    "Salary": "float32",   # Spécifier comme flottant 32 bits
    "Name": "string"     # Utiliser le type string PyArrow
})

Spécification des types à la création

Exemple

import pandas as pd
import numpy as np

# Spécifier le type de données pour créer une Series
s = pd.Series([1, 2, 3], dtype="int8")  # Utiliser un type entier plus petit
print(f"type int8: {s.dtype}")

s = pd.Series([1.5, 2.5, 3.5], dtype="float32")  # Utiliser float32
print(f"type float32: {s.dtype}")

# Utiliser le type numpy
s = pd.Series([1, 2, 3], dtype=np.int8)
print(f"type np.int8: {s.dtype}")

Conversion de type

Conversion avec astype

Exemple

import pandas as pd
import numpy as np

# Créer des données d'exemple
df = pd.DataFrame({
    "Entier": [1, 2, 3],
    "Flottant": [1.5, 2.5, 3.5],
    "Chaîne": ["1", "2", "3"],
    "Booléen": [1, 0, 1]
})

print("Types d'origine :")
print(df.dtypes)
print()

# Convertir en chaîne
df["Integer_str"] = df["Integer"].astype(str)
print("Après conversion en chaîne :")
print(df.dtypes)

# Convertir une chaîne en numérique
df["String_int"] = df["String"].astype(int)
print("\n"Chaîne en entier :")
print(df.dtypes)

# Convertir un numérique en booléen (non nul est True)
df["Boolean_int"] = df["Boolean"].astype(bool)
print("\n"Entier en booléen :")
print(df.dtypes)

# Convertir un float en entier (troncature)
df["Float_int"] = df["Float"].astype(int)
print("\n"Conversion de float en entier :")
print(df)

Conversion avec pd.to_numeric

Exemple

import pandas as pd
import numpy as np

# Gérer les chaînes numériques avec des caractères spéciaux
s = pd.Series(["$1,000", "$2,500", "$3,200"])

# Nettoyer et convertir
s_cleaned = s.str.replace("$", "", regex=False).str.replace(",", "", regex=False)
s_numeric = pd.to_numeric(s_cleaned)
print("Chaîne en numérique :")
print(s_numeric)
print(f"Type : {s_numeric.dtype}")
print()

# Gérer les valeurs manquantes
s_with_na = pd.Series(["1", "2", "NA", "4"])
s_numeric = pd.to_numeric(s_with_na, errors="coerce")  # Convertir les valeurs invalides en NaN
print("Gestion des valeurs manquantes :")
print(s_numeric)

Conversion des dates avec pd.to_datetime

Exemple

import pandas as pd

# Convertir divers formats de date
dates = ["2024-01-01", "2024/01/02", "01/03/2024", "20240104"]

# Convertir les dates
dt = pd.to_datetime(dates, errors="coerce")
print("Résultat de la conversion des dates :")
print(dt)
print(f"Type : {dt.dtype}")
print()

# Spécifier le format de date
dates2 = ["20240101", "20240102", "20240103"]
dt2 = pd.to_datetime(dates2, format="%Y%m%d")
print("Conversion avec le format spécifié :")
print(dt2)

Optimisation de la mémoire

Choisir des types de données appropriés peut réduire considérablement l'utilisation de la mémoire.

Choix des types entiers

Exemple

import pandas as pd
import numpy as np

# Créer une Series avec une grande quantité de données
s = pd.Series(np.random.randint(0, 100, 1000000))

# int64 par défaut
print(f"mémoire int64 : {s.dtype} -> {s.memory_usage(deep=True) / 1024 / 1024:.2f} MB")

# Convertir vers un type plus petit
s_int8 = s.astype("int8")
print(f"mémoire int8 : {s_int8.dtype} -> {s_int8.memory_usage(deep=True) / 1024 / 1024:.2f} MB")

# Choisir un type approprié en fonction de la plage de données
# np.iinfo pour afficher la plage des entiers
print(f"\n"plage int8 : {np.iinfo('int8').min} à {np.iinfo('int8').max}")
print(f"plage int16 : {np.iinfo('int16').min} à {np.iinfo('int16').max}")
print(f"plage int32 : {np.iinfo('int32').min} à {np.iinfo('int32').max}")

Utilisation du type category

Exemple

import pandas as pd
import numpy as np

# Créer une Series avec de nombreuses valeurs dupliquées
s = pd.Series(np.random.choice(["Pékin", "Shanghai", "Canton", "Shenzhen"], 1000000))

# Type chaîne
print(f"mémoire du type object : {s.dtype} -> {s.memory_usage(deep=True) / 1024 / 1024:.2f} MB")

# Convertir en type category
s_cat = s.astype("category")
print(f"mémoire du type category : {s_cat.dtype} -> {s_cat.memory_usage(deep=True) / 1024 / 1024:.2f} MB")

# Inconvénient : certaines opérations peuvent devenir plus lentes
print("\n"infos category :")
print(s_cat.cat.categories)

Vérification et validation des types

Exemple

import pandas as pd
import numpy as np

df = pd.DataFrame({
    "Entier": [1, 2, 3],
    "Flottant": [1.5, 2.5, 3.5],
    "Chaîne": ["a", "b", "c"]
})

# Vérifier les types de données
print("Vérifier s'il s'agit d'un type numérique :")
print(df.dtypes)

# Utiliser is_integer_dtype
print(f"\n"Colonne Integer : {pd.api.types.is_integer_dtype(df['Integer'])}")
print(f"Colonne Float : {pd.api.types.is_float_dtype(df['Float'])}")
print(f"Colonne String : {pd.api.types.is_object_dtype(df['String'])}")

# Vérifier s'il peut être converti en numérique
print(f"\n"Peut être converti en numérique : {pd.api.types.is_numeric_dtype(df['Integer'])}")
print(f"Est de type datetime : {pd.api.types.is_datetime64_any_dtype(pd.Series(pd.date_range('2024', periods=3)))}")

Problèmes courants

1. Les valeurs flottantes apparaissent dans des colonnes d'entiers

Lorsqu'on les mélange dans un DataFrame, elles sont automatiquement converties en float64. UtilisezNullable IntegerLe type peut préserver les valeurs nulles de type entier.

2. Formats de date incohérents

Utiliserpd.to_datetimeet spécifiezformatparamètre pour gérer les formats non standard.

3. Erreur de type lors de la lecture d'un CSV

Utiliserdtypele paramètre pour spécifier explicitement le type, ou utilisezconverterspour convertir.

Pour les grands jeux de données, privilégiez l'utilisation de types de données plus petits (tels que int8, int16, float32) et des types catégoriels pour réduire l'utilisation de la mémoire.

Autres extensions