2016-01-19 11 views
8

Numpy wydaje się odróżniać typy str i object. Na przykład można to zrobić ::rozróżnienie pand między typami str i object

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

przypadku dtype ('S') i dtype ('O') odpowiada str i object odpowiednio.

Jednak wydaje się, że pandy brakuje tego rozróżnienia i zmuszają do współpracy str do 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') 

Wymuszenie typu na dtype('S') również nie pomaga. ::

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

Czy istnieje jakieś wytłumaczenie tego zachowania?

+3

Jako bardzo krótkie wyjaśnienie, które nie jest pełną odpowiedzią: Jeśli użyjesz dtype typu string w 'numpy', jest to zasadniczo ciąg o stałej szerokości c. W 'pandach' są to" normalne "ciągi Pythona, a więc typ obiektu. –

+2

To może rozwiązać twoje pytanie - http://stackoverflow.com/questions/21018654/strings-in-a-dataframe-but-dtype-is-object - w zasadzie przechowują one obiekt ndarray, a nie ciągi w ndarray. Popieram jednak, że mogłyby one być bardziej jasne, jeśli chodzi o rozróżnianie typów - na przykład posiadanie umiejętności odróżniania kolumn "str" ​​od "mieszanych", które są również zgłaszane jako "O". – Sereger

Odpowiedz

12

Dotyki ciągów Numpy nie są ciągami Pythona.

Dlatego też, pandas celowo używa natywnych ciągów Pythona, które wymagają typu dtype obiektu.

Po pierwsze, pozwól wykazać trochę co to znaczy przez ciągi NumPy za bycie innym:

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) 

Teraz, 'x' jest numpy ciąg dtype (stałej szerokości, c-podobny łańcuch) i y to tablica rodzimych ciągów Pythona.

Jeśli spróbujemy przekroczyć 7 znaków, zobaczymy bezpośrednią różnicę. Wersje ciąg dtype zostanie obcięty:

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

Chociaż wersje obiekt dtype może być dowolna długość:

In [6]: y[1] = 'a really really really long' 

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

Następnie |S dtype struny nie może posiadać Unicode poprawnie, choć nie jest Unicode Ciąg dtype o stałej długości. Na razie pominę przykład.

Wreszcie, ciągi numpy są w rzeczywistości zmienne, a łańcuchy w języku Python nie. Na przykład:

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

Z tych wszystkich powodów, pandas wybraliśmy nie zawsze pozwalają C-podobne, ciągi stałej długości jako typ danych. Jak zauważyłeś, próba zmuszenia łańcucha Pythona do stałego ciągu numpy nie zadziała w pandas. Zamiast tego zawsze używa natywnych ciągów Pythona, które zachowują się w sposób bardziej intuicyjny dla większości użytkowników.

+1

W rzeczywistości pandy umożliwiają ciągi bajtowe o stałej długości w rodzaju "numpy", chociaż są one mało używane, np. 'Pd.Series (['a', 'b', 'c'], dtype = 'S1') – mdurant

Powiązane problemy