Konvertieren Sie Spalten in Pandas in Zeichenfolgen

Lesezeit: 8 Minuten

Konvertieren Sie Spalten in Pandas in Zeichenfolgen
sontek

Ich habe den folgenden DataFrame aus einer SQL-Abfrage:

(Pdb) pp total_rows
     ColumnID  RespondentCount
0          -1                2
1  3030096843                1
2  3030096845                1

und ich möchte es so drehen:

total_data = total_rows.pivot_table(cols=['ColumnID'])

(Pdb) pp total_data
ColumnID         -1            3030096843   3030096845
RespondentCount            2            1            1

[1 rows x 3 columns]


total_rows.pivot_table(cols=['ColumnID']).to_dict('records')[0]

{3030096843: 1, 3030096845: 1, -1: 2}

aber ich möchte sicherstellen, dass die 303-Spalten als Zeichenfolgen anstelle von Ganzzahlen umgewandelt werden, damit ich Folgendes bekomme:

{'3030096843': 1, '3030096845': 1, -1: 2}

Eine Möglichkeit zum Konvertieren in eine Zeichenfolge ist die Verwendung astyp:

total_rows['ColumnID'] = total_rows['ColumnID'].astype(str)

Vielleicht suchen Sie jedoch nach der to_json Funktion, die Schlüssel in gültige json konvertiert (und damit Ihre Schlüssel in Zeichenfolgen):

In [11]: df = pd.DataFrame([['A', 2], ['A', 4], ['B', 6]])

In [12]: df.to_json()
Out[12]: '{"0":{"0":"A","1":"A","2":"B"},"1":{"0":2,"1":4,"2":6}}'

In [13]: df[0].to_json()
Out[13]: '{"0":"A","1":"A","2":"B"}'

Hinweis: Sie können einen Puffer/eine Datei übergeben, um dies zusammen mit einigen anderen Optionen zu speichern …

  • Ich denke, to_string() ist aufgrund der Beibehaltung von NULLen vorzuziehen. stackoverflow.com/a/44008334/3647167

    – Keith

    16. Mai 17 um 17:51 Uhr

  • @Keith Nullerhaltung ist attraktiv. aber das Dokument sagt, dass sein Zweck darin besteht, “einen DataFrame in eine konsolenfreundliche tabellarische Ausgabe zu rendern”. Ich möchte, dass jemand Autoritätsperson abwiegt

    – 3pitt

    21. Februar 18 um 16:58 Uhr

  • to_json() ruft wohl nicht an astype(str) da es datetime64 und seine Unterklassen als Millisekunden seit Epoche verlässt.

    – Süß

    10. Juli 19 um 5:41 Uhr

  • @Sussch Ich vermute, das liegt daran, dass json kein explizites Datetime-Format hat, also sind Sie irgendwie gezwungen, Epoche zu verwenden. Das heißt, ich denke, das ist der Standard.

    – Andy Hayden

    10. Juli 19 um 6:05 Uhr

  • @webNoob13: Dies ist ein gewünschtes/beabsichtigtes Verhalten – das sind im Wesentlichen Pandas-Strings. Siehe hier: stackoverflow.com/questions/34881079/…

    – felsenfest

    21. Oktober 20 um 14:18 Uhr

Wenn Sie ALLE Spalten in Zeichenfolgen konvertieren müssen, können Sie einfach Folgendes verwenden:

df = df.astype(str)

Dies ist nützlich, wenn Sie alles außer ein paar Spalten als Strings/Objekte benötigen, dann gehen Sie zurück und konvertieren Sie die anderen in das, was Sie brauchen (in diesem Fall eine ganze Zahl):

 df[["D", "E"]] = df[["D", "E"]].astype(int) 

  • Ich würde Ihre Antwort bevorzugen – weil das OP nach “allen” Spalten gefragt hat, nicht nach einzelnen Spalten.

    – abhijat_saxena

    18. November 21 um 16:40 Uhr

Konvertieren Sie Spalten in Pandas in Zeichenfolgen
cs95

Pandas >= 1.0: Es ist Zeit, aufhören zu können astype(str)!

Vor Pandas 1.0 (naja, eigentlich 0.25) war dies die Defacto-Methode, um eine Serie/Spalte als Zeichenfolge zu deklarieren:

# 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')

