Warum sagt mir Pandas, dass ich Objekte habe, obwohl jedes Element in der ausgewählten Spalte eine Zeichenfolge ist - auch nach expliziter Konvertierung.
Dies ist mein DataFrame:
<class 'pandas.core.frame.DataFrame'>
Int64Index: 56992 entries, 0 to 56991
Data columns (total 7 columns):
id 56992 non-null values
attr1 56992 non-null values
attr2 56992 non-null values
attr3 56992 non-null values
attr4 56992 non-null values
attr5 56992 non-null values
attr6 56992 non-null values
dtypes: int64(2), object(5)
Fünf von ihnen sind dtype object
. Ich konvertiere diese Objekte explizit in Zeichenfolgen:
for c in df.columns:
if df[c].dtype == object:
print "convert ", df[c].name, " to string"
df[c] = df[c].astype(str)
Dann hat df["attr2"]
noch dtype object
, obwohl type(df["attr2"].ix[0]
offenbart str
, was richtig ist.
Pandas unterscheidet zwischen int64
und float64
und object
. Was ist die Logik dahinter, wenn es keine gibt dtype str
? Warum ist ein str
abgedeckt von object
?
Antworten:
Das dtype-Objekt stammt von NumPy und beschreibt den Elementtyp in einem ndarray. Jedes Element in einem ndarray muss dieselbe Byte-Größe haben. Für int64 und float64 sind dies 8 Bytes. Bei Zeichenfolgen ist die Länge der Zeichenfolge jedoch nicht festgelegt. Anstatt die Bytes der Zeichenfolgen direkt im ndarray zu speichern, verwenden Pandas das Objekt ndarray, das Zeiger auf Objekte speichert. Aus diesem Grund ist der dtype dieser Art ndarray object.
Hier ist ein Beispiel:
quelle
Die akzeptierte Antwort ist gut. Ich wollte nur eine Antwort geben, die auf die Dokumentation verweist . Die Dokumentation sagt:
Wie der Hauptkommentar sagt: "Mach dir keine Sorgen, es soll so sein." (Obwohl die akzeptierte Antwort großartige Arbeit geleistet hat, um das "Warum" zu erklären; Zeichenfolgen sind variabel lang)
quelle
astype(str)
obwohl ich mich immer noch fragen würde , ob eine Konvertierung von Zeichenfolgen erforderlich ist@ HYRYs Antwort ist großartig. Ich möchte nur etwas mehr Kontext bereitstellen.
Arrays gespeicherten Daten als zusammenhängende , feste Größe Speicherblocks. Die Kombination dieser Eigenschaften macht Arrays blitzschnell für den Datenzugriff. Überlegen Sie beispielsweise, wie Ihr Computer ein Array von 32-Bit-Ganzzahlen speichern könnte
[3,0,1]
.Wenn Sie Ihren Computer bitten, das dritte Element im Array abzurufen, beginnt es am Anfang und springt dann über 64 Bit, um zum dritten Element zu gelangen. Wenn Sie genau wissen, über wie viele Bits Sie springen müssen, sind Arrays schnell .
Betrachten Sie nun die Reihenfolge der Zeichenfolgen
['hello', 'i', 'am', 'a', 'banana']
. Strings sind Objekte mit unterschiedlicher Größe. Wenn Sie also versuchen, sie in zusammenhängenden Speicherblöcken zu speichern, sieht sie am Ende so aus.Jetzt hat Ihr Computer keine schnelle Möglichkeit, auf ein zufällig angefordertes Element zuzugreifen. Der Schlüssel zur Überwindung dieses Problems ist die Verwendung von Zeigern. Speichern Sie grundsätzlich jede Zeichenfolge an einem zufälligen Speicherort und füllen Sie das Array mit der Speicheradresse jeder Zeichenfolge. (Speicheradressen sind nur ganze Zahlen.) Nun sehen die Dinge so aus
Wenn Sie Ihren Computer nun wie zuvor auffordern, das dritte Element abzurufen, kann er über 64 Bit springen (vorausgesetzt, die Speicheradressen sind 32-Bit-Ganzzahlen), und dann einen zusätzlichen Schritt ausführen, um die Zeichenfolge abzurufen.
Die Herausforderung für NumPy besteht darin, dass es keine Garantie gibt, dass die Zeiger tatsächlich auf Zeichenfolgen zeigen. Aus diesem Grund wird der dtype als "Objekt" gemeldet.
Ich werde schamlos meinen eigenen Blog-Artikel einstecken, in dem ich das ursprünglich besprochen habe.
quelle
Ab Version 1.0.0 (Januar 2020) hat pandas eine experimentelle Funktion eingeführt, die erstklassige Unterstützung für String-Typen bietet
pandas.StringDtype
.Während Sie
object
standardmäßig immer noch sehen , kann der neue Typ verwendet werden, indem Sie eindtype
vonpd.StringDtype
oder einfach Folgendes angeben'string'
:quelle
The implementation may change without warning.
bedeutet dies, dass neue Updates Ihre alten Programme beschädigen.