220 votes

NumPy ou Pandas : Conserver le type de tableau en tant qu'entier tout en ayant une valeur NaN

Existe-t-il une méthode préférée pour conserver le type de données d'un fichier numpy fixé comme int (ou int64 ou autre), tout en ayant un élément à l'intérieur répertorié comme numpy.NaN ?

En particulier, je suis en train de convertir une structure de données interne en DataFrame Pandas. Dans notre structure, nous avons des colonnes de type entier qui ont toujours des NaN (mais le dtype de la colonne est int). Il semble que tout soit refondu en float si nous transformons cette structure en DataFrame, mais nous aimerions vraiment être en mesure de le faire. int .

Réflexions ?

Choses essayées :

J'ai essayé d'utiliser le from_records() sous pandas.DataFrame, avec la fonction coerce_float=False et cela n'a pas aidé. J'ai également essayé d'utiliser des tableaux masqués NumPy, avec une valeur de remplissage NaN, ce qui n'a pas fonctionné non plus. Toutes ces tentatives ont eu pour effet de transformer le type de données de la colonne en un flottant.

123voto

Wes McKinney Points 17545

NaN ne peut pas être stocké dans un tableau d'entiers. C'est une limitation connue de pandas pour le moment ; j'attendais des progrès avec les valeurs NA dans NumPy (similaires aux NA dans R), mais il faudra au moins 6 mois à un an avant que NumPy n'obtienne ces fonctionnalités, semble-t-il :

http://pandas.pydata.org/pandas-docs/stable/gotchas.html#support-for-integer-na

(Cette fonctionnalité a été ajoutée à partir de la version 0.24 de pandas, mais notez qu'elle nécessite l'utilisation de l'extension dtype Int64 (en majuscules), plutôt que le dtype int64 par défaut (en minuscules) : https://pandas.pydata.org/pandas-docs/version/0.24/whatsnew/v0.24.0.html#optional-integer-na-support )

114voto

techvslife Points 63

Cette fonctionnalité a été ajoutée à pandas commençant par version 0.24 .

À ce stade, il est nécessaire d'utiliser l'extension dtype 'Int64' (en majuscules), plutôt que le dtype par défaut 'int64' (en minuscules).

10voto

Si vous essayez de convertir un vecteur float (1.143) en integer (1), et que ce vecteur contient des NA, la conversion vers le nouveau dtype 'Int64' vous donnera une erreur. Pour résoudre ce problème, vous devez arrondir les nombres, puis faire ".astype('Int64')"

s1 = pd.Series([1.434, 2.343, np.nan])
#without round() the next line returns an error 
s1.astype('Int64')
#cannot safely cast non-equivalent float64 to int64
##with round() it works
s1.round().astype('Int64')
0      1
1      2
2    NaN
dtype: Int64

Mon cas d'utilisation est que j'ai une série de float que je veux arrondir en int, mais quand vous faites .round() il y a encore des décimales, vous devez convertir en int pour enlever les décimales.

9voto

Sergey Orshanskiy Points 1180

Si la performance n'est pas l'enjeu principal, vous pouvez stocker des chaînes de caractères à la place.

df.col = df.col.dropna().apply(lambda x: str(int(x)) )

Vous pouvez ensuite les mélanger avec NaN autant que vous le souhaitez. Si vous voulez vraiment avoir des entiers, en fonction de votre application, vous pouvez utiliser -1 ou 0 ou 1234567890 ou toute autre valeur dédiée pour représenter NaN .

Vous pouvez également dupliquer temporairement les colonnes : l'une comme vous l'avez fait, avec des flottants ; l'autre expérimentale, avec des ints ou des chaînes. Insérez ensuite asserts dans tous les endroits raisonnables pour vérifier que les deux sont synchronisés. Après un nombre suffisant de tests, vous pouvez laisser tomber les flotteurs.

7voto

pufferfish Points 3512

Ce n'est pas une solution pour tous les cas, mais dans le mien (coordonnées génomiques), j'ai utilisé 0 comme NaN.

a3['MapInfo'] = a3['MapInfo'].fillna(0).astype(int)

Cela permet au moins d'utiliser le type de colonne "natif" approprié, et les opérations telles que la soustraction, la comparaison, etc. fonctionnent comme prévu.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X