Ich arbeite mit einzelnen Zeilen von Pandas-Datenrahmen, aber ich stolpere über Zwangsprobleme beim Indizieren und Einfügen von Zeilen. Pandas scheint immer von einem gemischten int / float-Typ zu einem All-float-Typ zwingen zu wollen, und ich kann keine offensichtlichen Kontrollen für dieses Verhalten erkennen.
Hier ist zum Beispiel ein einfacher Datenrahmen mit a
as int
und b
as float
:
import pandas as pd
pd.__version__ # '0.25.2'
df = pd.DataFrame({'a': [1], 'b': [2.2]})
print(df)
# a b
# 0 1 2.2
print(df.dtypes)
# a int64
# b float64
# dtype: object
Hier ist ein Zwangsproblem beim Indizieren einer Zeile:
print(df.loc[0])
# a 1.0
# b 2.2
# Name: 0, dtype: float64
print(dict(df.loc[0]))
# {'a': 1.0, 'b': 2.2}
Und hier ist ein Zwangsproblem beim Einfügen einer Zeile:
df.loc[1] = {'a': 5, 'b': 4.4}
print(df)
# a b
# 0 1.0 2.2
# 1 5.0 4.4
print(df.dtypes)
# a float64
# b float64
# dtype: object
In beiden Fällen möchte ich, dass die a
Spalte als Ganzzahltyp verbleibt und nicht zu einem Float-Typ gezwungen wird.
df.loc[[0], df.columns]
.read_[type]
unterstützt jedoch mehrere dtypes ...Antworten:
Nach einigem Graben finden Sie hier einige schrecklich hässliche Problemumgehungen. (Eine bessere Antwort wird akzeptiert.)
Eine Besonderheit, die hier zu finden ist, ist, dass nicht numerische Spalten den Zwang stoppen. Hier erfahren Sie , wie Sie eine Zeile auf a indizieren
dict
:Zum Einfügen einer Zeile können Sie einen neuen Datenrahmen mit einer Zeile erstellen:
Beide Tricks sind nicht für große Datenrahmen optimiert, daher würde ich mich über eine bessere Antwort sehr freuen!
quelle
df['a'] = df.a.astype(mytype)
... Es ist zwar immer noch schmutzig und wahrscheinlich nicht effizient..astype()
ist gefährlich für float -> integer; es hat kein Problem Wechsel1.1
zu1
, so dass Sie wirklich sicher sein müssen , alle Ihre Werte sind ‚integer-like‘ , bevor es zu tun. Wahrscheinlich am bestenpd.to_numeric
mitdowncast='integer'
Die Wurzel des Problems ist das
Wir können das sehen:
Und eine Serie kann nur einen dtype haben, in Ihrem Fall entweder int64 oder float64.
Ich habe zwei Problemumgehungen:
oder
https://github.com/pandas-dev/pandas/blob/master/pandas/core/frame.py#L6973
Ihr Walkaround ist also tatsächlich solide, oder wir könnten:
quelle
object
Datentypen zu verwenden! Eine andere Möglichkeit besteht darin, von Anfang an ein Objekt DataFrame zu erstellen:df = pd.DataFrame({'a': [1], 'b': [2.2]}, dtype=object)
Vermeiden Sie die Konvertierung in andere interne Strukturen, die die benötigten Datentypen nicht kennen, wenn Sie Daten aus dem Datenrahmen abrufen oder Daten an einen Datenrahmen anhängen und den Datentyp beibehalten müssen.
Wenn Sie es tun
df.loc[0]
, konvertiert es zupd.Series
,Und jetzt
Series
wird nur eine einzige habendtype
. So zwingenint
zufloat
.Behalten Sie stattdessen die Struktur bei
pd.DataFrame
,Wählen Sie die als Frame benötigte Zeile aus und konvertieren Sie sie dann in
dict
Um eine neue Zeile hinzuzufügen, verwenden Sie die Pandas-
pd.DataFrame.append
Funktion.Dies führt nicht zu einer Typkonvertierung.
quelle
Ein anderer Ansatz mit geringfügigen Datenmanipulationen:
Angenommen, Sie haben eine Liste von Wörterbüchern (oder Datenrahmen).
lod=[{'a': [1], 'b': [2.2]}, {'a': [5], 'b': [4.4]}]
Dabei steht jedes Wörterbuch für eine Zeile (beachten Sie die Listen im zweiten Wörterbuch). Dann können Sie ganz einfach einen Datenrahmen erstellen über:
und Sie pflegen die Arten der Spalten. Siehe concat
Wenn Sie also einen Datenrahmen und eine Liste von Diktaten haben, können Sie diese einfach verwenden
quelle
Im ersten Fall können Sie mit dem Datentyp nullable integer arbeiten . Die Serienauswahl wird nicht erzwungen
float
und Werte werden in einenobject
Container gestellt. Das Wörterbuch wird dann ordnungsgemäß erstellt, wobei der zugrunde liegende Wert als gespeichert wirdnp.int64
.Mit Ihrer Syntax funktioniert dies fast auch für den zweiten Fall, aber dies wird aktualisiert
object
, also nicht großartig:Wir können jedoch eine kleine Änderung an der Syntax zum Hinzufügen einer Zeile am Ende vornehmen (mit einem RangeIndex), und jetzt werden Typen ordnungsgemäß behandelt.
quelle