Je souhaite convertir un tableau, représenté sous forme de liste de listes, en un Pandas DataFrame
. À titre d'exemple extrêmement simplifié:
a = [['a', '1.2', '4.2'], ['b', '70', '0.03'], ['x', '5', '0']]
df = pd.DataFrame(a)
Quelle est la meilleure façon de convertir les colonnes en types appropriés, dans ce cas les colonnes 2 et 3 en flottants? Existe-t-il un moyen de spécifier les types lors de la conversion en DataFrame? Ou est-il préférable de créer d'abord le DataFrame, puis de parcourir les colonnes pour changer le type de chaque colonne? Idéalement, je voudrais le faire de manière dynamique car il peut y avoir des centaines de colonnes et je ne veux pas spécifier exactement quelles colonnes sont de quel type. Tout ce que je peux garantir, c'est que chaque colonne contient des valeurs du même type.
df.apply(pd.to_numeric, downcast="integer", errors="ignore")
pour downcast des colonnes entières vers le plus petit (entier) dtype qui contiendra les valeurs.Réponses:
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 aussito_datetime()
etto_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.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:
Vous pouvez également l'utiliser pour convertir plusieurs colonnes d'un DataFrame via la
apply()
méthode: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 unerrors
argument de mot clé qui vous permet de forcer les valeurs non numériques à êtreNaN
, 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: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»:
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é:La troisième option pour
errors
est simplement d'ignorer l'opération si une valeur non valide est rencontrée: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:
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 unint64
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éries
de type entier:La descente en «entier» utilise le plus petit entier possible pouvant contenir les valeurs:
La descente vers «flottant» choisit de la même manière un type flottant plus petit que la normale:
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: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 unNaN
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:Ce sont de petits entiers, alors que diriez-vous de convertir en un type 8 bits non signé pour économiser de la mémoire?
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:
En utilisant
infer_objects()
, vous pouvez changer le type de colonne 'a' en int64: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.la source
.convert_objects
est obsolète depuis0.17
- utilisez à ladf.to_numeric
placepd.to_numeric
et ses méthodes compagnes ne fonctionneront que sur une colonne à la fois, contrairement àconvert_objects
. La discussion sur une fonction de remplacement dans l'API semble être en cours ; J'espère qu'une méthode qui fonctionne sur l'ensemble du DataFrame restera car elle est très utile.int64
enint32
?astype
(comme dans l'autre réponse), c'est à dire.astype(numpy.int32)
.Que dis-tu de ça?
la source
pd.DataFrame
a undtype
argument qui pourrait vous permettre de faire ce que vous cherchez. df = pd.DataFrame (a, colonnes = ['un', 'deux', 'trois'], dtype = float) In [2]: df.dtypes Out [2]: un objet deux float64 trois float64 dtype: objectSettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_index,col_indexer] = value instead
. Cela a peut-être été introduit dans une version plus récente de pandas et je ne vois rien de mal en conséquence, mais je me demande simplement en quoi consiste cet avertissement. Une idée?ValueError: Cannot convert NA to integer
df = pd.DataFrame(a, columns=['one', 'two', 'three'], dtype={'one': str, 'two': int, 'three': float})
. J'ai du mal à trouver la spécification pour les valeurs "dtype" acceptées. Une liste serait bien (actuellement je le faisdict(enumerate(my_list))
).ce code ci-dessous changera le type de données de la colonne.
au lieu du type de données, vous pouvez donner votre type de données. que voulez-vous comme str, float, int etc.
la source
bool
, tout est changé enTrue
.Lorsque je n'ai eu besoin que de spécifier des colonnes spécifiques et que je veux être explicite, j'ai utilisé (par DOCS LOCATION ):
Donc, en utilisant la question d'origine, mais en lui fournissant des noms de colonnes ...
la source
Voici une fonction qui prend comme arguments un DataFrame et une liste de colonnes et contraint toutes les données des colonnes à des nombres.
Donc, pour votre exemple:
la source
Que diriez-vous de créer deux cadres de données, chacun avec des types de données différents pour leurs colonnes, puis de les ajouter ensemble?
Résultats
Une fois la trame de données créée, vous pouvez la remplir avec des variables à virgule flottante dans la 1ère colonne et des chaînes (ou tout type de données souhaité) dans la 2ème colonne.
la source
pandas> = 1.0
Voici un tableau qui résume certaines des conversions les plus importantes chez les pandas.
Les conversions en chaîne sont triviales
.astype(str)
et ne sont pas représentées sur la figure.Conversions "dures" contre "douces"
Notez que les «conversions» dans ce contexte peuvent faire référence à la conversion de données texte en leur type de données réel (conversion matérielle) ou à l'inférence de types de données plus appropriés pour les données dans les colonnes d'objets (conversion logicielle). Pour illustrer la différence, jetez un œil à
la source
Je pensais que j'avais le même problème mais en fait j'ai une légère différence qui rend le problème plus facile à résoudre. Pour ceux qui regardent cette question, il vaut la peine de vérifier le format de votre liste de saisie. Dans mon cas, les nombres sont initialement des flottants et non des chaînes comme dans la question:
mais en traitant trop la liste avant de créer la trame de données, je perds les types et tout devient une chaîne.
Création de la trame de données via un tableau numpy
donne le même bloc de données que dans la question, où les entrées dans les colonnes 1 et 2 sont considérées comme des chaînes. Cependant faire
donne en fait un bloc de données avec les colonnes au format correct
la source
À partir de pandas 1.0.0, nous l'avons
pandas.DataFrame.convert_dtypes
. Vous pouvez même contrôler quels types convertir!la source