2016-06-23 17 views
0

Ich verwende Pandas 0.18.1 mit Python 2.7.x. Ich habe einen leeren Datenrahmen, den ich zuerst gelesen habe. Ich sehe, dass die Typen dieser Spalten object sind, was OK ist. Wenn ich eine Datenzeile zuweise, ändert sich der Typ für numerische Werte in float64. Ich habe int oder int64 erwartet. Warum passiert das?Pandas: Warum ist der Standardspalten-Typ für das numerische Float?

Gibt es eine Möglichkeit, eine globale Option zu setzen, damit Pandas weiß, dass numerische Werte sie standardmäßig als int behandeln, es sei denn, die Daten haben eine .? Zum Beispiel [0 1.0, 2.], erste Spalte ist int aber andere zwei sind float64?

Zum Beispiel:

>>> df = pd.read_csv('foo.csv', engine='python', keep_default_na=False) 
>>> print df.dtypes 
bbox_id_seqno object 
type    object 
layer   object 
ll_x    object 
ll_y    object 
ur_x    object 
ur_y    object 
polygon_count object 
dtype: object 
>>> df.loc[0] = ['a', 'b', 'c', 1, 2, 3, 4, 5] 
>>> print df.dtypes 
bbox_id_seqno  object 
type    object 
layer    object 
ll_x    float64 
ll_y    float64 
ur_x    float64 
ur_y    float64 
polygon_count float64 
dtype: object 

Antwort

3

Es ist nicht möglich, dass Pandas NaN Werte in ganzzahligen Spalten speichern.

Dies macht float die offensichtliche Standardauswahl für die Datenspeicherung, weil Pandas den Datentyp für die gesamte Spalte ändern müsste, sobald ein fehlender Wert auftritt. Und in der Praxis tauchen häufig fehlende Werte auf.

Wie für warum dies ist, ist es eine Einschränkung geerbt von Numpy. Im Grunde genommen müssen Pandas ein bestimmtes Bitmuster zur Darstellung NaN beiseite legen. Dies ist unkompliziert für Fließkommazahlen und es ist im IEEE 754-Standard definiert. Es ist umständlicher und weniger effizient, dies für eine Ganzzahl mit fester Breite zu tun.

2

Der Grund ist mit ziemlicher Sicherheit mit Flexibilität und Geschwindigkeit zu tun. Nur weil Pandas bisher nur eine ganze Zahl in dieser Spalte gesehen haben, bedeutet das nicht, dass Sie nicht später versuchen werden, einen Gleitkommazuweisungsbefehl hinzuzufügen, was erfordern würde, dass Pandas zurückgehen und den Typ für diese ganze Spalte ändern würden. Ein Float ist der robusteste/flexibelste numerische Typ.

Es gibt keine globale Möglichkeit, dieses Verhalten zu überschreiben (das ist mir bekannt), aber Sie können die Methode astype verwenden, um einen einzelnen DataFrame zu ändern.

http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.astype.html

3

Wenn Sie eine leere Datenrahmen lesen, können Sie explizit die Typen für jede Spalte geworfen, nachdem sie zu lesen.

dtypes = { 
    'bbox_id_seqno': object, 
    'type': object, 
    'layer': object, 
    'll_x': int, 
    'll_y': int, 
    'ur_x': int, 
    'ur_y': int, 
    'polygon_count': int 
} 


df = pd.read_csv('foo.csv', engine='python', keep_default_na=False) 

for col, dtype in dtypes.iteritems(): 
    df[col] = df[col].astype(dtype) 

df.loc[0] = ['a', 'b', 'c', 1, 2, 3, 4, 5] 

>>> df.dtypes 
bbox_id_seqno object 
type    object 
layer   object 
ll_x    int64 
ll_y    int64 
ur_x    int64 
ur_y    int64 
polygon_count  int64 
dtype: object 

Wenn Sie nicht die Spaltennamen in Ihrem leeren Datenrahmen kennen, können Sie zunächst alles als int zuweisen und dann lassen Pandas sort it out.

for col in df: 
    df[col] = df[col].astype(int)