Avant Pandas 1.0 (enfin, 0.25 en fait), c'était la façon de facto de déclarer une série / colonne comme une chaîne:
# pandas <= 0.25
# Note to pedants: specifying the type is unnecessary since pandas will
# automagically infer the type as object
s = pd.Series(['a', 'b', 'c'], dtype=str)
s.dtype
# dtype('O')
À partir de pandas 1.0, envisagez d'utiliser le "string"
type à la place.
# pandas >= 1.0
s = pd.Series(['a', 'b', 'c'], dtype="string")
s.dtype
# StringDtype
Voici pourquoi, comme cité par la documentation:
Vous pouvez accidentellement stocker un mélange de chaînes et de non-chaînes dans un tableau objet dtype. Il vaut mieux avoir un dtype dédié.
object
dtype interrompt les opérations spécifiques à dtype comme DataFrame.select_dtypes()
. Il n'existe pas de moyen clair de sélectionner uniquement du texte tout en excluant les colonnes non textuelles mais toujours de type objet.
Lors de la lecture de code, le contenu d'un object
tableau dtype est moins clair que 'string'
.
Voir également la section sur les différences de comportement entre "string"
etobject
.
Les types d'extensions (introduits dans 0.24 et formalisés dans 1.0) sont plus proches des pandas que numpy, ce qui est bien car les types numpy ne sont pas assez puissants. Par exemple, NumPy n'a aucun moyen de représenter les données manquantes dans des données entières (depuis type(NaN) == float
). Mais les pandas peuvent utiliser des colonnes Nullable Integer .
Pourquoi devrais-je arrêter de l'utiliser?
Mélange accidentel de dtypes
La première raison, comme indiqué dans la documentation, est que vous pouvez accidentellement stocker des données non textuelles dans des colonnes d'objets.
# pandas <= 0.25
pd.Series(['a', 'b', 1.23]) # whoops, this should have been "1.23"
0 a
1 b
2 1.23
dtype: object
pd.Series(['a', 'b', 1.23]).tolist()
# ['a', 'b', 1.23] # oops, pandas was storing this as float all the time.
# pandas >= 1.0
pd.Series(['a', 'b', 1.23], dtype="string")
0 a
1 b
2 1.23
dtype: string
pd.Series(['a', 'b', 1.23], dtype="string").tolist()
# ['a', 'b', '1.23'] # it's a string and we just averted some potentially nasty bugs.
Difficulté à différencier les chaînes et les autres objets python
Un autre exemple évident est qu'il est plus difficile de faire la distinction entre les "chaînes" et les "objets". Les objets sont essentiellement le type de couverture pour tout type qui ne prend pas en charge les opérations vectorisables .
Considérer,
# Setup
df = pd.DataFrame({'A': ['a', 'b', 'c'], 'B': [{}, [1, 2, 3], 123]})
df
A B
0 a {}
1 b [1, 2, 3]
2 c 123
Jusqu'à pandas 0.25, il n'y avait pratiquement aucun moyen de distinguer que "A" et "B" n'ont pas le même type de données.
# pandas <= 0.25
df.dtypes
A object
B object
dtype: object
df.select_dtypes(object)
A B
0 a {}
1 b [1, 2, 3]
2 c 123
Depuis pandas 1.0, cela devient beaucoup plus simple:
# pandas >= 1.0
# Convenience function I call to help illustrate my point.
df = df.convert_dtypes()
df.dtypes
A string
B object
dtype: object
df.select_dtypes("string")
A
0 a
1 b
2 c
Lisibilité
Cela va de soi ;-)
OK, devrais-je arrêter de l'utiliser maintenant?
...Non. Au moment de la rédaction de cette réponse (version 1.1), il n'y a aucun avantage en termes de performances, mais la documentation s'attend à des améliorations futures pour améliorer considérablement les performances et réduire l'utilisation de la mémoire pour les "string"
colonnes par opposition aux objets. Cela dit, cependant, il n'est jamais trop tôt pour prendre de bonnes habitudes!
astype("string")
au lieu deastype(str)
pour de très bonnes raisons, jetez un œil.