Antes do pandas 1.0 (na verdade, 0,25), essa era a maneira mais comum de declarar uma série / coluna como uma string:
# 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')
Do pandas 1.0 em diante, considere usar o "string"
tipo .
# pandas >= 1.0
s = pd.Series(['a', 'b', 'c'], dtype="string")
s.dtype
# StringDtype
Aqui está o porquê, conforme citado pelos documentos:
Você pode armazenar acidentalmente uma mistura de cadeias e não cadeias em uma matriz de tipo de objeto. É melhor ter um dtype dedicado.
object
dtype quebra operações específicas do tipo, como DataFrame.select_dtypes()
. Não há uma maneira clara de selecionar apenas o texto, excluindo as colunas que não são de texto, mas ainda o tipo de objeto.
Ao ler o código, o conteúdo de uma object
matriz dtype é menos claro que 'string'
.
Veja também a seção Diferenças comportamentais entre "string"
eobject
.
Os tipos de extensão (introduzidos em 0.24 e formalizados em 1.0) estão mais próximos dos pandas do que do numpy, o que é bom porque os tipos numpy não são poderosos o suficiente. Por exemplo, o NumPy não tem como representar dados ausentes em dados inteiros (desde type(NaN) == float
). Mas os pandas podem usar colunas Nullable Integer .
Por que devo parar de usá-lo?
Mistura acidental de tipos de dados
O primeiro motivo, conforme descrito nos documentos, é que você pode armazenar acidentalmente dados que não são de texto em colunas de objetos.
# 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.
Desafiando a diferenciação de strings e outros objetos python
Outro exemplo óbvio de exemplo é que é mais difícil distinguir entre "strings" e "objetos". Os objetos são essencialmente do tipo geral para qualquer tipo que não suporte operações vetorizáveis .
Considerar,
# 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
Até os pandas 0,25, não havia praticamente nenhuma maneira de distinguir que "A" e "B" não tinham o mesmo tipo de dados.
# 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
No pandas 1.0, isso se torna muito mais simples:
# 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
Legibilidade
Isso é auto-explicativo ;-)
OK, então devo parar de usá-lo agora?
...Não. No momento em que escrevemos esta resposta (versão 1.1), não há benefícios de desempenho, mas os documentos esperam que aprimoramentos futuros melhorem significativamente o desempenho e reduzam o uso de memória para "string"
colunas em oposição a objetos. Com isso dito, no entanto, nunca é cedo para formar bons hábitos!
astype("string")
vez de,astype(str)
por boas razões, dar uma olhada.