Pandas distinción entre str y tipos de objetos.

Numpy parece hacer una distinción entre str y tipos de object . Por ejemplo puedo hacer:

 >>> import pandas as pd >>> import numpy as np >>> np.dtype(str) dtype('S') >>> np.dtype(object) dtype('O') 

Donde dtype (‘S’) y dtype (‘O’) corresponde a str y object respectivamente.

Sin embargo, los pandas parecen carecer de esa distinción y obligan a object . ::

 >>> df = pd.DataFrame({'a': np.arange(5)}) >>> df.a.dtype dtype('int64') >>> df.a.astype(str).dtype dtype('O') >>> df.a.astype(object).dtype dtype('O') 

Forzar el tipo a dtype('S') tampoco ayuda. ::

 >>> df.a.astype(np.dtype(str)).dtype dtype('O') >>> df.a.astype(np.dtype('S')).dtype dtype('O') 

¿Hay alguna explicación para este comportamiento?

Los dtypes de cuerdas de Numpy no son cuerdas de python.

Por lo tanto, los pandas utilizan deliberadamente cadenas nativas de python, que requieren un tipo de objeto.

En primer lugar, permítame demostrar un poco de lo que quiero decir con que las cuerdas de numpy son diferentes:

 In [1]: import numpy as np In [2]: x = np.array(['Testing', 'a', 'string'], dtype='|S7') In [3]: y = np.array(['Testing', 'a', 'string'], dtype=object) 

Ahora, ‘x’ es un numpy cadena numpy (ancho-fijo, cadena tipo c) e y es una matriz de cadenas de python nativas.

Si intentamos ir más allá de los 7 caracteres, veremos una diferencia inmediata. Se truncarán las versiones de dtype de cadena:

 In [4]: x[1] = 'a really really really long' In [5]: x Out[5]: array(['Testing', 'a reall', 'string'], dtype='|S7') 

Mientras que las versiones del tipo de objeto pueden ser de longitud arbitraria:

 In [6]: y[1] = 'a really really really long' In [7]: y Out[7]: array(['Testing', 'a really really really long', 'string'], dtype=object) 

A continuación, las cadenas |S d dtype no pueden contener unicode correctamente, aunque también hay un tipo dtype unicode de longitud fija. Voy a omitir un ejemplo, por el momento.

Finalmente, las cadenas de numpy son realmente mutables, mientras que las cadenas de Python no lo son. Por ejemplo:

 In [8]: z = x.view(np.uint8) In [9]: z += 1 In [10]: x Out[10]: array(['Uftujoh', 'b!sfbmm', 'tusjoh\x01'], dtype='|S7') 

Por todas estas razones, los pandas decidieron no permitir nunca cadenas tipo C de longitud fija como tipo de datos. Como te habrás dado cuenta, el bash de forzar una cadena de python en una cadena de numpy corregida no funcionará en pandas . En su lugar, siempre utiliza cadenas nativas de Python, que se comportan de una manera más intuitiva para la mayoría de los usuarios.