2014-01-17 14 views
59

ich die dtype s mehrerer Spalten in pd.Dataframe (Ich habe eine Datei, die ich je hatte, um manuell in eine Liste von Listen zu analysieren, wie die Datei für pd.read_csv nicht zugänglich war) festlegen möchtenAssign Pandas Datenrahmen Spalte dtypes

import pandas as pd 
print pd.DataFrame([['a','1'],['b','2']], 
        dtype={'x':'object','y':'int'}, 
        columns=['x','y']) 

ich

ValueError: entry not a 2- or 3- tuple 

Die einzige Art, wie ich sie durch Schleifen durch jede Spalte Variable und Neufassung mit astype einstellen.

dtypes = {'x':'object','y':'int'} 
mydata = pd.DataFrame([['a','1'],['b','2']], 
         columns=['x','y']) 
for c in mydata.columns: 
    mydata[c] = mydata[c].astype(dtypes[c]) 
print mydata['y'].dtype #=> int64 

Gibt es einen besseren Weg?

+0

Dies wäre vielleicht ein gutes [Bug/Feature Request] (https://github.com/pydata/pandas/issues/new), derzeit bin ich nicht sicher, was dtype arg (Sie können tut übergeben Sie es einen Skalar, aber es ist nicht streng) ... –

+1

FYI: 'df = pd.DataFrame ([['a', '1'], ['b', '2']], dtype = 'int' , columns = ['x', 'y']) '" funktioniert "... aber: s –

+1

Ja," funktioniert "in der Tat; unvorhersehbar ... – hatmatrix

Antwort

34

können Sie convert_objects verwenden, um besser dtypes zu folgern:

In [11]: df 
Out[11]: 
    x y 
0 a 1 
1 b 2 

In [12]: df.dtypes 
Out[12]: 
x object 
y object 
dtype: object 

In [13]: df.convert_objects(convert_numeric=True) 
Out[13]: 
    x y 
0 a 1 
1 b 2 

In [14]: df.convert_objects(convert_numeric=True).dtypes 
Out[14]: 
x object 
y  int64 
dtype: object 

Magic!

+2

wie 'type.convert' in R ein wenig; nett aber lässt man in manchen fällen explizite spezifikationen. – hatmatrix

+0

@crippledlambda stimmte zu, ich denke, das wäre eine gute Feature-Anfrage und nicht zu schwierigTM zu implementieren. –

+1

Seien Sie vorsichtig, wenn Sie eine Spalte haben, die eine Zeichenfolge sein muss, aber mindestens einen Wert enthält, der in einen int konvertiert werden kann. Alles was es braucht ist ein Wert und das gesamte Feld wird in float64 umgewandelt. –

50

Für diejenigen von Google kommen (etc.) wie mich:

convert_objects ist veraltet - wenn Sie es verwenden, erhalten Sie eine Warnung wie diese:

FutureWarning: convert_objects is deprecated. Use the data-type specific converters 
pd.to_datetime, pd.to_timedelta and pd.to_numeric. 

Sie tun sollten etwa wie folgt:

8

Ein anderer Weg, um die Spaltentypen eingestellt ist, zunächst einen Datensatz numpy Array mit dem gewünschten Typ zu konstruieren, ausfüllen, und es dann zu einem Datenrahmen Konstruktor übergeben.

import pandas as pd 
import numpy as np  

x = np.empty((10,), dtype=[('x', np.uint8), ('y', np.float64)]) 
df = pd.DataFrame(x) 

df.dtypes -> 

x  uint8 
y float64 
0

mit ähnlichen Problem für Sie. In meinem Fall habe ich 1000 von Dateien aus Cisco-Logs, die ich manuell analysieren muss.

Um flexibel mit Feldern und Typen zu sein, habe ich erfolgreich mit StringIO + read_cvs getestet, die tatsächlich ein dict für die dtype-Spezifikation akzeptiert.

Ich bekomme normalerweise jede der Dateien (5k-20k Zeilen) in einen Puffer und erstellen Sie die dtype Wörterbücher dynamisch.

Schließlich verkette ich (mit kategorischen ... dank 0.19) diese Datenframes in einen großen Datenrahmen, den ich in hdf5 ablege.

Etwas in dieser Richtung

import pandas as pd 
import io 

output = io.StringIO() 
output.write('A,1,20,31\n') 
output.write('B,2,21,32\n') 
output.write('C,3,22,33\n') 
output.write('D,4,23,34\n') 

output.seek(0) 


df=pd.read_csv(output, header=None, 
     names=["A","B","C","D"], 
     dtype={"A":"category","B":"float32","C":"int32","D":"float64"}, 
     sep="," 
     ) 

df.info() 

<class 'pandas.core.frame.DataFrame'> 
RangeIndex: 5 entries, 0 to 4 
Data columns (total 4 columns): 
A 5 non-null category 
B 5 non-null float32 
C 5 non-null int32 
D 5 non-null float64 
dtypes: category(1), float32(1), float64(1), int32(1) 
memory usage: 205.0 bytes 
None 

Nicht sehr pythonic .... aber macht den Job

Hoffe, es hilft.

JC

15

Sie die Typen explizit mit Pandas DataFrame.astype(dtype, copy=True, raise_on_error=True, **kwargs) einstellen und mit den dtypes in einem Wörterbuch übergeben Sie wollen dtype

hier ein Beispiel:

import pandas as pd 
wheel_number = 5 
car_name = 'jeep' 
minutes_spent = 4.5 

# set the columns 
data_columns = ['wheel_number', 'car_name', 'minutes_spent'] 

# create an empty dataframe 
data_df = pd.DataFrame(columns = data_columns) 
df_temp = pd.DataFrame([[wheel_number, car_name, minutes_spent]],columns = data_columns) 
data_df = data_df.append(df_temp, ignore_index=True) 

In [11]: data_df.dtypes 
Out[11]: 
wheel_number  float64 
car_name   object 
minutes_spent float64 
dtype: object 

data_df = data_df.astype(dtype= {"wheel_number":"int64", 
     "car_name":"object","minutes_spent":"float64"}) 

jetzt können Sie sehen, dass es hat sich geändert

In [18]: data_df.dtypes 
Out[18]: 
wheel_number  int64 
car_name   object 
minutes_spent float64 
0

Y Es ist besser, typisierte np.arrays zu verwenden und dann die Daten- und Spaltennamen als Wörterbuch zu übergeben.

# Feature: np arrays are 1: efficient, 2: can be pre-sized 
x = np.array(['a', 'b'], dtype=object) 
y = np.array([ 1 , 2 ], dtype=np.int32) 
df = pd.DataFrame({ 
    'x' : x, # Feature: column name is near data array 
    'y' : y, 
    } 
) 
Verwandte Themen