Erwägen Sie ab Pandas 1.0 die Verwendung von "string" Typ stattdessen.

# pandas >= 1.0
s = pd.Series(['a', 'b', 'c'], dtype="string")
s.dtype
# StringDtype

Hier ist der Grund, wie in den Dokumenten zitiert:

  1. Sie können versehentlich eine Mischung aus Strings und Nicht-Strings in einem Objekt-Dtype-Array speichern. Es ist besser, einen dedizierten dtype zu haben.

  2. object dtype unterbricht dtype-spezifische Operationen wie DataFrame.select_dtypes(). Es gibt keine eindeutige Möglichkeit, nur Text auszuwählen und gleichzeitig Nicht-Text-Spalten, aber immer noch Objekt-D-Typ-Spalten auszuschließen.

  3. Beim Lesen von Code wird der Inhalt einer object dtype-Array ist weniger klar als 'string'.

Siehe auch den Abschnitt zu Verhaltensunterschiede zwischen "string" und object.

Erweiterungstypen (eingeführt in 0.24 und formalisiert in 1.0) näher an Pandas als an numpy, was gut ist, weil numpy-Typen nicht leistungsfähig genug sind. Zum Beispiel hat NumPy keine Möglichkeit, fehlende Daten in ganzzahligen Daten darzustellen (seit type(NaN) == float). Aber Pandas können mit Nullable Integer-Spalten.


Warum sollte ich aufhören, es zu verwenden?

Versehentliches Mischen von dtypes

Der erste Grund, wie in der Dokumentation beschrieben, ist, dass Sie versehentlich Nicht-Text-Daten in Objektspalten speichern können.

# 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.

Herausfordernd, Zeichenfolgen und andere Python-Objekte zu unterscheiden

Ein weiteres offensichtliches Beispiel ist, dass es schwieriger ist, zwischen “Zeichenfolgen” und “Objekten” zu unterscheiden. Objekte sind im Wesentlichen der allgemeine Typ für jeden Typ, der keine vektorisierbaren Operationen unterstützt.

Erwägen,

# 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

Bis Pandas 0.25 gab es praktisch keine Möglichkeit zu unterscheiden, dass „A“ und „B“ nicht denselben Datentyp haben.

# 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

Von Pandas 1.0 wird dies viel einfacher:

# 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

Lesbarkeit

Das ist selbsterklärend 😉


OK, also sollte ich jetzt aufhören, es zu benutzen?

…Nein. Zum Zeitpunkt des Schreibens dieser Antwort (Version 1.1) dort sind keine Leistungsvorteile Die Dokumentation erwartet jedoch, dass zukünftige Verbesserungen die Leistung erheblich verbessern und die Speichernutzung für reduzieren "string" Spalten im Gegensatz zu Objekten. Trotzdem ist es nie zu früh, sich gute Gewohnheiten anzueignen!

  • Dies funktioniert, wenn die Quelle a, b, c ist, und schlägt fehl, wenn die Quelle 1,2,3 usw. ist.

    – Nages

    29. Juli 2020 um 23:59 Uhr


  • @Nages Ich hoffe es, es macht im Allgemeinen keinen Sinn, numerische Daten als Text darzustellen.

    – cs95

    30. Juli 2020 um 0:34 Uhr

  • Das ist richtig. Aber manchmal passiert es, wenn Sie versuchen, den Kaggle-Titanic-Wettbewerb zu lösen, bei dem Pclass als 1, 2 und 3 dargestellt wird. Hier sollte es kategorisch wie ein Zeichenfolgenformat statt numerisch sein. Zur Lösung dieses Problems hat in diesem Fall str anstelle von string geholfen. Wie auch immer, danke, es funktioniert für Charaktere. Vielen Dank für die Weitergabe dieser Dokumentationsdetails.

    – Nages

    1. August 2020 um 2:22 Uhr

  • @cs95 Sehr aufschlussreich.. Danke fürs Teilen 🙂

    – Shubham Sharma

    7. September 2020 um 15:46 Uhr

Hier ist der andere, besonders nützlich zu Konvertieren Sie die mehreren Spalten in eine Zeichenfolge statt nur einer Spalte:

In [76]: import numpy as np
In [77]: import pandas as pd
In [78]: df = pd.DataFrame({
    ...:     'A': [20, 30.0, np.nan],
    ...:     'B': ["a45a", "a3", "b1"],
    ...:     'C': [10, 5, np.nan]})
    ...: 

