Vous avez trois options principales pour convertir des types en pandas:
to_numeric()
- fournit des fonctionnalités pour convertir en toute sécurité des types non numériques (par exemple des chaînes) en un type numérique approprié. (Voir aussi to_datetime()
et to_timedelta()
.)
astype()
- convertir (presque) tout type en (presque) tout autre type (même si cela n'est pas nécessairement judicieux). Vous permet également de convertir en types catégoriels (très utile).
infer_objects()
- une méthode utilitaire pour convertir les colonnes d'objets contenant des objets Python en type pandas si possible.
Lisez la suite pour des explications plus détaillées et l'utilisation de chacune de ces méthodes.
1. to_numeric()
La meilleure façon de convertir une ou plusieurs colonnes d'un DataFrame en valeurs numériques est d'utiliser pandas.to_numeric()
.
Cette fonction essaiera de changer des objets non numériques (tels que des chaînes) en nombres entiers ou en virgule flottante, selon le cas.
Utilisation basique
L'entrée de to_numeric()
est une série ou une seule colonne d'un DataFrame.
>>> s = pd.Series(["8", 6, "7.5", 3, "0.9"]) # mixed string and numeric values
>>> s
0 8
1 6
2 7.5
3 3
4 0.9
dtype: object
>>> pd.to_numeric(s) # convert everything to float values
0 8.0
1 6.0
2 7.5
3 3.0
4 0.9
dtype: float64
Comme vous pouvez le voir, une nouvelle série est retournée. N'oubliez pas d'affecter cette sortie à un nom de variable ou de colonne pour continuer à l'utiliser:
# convert Series
my_series = pd.to_numeric(my_series)
# convert column "a" of a DataFrame
df["a"] = pd.to_numeric(df["a"])
Vous pouvez également l'utiliser pour convertir plusieurs colonnes d'un DataFrame via la apply()
méthode:
# convert all columns of DataFrame
df = df.apply(pd.to_numeric) # convert all columns of DataFrame
# convert just columns "a" and "b"
df[["a", "b"]] = df[["a", "b"]].apply(pd.to_numeric)
Tant que vos valeurs peuvent toutes être converties, c'est probablement tout ce dont vous avez besoin.
La gestion des erreurs
Mais que faire si certaines valeurs ne peuvent pas être converties en un type numérique?
to_numeric()
prend également un errors
argument de mot clé qui vous permet de forcer les valeurs non numériques à être NaN
, ou tout simplement ignorer les colonnes contenant ces valeurs.
Voici un exemple utilisant une série de chaînes s
qui a le type d'objet:
>>> s = pd.Series(['1', '2', '4.7', 'pandas', '10'])
>>> s
0 1
1 2
2 4.7
3 pandas
4 10
dtype: object
Le comportement par défaut consiste à augmenter s'il ne peut pas convertir une valeur. Dans ce cas, il ne peut pas faire face à la chaîne «pandas»:
>>> pd.to_numeric(s) # or pd.to_numeric(s, errors='raise')
ValueError: Unable to parse string
Plutôt que d'échouer, nous pourrions vouloir que «pandas» soit considéré comme une valeur numérique manquante / incorrecte. Nous pouvons contraindre les valeurs non valides NaN
comme suit à l'aide de l' errors
argument mot - clé:
>>> pd.to_numeric(s, errors='coerce')
0 1.0
1 2.0
2 4.7
3 NaN
4 10.0
dtype: float64
La troisième option pour errors
est simplement d'ignorer l'opération si une valeur non valide est rencontrée:
>>> pd.to_numeric(s, errors='ignore')
# the original Series is returned untouched
Cette dernière option est particulièrement utile lorsque vous souhaitez convertir l'intégralité de votre DataFrame, mais que vous ne savez pas laquelle de nos colonnes peut être convertie de manière fiable en un type numérique. Dans ce cas, écrivez simplement:
df.apply(pd.to_numeric, errors='ignore')
La fonction sera appliquée à chaque colonne du DataFrame. Les colonnes qui peuvent être converties en un type numérique seront converties, tandis que les colonnes qui ne peuvent pas (par exemple, elles contiennent des chaînes ou des dates non numériques) seront laissées seules.
Downcasting
Par défaut, la conversion avec to_numeric()
vous donnera soit un int64
oufloat64
dtype (ou quelle que soit la largeur entière native de votre plateforme).
C'est généralement ce que vous voulez, mais si vous vouliez économiser de la mémoire et utiliser un type plus compact, comme float32
ouint8
?
to_numeric()
vous donne la possibilité de rétrograder en «entier», «signé», «non signé», «flottant». Voici un exemple pour une simple série s
de type entier:
>>> s = pd.Series([1, 2, -7])
>>> s
0 1
1 2
2 -7
dtype: int64
La descente en «entier» utilise le plus petit entier possible pouvant contenir les valeurs:
>>> pd.to_numeric(s, downcast='integer')
0 1
1 2
2 -7
dtype: int8
La descente vers «flottant» choisit de la même manière un type flottant plus petit que la normale:
>>> pd.to_numeric(s, downcast='float')
0 1.0
1 2.0
2 -7.0
dtype: float32
2. astype()
le astype()
méthode vous permet d'être explicite sur le dtype que vous voulez que votre DataFrame ou Series ait. Il est très polyvalent en ce sens que vous pouvez essayer de passer d'un type à l'autre.
Utilisation basique
Choisissez simplement un type: vous pouvez utiliser un type NumPy (par exemple np.int16
), certains types Python (par exemple bool) ou des types spécifiques aux pandas (comme le type catégoriel).
Appelez la méthode sur l'objet que vous souhaitez convertir et astype()
essayez de le convertir pour vous:
# convert all DataFrame columns to the int64 dtype
df = df.astype(int)
# convert column "a" to int64 dtype and "b" to complex type
df = df.astype({"a": int, "b": complex})
# convert Series to float16 type
s = s.astype(np.float16)
# convert Series to Python strings
s = s.astype(str)
# convert Series to categorical type - see docs for more details
s = s.astype('category')
Remarquez que j'ai dit "essayez" - si astype()
ne sait pas comment convertir une valeur dans la série ou le DataFrame, cela soulèvera une erreur. Par exemple, si vous avez un NaN
ouinf
valeur , vous obtiendrez une erreur en essayant de la convertir en entier.
Depuis pandas 0.20.0, cette erreur peut être supprimée en passant errors='ignore'
. Votre objet d'origine sera retourné intact.
Faites attention
astype()
est puissant, mais il convertit parfois des valeurs "incorrectement". Par exemple:
>>> s = pd.Series([1, 2, -7])
>>> s
0 1
1 2
2 -7
dtype: int64
Ce sont de petits entiers, alors que diriez-vous de convertir en un type 8 bits non signé pour économiser de la mémoire?
>>> s.astype(np.uint8)
0 1
1 2
2 249
dtype: uint8
La conversion a fonctionné, mais le -7 a été bouclé pour devenir 249 (soit 2 8 - 7)!
Essayer de rétrograder à la pd.to_numeric(s, downcast='unsigned')
place pourrait aider à éviter cette erreur.
3. infer_objects()
La version 0.21.0 de pandas a introduit la méthode infer_objects()
de conversion des colonnes d'un DataFrame qui ont un type de données d'objet en un type plus spécifique (conversions logicielles).
Par exemple, voici un DataFrame avec deux colonnes de type d'objet. L'un contient des entiers réels et l'autre contient des chaînes représentant des entiers:
>>> df = pd.DataFrame({'a': [7, 1, 5], 'b': ['3','2','1']}, dtype='object')
>>> df.dtypes
a object
b object
dtype: object
En utilisant infer_objects()
, vous pouvez changer le type de colonne 'a' en int64:
>>> df = df.infer_objects()
>>> df.dtypes
a int64
b object
dtype: object
La colonne 'b' a été laissée seule car ses valeurs étaient des chaînes, pas des entiers. Si vous souhaitez essayer de forcer la conversion des deux colonnes en un type entier, vous pouvez utiliser à la df.astype(int)
place.