In [79]: df.dtypes ## Current datatype
Out[79]: 
A    float64
B     object
C    float64
dtype: object

## Multiple columns string conversion
In [80]: df[["A", "C"]] = df[["A", "C"]].astype(str) 

In [81]: df.dtypes ## Updated datatype after string conversion
Out[81]: 
A    object
B    object
C    object
dtype: object

1643039168 415 Konvertieren Sie Spalten in Pandas in Zeichenfolgen
Govinda

Es gibt vier Möglichkeiten, Spalten in Zeichenfolgen zu konvertieren

1. astype(str)
df['column_name'] = df['column_name'].astype(str)

2. values.astype(str)
df['column_name'] = df['column_name'].values.astype(str)

3. map(str)
df['column_name'] = df['column_name'].map(str)

4. apply(str)
df['column_name'] = df['column_name'].apply(str)

Sehen wir uns die Leistung jedes Typs an

#importing libraries
import numpy as np
import pandas as pd
import time

#creating four sample dataframes using dummy data
df1 = pd.DataFrame(np.random.randint(1, 1000, size =(10000000, 1)), columns =['A'])
df2 = pd.DataFrame(np.random.randint(1, 1000, size =(10000000, 1)), columns =['A'])
df3 = pd.DataFrame(np.random.randint(1, 1000, size =(10000000, 1)), columns =['A'])
df4 = pd.DataFrame(np.random.randint(1, 1000, size =(10000000, 1)), columns =['A'])

#applying astype(str)
time1 = time.time()
df1['A'] = df1['A'].astype(str)
print('time taken for astype(str) : ' + str(time.time()-time1) + ' seconds')

#applying values.astype(str)
time2 = time.time()
df2['A'] = df2['A'].values.astype(str)
print('time taken for values.astype(str) : ' + str(time.time()-time2) + ' seconds')

#applying map(str)
time3 = time.time()
df3['A'] = df3['A'].map(str)
print('time taken for map(str) : ' + str(time.time()-time3) + ' seconds')

#applying apply(str)
time4 = time.time()
df4['A'] = df4['A'].apply(str)
print('time taken for apply(str) : ' + str(time.time()-time4) + ' seconds')

Ausgabe

time taken for astype(str): 5.472359895706177 seconds
time taken for values.astype(str): 6.5844292640686035 seconds
time taken for map(str): 2.3686647415161133 seconds
time taken for apply(str): 2.39758563041687 seconds

map(str) und apply(str) Diese dauert im Vergleich zu den beiden verbleibenden Techniken weniger Zeit

  • Ihre Ergebnisse sind verdächtig. .astype(str) sollte auf jeden Fall am schnellsten sein. benutzen %timeit um zuverlässigere Ergebnisse zu erhalten (gibt Ihnen den Durchschnitt über viele Versuche). %timeit gibt mir 654ms für .astype(str), 1,4 s für .values.astype(str), 2,11 s für .map(str), und 1,74 s für für .apply(str).

    – tdy

    30. Juli 21 um 19:40 Uhr


Konvertieren Sie Spalten in Pandas in Zeichenfolgen
Feng Bao

Ich benutze meistens diesen:

pd['Column'].map(str)

  • Ihre Ergebnisse sind verdächtig. .astype(str) sollte auf jeden Fall am schnellsten sein. benutzen %timeit um zuverlässigere Ergebnisse zu erhalten (gibt Ihnen den Durchschnitt über viele Versuche). %timeit gibt mir 654ms für .astype(str), 1,4 s für .values.astype(str), 2,11 s für .map(str), und 1,74 s für für .apply(str).

    – tdy

    30. Juli 21 um 19:40 Uhr


1643039168 528 Konvertieren Sie Spalten in Pandas in Zeichenfolgen
dbouz

Verwenden .apply() mit einer lambda Konvertierungsfunktion funktioniert auch in diesem Fall:

total_rows['ColumnID'] = total_rows['ColumnID'].apply(lambda x: str(x))

Für ganze Datenrahmen können Sie verwenden .applymap(). (aber auf jeden Fall wahrscheinlich .astype() ist schneller)

.

620000cookie-checkKonvertieren Sie Spalten in Pandas in Zeichenfolgen

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy